Skip to content

Commit e739d96

Browse files
committed
Add new features
1 parent 074ef27 commit e739d96

File tree

8 files changed

+57
-62
lines changed

8 files changed

+57
-62
lines changed

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,14 @@ IFTG offers a wide variety of noise effects that you can apply to your images to
119119
</tr>
120120
</table>
121121

122+
<table>
123+
<tr>
124+
<th>Pixelate</th>
125+
</tr>
126+
<tr>
127+
<td><img src="https://drive.google.com/uc?export=view&id=1r3_sA2A4HM2ILnoxkw1TFrQYYeuIjsk-" alt="Pixel Dropout" width="100%"></td>
128+
</table>
129+
122130
## Installation
123131
To get started with IFTG, you'll need to install the package. You can do this using pip.
124132
```bash

docs/assets/pixelate_img.png

1.3 KB
Loading

docs/introduction.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,15 @@ enhancing the robustness of your models.
8383
</tr>
8484
</table>
8585

86+
<table>
87+
<tr>
88+
<th>Pixelate</th>
89+
</tr>
90+
<tr>
91+
<td><img src="/ImageFromTextGenerator/assets/pixelate_img.png" alt="Pixel Dropout" width="100%"></td>
92+
</tr>
93+
</table>
94+
8695
## **Quick Start**
8796
To get started with IFTG, follow these simple steps:
8897

iftg/creators/creator.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ def _create_base_image(cls,
1717
text: str,
1818
font: ImageFont,
1919
font_color: tuple[int, int, int],
20+
font_opacity: float,
2021
background_color: str,
2122
margins: tuple[int, int, int, int],
2223
background_img: Image

iftg/creators/image_creator.py

Lines changed: 23 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,13 @@ def _create_base_image(cls,
2020
text: str,
2121
font: ImageFont,
2222
font_color: tuple[int, int, int],
23+
font_opacity: float,
2324
background_color: str,
2425
margins: tuple[int, int, int, int],
2526
background_img: Image
2627
) -> Image.Image:
2728
"""
28-
Creates a base image with the specified background color and dimensions,
29+
Creates a base image with the specified text, background color and dimensions,
2930
and optionally adds a background image.
3031
3132
Parameters:
@@ -51,13 +52,18 @@ def _create_base_image(cls,
5152
image_width, image_height = cls.get_image_dimensions(
5253
margins, text_dimensions)
5354

54-
image = Image.new('RGB',
55-
(image_width, image_height+text_dimensions[1]),
56-
color=background_color
57-
)
55+
base_img = Image.new('RGBA',
56+
(image_width, image_height+text_dimensions[1]),
57+
color=background_color
58+
)
59+
text_layer = Image.new('RGBA',
60+
(image_width, image_height+text_dimensions[1]),
61+
color=(255, 255, 255, 0)
62+
)
5863

5964
# add a background image to the text
6065
if background_img != None:
66+
background_img = background_img.convert("RGBA")
6167
bg_width, bg_height = background_img.size
6268

6369
x1 = np.random.randint(0, bg_width - image_width)
@@ -67,19 +73,23 @@ def _create_base_image(cls,
6773

6874
random_bg_part = background_img.crop((x1, y1, x2, y2))
6975

70-
image.paste(random_bg_part)
76+
base_img.paste(random_bg_part)
7177

7278
# Draw the text on the image
73-
draw = ImageDraw.Draw(image)
79+
opacity = int(font_opacity * 255)
80+
draw = ImageDraw.Draw(text_layer)
7481
draw.text((margins[0], -text_dimensions[1]+margins[1]),
75-
text, font=font, fill=font_color)
76-
77-
return image
82+
text, font=font,
83+
fill=(*font_color, opacity)
84+
)
85+
final_img = Image.alpha_composite(base_img, text_layer)
86+
87+
return final_img.convert('RGB')
7888

7989
@classmethod
8090
def _apply_noise(cls, noises: list[Noise], image: Image) -> Image:
8191
"""
82-
Applies text, and noise effects to the base image.
92+
Applies noise effects to the base image.
8393
8494
Parameters:
8595
noises (list[Noise]):
@@ -95,29 +105,6 @@ def _apply_noise(cls, noises: list[Noise], image: Image) -> Image:
95105

96106
return image
97107

98-
@classmethod
99-
def _blend_colors(cls, bg_color: str, text_color: str, font_opacity: float) -> tuple[int, int, int]:
100-
"""
101-
Blends the text color with the background color to simulate transparency.
102-
103-
Parameters:
104-
bg_color (str): The background color in any valid PIL color format.
105-
text_color (str): The text color in any valid PIL color format.
106-
alpha (float): The transparency level (0.0 to 1.0).
107-
108-
Returns:
109-
tuple: The blended color as an (R, G, B) tuple.
110-
"""
111-
112-
bg_r, bg_g, bg_b = ImageColor.getrgb(bg_color)
113-
text_r, text_g, text_b = ImageColor.getrgb(text_color)
114-
115-
r = int((1 - font_opacity) * bg_r + font_opacity * text_r)
116-
g = int((1 - font_opacity) * bg_g + font_opacity * text_g)
117-
b = int((1 - font_opacity) * bg_b + font_opacity * text_b)
118-
119-
return r, g, b
120-
121108
@classmethod
122109
def create_image(cls,
123110
text: str,
@@ -165,9 +152,9 @@ def create_image(cls,
165152
"""
166153
font = ImageFontManager.get_font(font_path, font_size)
167154

168-
r, g, b = cls._blend_colors(background_color, font_color, font_opacity)
155+
font_rgb = ImageColor.getrgb(font_color)
169156
image = cls._create_base_image(
170-
text, font, (r, g, b), background_color, margins, background_img)
157+
text, font, font_rgb, font_opacity, background_color, margins, background_img)
171158

172159
image = cls._apply_noise(noises, image)
173160
image.info['dpi'] = dpi

main_test.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
def main0():
2121
image = ImageCreator.create_image(
2222
'Hello, world', './fonts/Arial.ttf', font_opacity=0.3)
23+
print(image.mode)
2324
image.save('opacity_img.png', **image.info)
2425

2526

@@ -96,8 +97,9 @@ def main4():
9697

9798
texts = ['Hello, World!', 'how are you', 'what are you doing'] * 10
9899
results = ImagesGenerator(
99-
texts=texts, font_path='fonts/Arial.ttf', font_opacity=0.7,
100-
noises=[RandomPixelateNoise()]
100+
texts=texts, font_path='fonts/Arial.ttf', font_opacity=1.0,
101+
noises=[RandomPixelateNoise()],
102+
img_format='.png'
101103
)
102104
results.generate_images_with_text()
103105

@@ -112,4 +114,4 @@ def main5():
112114

113115

114116
if __name__ == '__main__':
115-
main4()
117+
main0()

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
setuptools.setup(
66
name='iftg',
7-
version='1.2.7',
7+
version='1.2.8',
88
description='IFTG (ImageFromTextGenerator) is a Python package that simplifies creating robust datasets for OCR models. Generate images from text, apply over 10 built-in noise effects, and customize fonts and layouts. IFTG supports all languages and offers endless noise combinations, including custom noise creation.',
99
long_description=pathlib.Path('README.md').read_text(),
1010
long_description_content_type='text/markdown',

tests/test_creators/test_image_creator.py

Lines changed: 10 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -12,42 +12,30 @@ def mock_font():
1212
font = ImageFontManager.get_font('tests/Arial.ttf', 12)
1313
return font
1414

15-
1615
@pytest.fixture
1716
def mock_image():
18-
image = MagicMock(spec=Image.Image)
19-
# Add required attributes and methods for ImageDraw
20-
image.size = (500, 500)
21-
image.readonly = False
22-
image.getdraw = MagicMock()
23-
# Mock the drawing context
24-
draw_context = MagicMock()
25-
image.getdraw.return_value = draw_context
26-
return image
27-
17+
# Create a real PIL Image with RGBA mode to support more operations
18+
return Image.new("RGBA", (500, 500), color=(255, 255, 255))
2819

2920
@pytest.fixture
3021
def noise_list():
3122
return [BlurNoise(blur_radius=2.0), BlurNoise(blur_radius=5.0)]
3223

33-
3424
@pytest.mark.parametrize(
3525
"text, margins, bg_color, font_color, expected_size",
3626
[
37-
("Sample Text", (5, 5, 5, 5), "white", (255, 255, 255), (500, 500)),
38-
("Another Text", (10, 10, 10, 10), "black", (255, 255, 255), (500, 500)),
27+
("Sample Text", (5, 5, 5, 5), (255, 255, 255), (0, 0, 0), (500, 500)),
28+
("Another Text", (10, 10, 10, 10), (0, 0, 0), (255, 255, 255), (500, 500)),
3929
]
4030
)
41-
def test_create_base_image(mock_font, mock_image, text, margins, bg_color, font_color, expected_size):
42-
with patch('PIL.Image.new', return_value=mock_image):
31+
def test_create_base_image(mock_font, text, margins, bg_color, font_color, expected_size):
32+
# Create a patch that returns a real RGBA image
33+
with patch('PIL.Image.new', return_value=Image.new("RGBA", expected_size, color=bg_color)):
4334
image = ImageCreator._create_base_image(
44-
text, mock_font, font_color, bg_color, margins, None)
45-
46-
assert image == mock_image
35+
text, mock_font, font_color, 1.0, bg_color, margins, None)
36+
4737
assert image.size == expected_size
48-
# Changed from Image.Image since we're using a mock
49-
assert isinstance(image, MagicMock)
50-
38+
assert isinstance(image, Image.Image)
5139

5240
def test_invalid_font_path():
5341
with patch('iftg.image_font_manager.ImageFontManager.get_font', side_effect=FileNotFoundError):

0 commit comments

Comments
 (0)