def generate_letter(char, font_size, font_name): img_dim = (font_size + font_size / 2,) * 2 img = new_image("RGB", img_dim, (0, 0, 0)) img_draw = Draw(img) #font = PIL.ImageFont.ImageFont() #font.font = PIL.ImageFont.truetype(font_name, font_size) #font.color = tuple( [randrange(126, 256) for i in range(3)] ) font = PIL.ImageFont.truetype(font_name, font_size) color = tuple( [randrange(126, 256) for i in range(3)] ) img_draw.text((0, 0), char, color, font) #img = img_draw.flush() img = img.rotate(randrange(-30, 30), BICUBIC) mask = new_image("L", img.size, 0) mask.paste(img, (0, 0)) return img, mask
def save_collage(filename, crown_dict, mse_dict): number_of_crowns = len(crown_dict) rows = ceil(number_of_crowns / 4) collage = new_image('RGB', (1200, 300 * rows)) crowns = crown_dict.keys() font = ImageFont.truetype("arial.ttf", 15) i = 1 h_offset = 0 v_offset = 0 for crown in crowns: img = crown_dict[crown].resize((300, 300)) Draw(img).text((30, 5), crown + ' with error: ' + str(mse_dict[crown]), fill=(255, 255, 255), font=font) collage.paste(img, (h_offset, v_offset)) h_offset += 300 if i % 4 == 0: v_offset += 300 h_offset = 0 i += 1 if isdir(join('saved_files', filename)): rmtree(join('saved_files', filename)) mkdir(join('saved_files', filename)) collage.save(join('saved_files', filename, 'collage.jpg')) print('Collage saved: ' + join('saved_files', filename, 'collage.jpg')) collage.show()
def get_thumbnail(self, xnewsize, ynewsize, format=None, fit=False): # Get the handle handle = self._get_handle() if handle is None: return None, None format = format or self._get_format(handle) # Icon's thumbnail is the icon itself if format == 'ICO': return self.to_str(), format.lower() xsize, ysize = self.size xratio, yratio = float(xnewsize)/xsize, float(ynewsize)/ysize # Case 1: fit if fit: # Scale the image so no more than one side overflows ratio = max(xratio, yratio) im, xsize, ysize = self._scale_down(handle, ratio) # Crop the image so none side overflows xsize = min(xsize, xnewsize) ysize = min(ysize, ynewsize) im = im.crop((0, 0, xsize, ysize)) # Paste the image into a background so it fits the target size if xsize < xnewsize or ysize < xnewsize: newsize = (xnewsize, ynewsize) background = new_image('RGBA', newsize, (255, 255, 255, 0)) x = (xnewsize - xsize) / 2 y = (ynewsize - ysize) / 2 background.paste(im, (x, y)) im = background # Case 2: thumbnail else: # Scale the image so none side overflows ratio = min(xratio, yratio) im, xsize, ysize = self._scale_down(handle, ratio) # To string output = StringIO() # JPEG : Convert to RGB if format.lower() == 'jpeg': im = im.convert("RGB") im.save(output, format, quality=80) value = output.getvalue() output.close() # Ok return value, format.lower()
def get_thumbnail(self, xnewsize, ynewsize, format=None, fit=False): # Get the handle handle = self._get_handle() if handle is None: return None, None format = format or self._get_format(handle) # Icon's thumbnail is the icon itself if format == 'ICO': return self.to_str(), format.lower() xsize, ysize = self.size xratio, yratio = float(xnewsize) / xsize, float(ynewsize) / ysize # Case 1: fit if fit: # Scale the image so no more than one side overflows ratio = max(xratio, yratio) im, xsize, ysize = self._scale_down(handle, ratio) # Crop the image so none side overflows xsize = min(xsize, xnewsize) ysize = min(ysize, ynewsize) im = im.crop((0, 0, xsize, ysize)) # Paste the image into a background so it fits the target size if xsize < xnewsize or ysize < xnewsize: newsize = (xnewsize, ynewsize) background = new_image('RGBA', newsize, (255, 255, 255, 0)) x = (xnewsize - xsize) / 2 y = (ynewsize - ysize) / 2 background.paste(im, (x, y)) im = background # Case 2: thumbnail else: # Scale the image so none side overflows ratio = min(xratio, yratio) im, xsize, ysize = self._scale_down(handle, ratio) # To string output = StringIO() # JPEG : Convert to RGB if format.lower() == 'jpeg': im = im.convert("RGB") im.save(output, format, quality=80) value = output.getvalue() output.close() # Ok return value, format.lower()
def generate_captcha(directory="tmp", letters=ascii_uppercase+digits, length=3, font_size=30, lines=5, mode="ellipse", font="FreeSerif.ttf"): """ Returns a tuple : (path, code) """ dimensions = ((length + 1) * font_size, int(font_size * 2)) path = "%s%s" % (os.path.join(directory, "".join(choice(ascii_letters) for i in xrange(7))), ".png") code = "".join(choice(letters) for i in range(length)) background_color = tuple( [randrange(190, 230) for i in xrange(3)] ) master = new_image("RGB", dimensions, background_color) # On colle les lettres for i, l in enumerate(code): img, mask = generate_letter(l, font_size, font) for _ in xrange(3): # On colle plusieurs fois pour plus de netteté master.paste(img, (font_size / 2 + font_size * i , font_size / 3), mask) # Et on dessine quelques jolies lignes draw = Draw(master) for i in xrange(lines): color = tuple( [randrange(128, 190) for i in xrange(3)] ) #pen = Pen("black", opacity=64) #pen.color = color w = dimensions[0] h = dimensions[1] geom = (randrange(0, int(w * 3. / 4)), randrange(0, h), randrange(int(w * 1. / 4), w), randrange(0, h)) if mode == "mixed": mode_ = choice( ("ellipse", "line") ) else: mode_ = mode if mode_ == "ellipse": draw.ellipse(geom, None, color) else: draw.line(geom, color, 1) with open(path, "w") as f: master.save(f) return (path, code)
def gen_image(self): return new_image('1', self.size, '#FFFFFF')
def image_crop( image: Union[bytes, Image], crop: Optional[Crop] = None, width_preview: Optional[int] = None, image_alt: Optional[str] = None, min_width: Optional[int] = None, min_height: Optional[int] = None, max_width: Optional[int] = None, max_height: Optional[int] = None, # FIXME: Changing these properties, the component is rerendered unfortunately. # ---- # keep_selection: Optional[bool] = None, # disabled: Optional[bool] = None, # locked: Optional[bool] = None, rule_of_thirds: Optional[bool] = None, circular_crop: Optional[bool] = None, # ---- key: Optional[str] = None, ) -> Optional[Image]: import dataclasses from io import BytesIO from os import path import streamlit as st from PIL.Image import composite as composite_image from PIL.Image import new as new_image from PIL.Image import open as open_image from PIL.ImageDraw import Draw from streamlit.components import v1 as components from streamlit.elements.image import image_to_url global _impl if _impl is None: if _DEBUG: option_address = st.get_option("browser.serverAddress") option_port = st.get_option("browser.serverPort") _impl = ( components.declare_component( "image_crop", url="http://localhost:3001", ), lambda s: f"http://{option_address}:{option_port}" + s, ) else: _impl = ( components.declare_component( "image_crop", path=path.join(path.dirname(path.abspath(__file__)), "frontend/build"), ), lambda s: s, ) if isinstance(image, Image): image_ = image else: image_ = open_image(BytesIO(image)) width, _ = image_.size src = image_to_url( image_, width=min(width, width_preview) if width_preview else width, clamp=False, channels="RGB", output_format="auto", image_id="foo", ) crop_ = None if crop is None else dataclasses.asdict(crop) default = { "width": 0.0, "height": 0.0, "x": 0.0, "y": 0.0, } component, build_url = _impl result = component( src=build_url(src), image_alt=image_alt, minWidth=min_width, minHeight=min_height, maxWidth=max_width, maxHeight=max_height, # FIXME: Changing these properties, the component is rerendered unfortunately. # ---- keepSelection=None, disabled=None, locked=None, ruleOfThirds=rule_of_thirds, circularCrop=circular_crop, # ---- crop=crop_, key=key, default=default, ) w, h = image_.size w_crop = int(w * float(result["width"]) / 100) h_crop = int(h * float(result["height"]) / 100) x0 = int(w * float(result["x"]) / 100) y0 = int(h * float(result["y"]) / 100) x1 = x0 + w_crop y1 = y0 + h_crop if w_crop <= 0 or h_crop <= 0: return None else: image_crop = image_.crop((x0, y0, x1, y1)) if circular_crop: background = new_image("RGBA", (w_crop, h_crop), (0, 0, 0, 0)) mask = new_image("L", (w_crop, h_crop), 0) draw = Draw(mask) draw.ellipse((0, 0, w_crop, h_crop), fill="white") image_crop = composite_image(image_crop, background, mask) return image_crop
def default(cls) -> Image: return new_image("RGB", (16, 16), "black")