def draw_balloon(img_draw: ImageDraw.Draw, points: Box, fill=None, width=0): r_x0 = points.top_left.x r_y0 = points.top_left.y + BOX_RADIUS r_x1 = points.bottom_right.x r_y1 = points.bottom_right.y - BOX_RADIUS img_draw.rectangle([r_x0, r_y0, r_x1, r_y1], fill=fill, width=width) r_x0 = points.top_left.x + BOX_RADIUS r_y0 = points.top_left.y r_x1 = points.bottom_right.x - BOX_RADIUS r_y1 = points.bottom_right.y img_draw.rectangle([r_x0, r_y0, r_x1, r_y1], fill=fill, width=width) diam = 2 * BOX_RADIUS c_x0 = points.top_left.x c_y0 = points.top_left.y c_x1 = c_x0 + diam c_y1 = c_y0 + diam img_draw.ellipse([c_x0, c_y0, c_x1, c_y1], fill=fill, width=width) c_x0 = points.bottom_right.x - diam c_x1 = c_x0 + diam img_draw.ellipse([c_x0, c_y0, c_x1, c_y1], fill=fill, width=width) c_y0 = points.bottom_right.y - diam c_y1 = c_y0 + diam img_draw.ellipse([c_x0, c_y0, c_x1, c_y1], fill=fill, width=width) arrow_x = 10 arrow_y = 10 if BOX_RADIUS < 10 else BOX_RADIUS arrow = [ (points.top_left.x - arrow_x, points.bottom_right.y), (points.top_left.x, points.bottom_right.y - arrow_y), (points.top_left.x + diam, points.bottom_right.y - arrow_y), (points.top_left.x + diam, points.bottom_right.y), ] img_draw.polygon(arrow, fill=fill)
def render_one(zone2poly, ddata, size): image = Image.new('RGBA', size=size) draw = Draw(image) for zoneix in ddata: if zoneix in zone2poly: dcount = ddata.get(zoneix, 0) intensity = round(2 * dcount) draw.polygon(zone2poly[zoneix], fill=(64, 255, 192, min(intensity, 150))) return image
def draw(self, image_to_draw_on): drawing_context = Draw(image_to_draw_on) if self.bounding_box: coords = Shape.scale_float_coords_to_image_size(self.bounding_box, image_to_draw_on) else: coords = Shape.scale_float_coords_to_image_size(self.vertices, image_to_draw_on) if self.kind == "chord": drawing_context.chord(coords, self.start_angle, self.end_angle, fill=self.color) elif self.kind == "ellipse": drawing_context.ellipse(coords, fill=self.color) elif self.kind == "pieslice": drawing_context.pieslice(coords, self.start_angle, self.end_angle, fill=self.color) elif self.kind == "polygon": drawing_context.polygon(coords, fill=self.color) else: raise Exception("unsupported kind")
def rasterize_geometry(geometry: List[Polygon], tile: Tile, source_zoom: int = 18) -> np.ndarray: wm_geometry = [transform(xy, shape) for shape in geometry] res = get_res(tile, source_zoom=source_zoom) wm_bounds = xy_bounds(tile) def imgspace_transform(xs, ys): xs = np.array(xs) ys = np.array(ys) xs -= wm_bounds.left ys -= wm_bounds.bottom xs /= (wm_bounds.right - wm_bounds.left) ys /= (wm_bounds.top - wm_bounds.bottom) xs *= res ys *= res ys = res - ys return xs, ys img_geometry = [ transform(imgspace_transform, shape) for shape in wm_geometry ] img_geometry = [ list(poly) if type(poly) == MultiPolygon else poly for poly in img_geometry ] img = Image.new('L', (res, res)) draw = Draw(img) for polygon in img_geometry: if type(polygon) != Polygon: print(f"Skipping non-polygon {type(polygon)}!") continue draw.polygon(list(polygon.exterior.coords), fill=1) for interior_hole in polygon.interiors: draw.polygon(list(interior_hole.coords), fill=0) ar = np.array(img, dtype=np.float32) return ar
def create_noise_triangle(image, number): w, h = image.size while number: distance = random.randint(1, 10) x1 = random.randint(int(w/10), w - int(w/10)) x2 = x1 + distance y1 = random.randint(int(h/10), h - int(h/10)) y2 = y1 dx = x2 - x1 dy = y2 - y1 alpha = 60. / 180 * math.pi x3 = x1 + math.cos(alpha) * dx + math.sin(alpha) * dy y3 = y1 + math.sin(-alpha) * dx + math.cos(alpha) * dy points = [x1, y1, x2, y2, x3, y3] color = random_color(10, 200, random.randint(220, 225)) draw = Draw(image) draw.polygon(points, fill=color) number -= 1 return image
async def vcr(self, ctx: Context, *, url: str): # TODO support attachments buffer = BytesIO() resp = await asks.get(url, stream=True) async for chunk in resp.body: buffer.write(chunk) async with ctx.channel.typing: async with spawn_thread(): with Image.open(buffer) as image: filter = np.random.choice(range(3), p=[0.7, 0.2, 0.1]) if filter == SCANLINES: image = add_scanlines(image) elif filter == NOISE: image = add_noise(image) else: image = add_scanlines(image) image = add_noise(image) Brightness(image).enhance(2.5) # hoo boy text = np.random.choice(['PLAY', ' PAUSE'], p=[0.8, 0.2]) font = truetype('VCR_OSD_MONO.ttf', size=int(min(image.size) / 10)) start = datetime.datetime(1980, 1, 1, 0, 0) now = datetime.datetime.utcnow() # https://stackoverflow.com/a/8170651/7581432 random_date = start + datetime.timedelta( seconds=random.randint( 0, int((now - start).total_seconds()))) topleft_text = antialiased_text(text, font, image.width, image.height, offset_x=1 / 30, offset_y=1 / 15) image.paste(topleft_text, (0, 0), mask=topleft_text) draw = Draw(image) if text == 'PLAY': width, height = font.getsize(text) offset_x = width + image.width * (1 / 30) * 1.5 offset_y = image.height * (1 / 15) draw.polygon([(offset_x, offset_y), (offset_x, offset_y + height), (offset_x + sqrt(height**2 - (height / 2)**2), offset_y + height / 2)], fill=(255, 255, 255)) else: _, height = font.getsize(' ') offset_x = image.width * (1 / 35) offset_y = image.height * (1 / 15) part = (height - offset_x / 2) / 8 draw.rectangle( [(offset_x, offset_y + part), (offset_x + 3 * part, offset_y - part + height)], fill=(255, 255, 255)) draw.rectangle( [(offset_x + 5 * part, offset_y + part), (offset_x + 8 * part, offset_y - part + height)], fill=(255, 255, 255)) # This is a nasty hack but oh well time, date = random_date.strftime('%H:%M|%b. %d %Y').split( '|') wrap_width = len(date) botleft_text = antialiased_text( time.ljust(wrap_width + 1) + date, font, image.width, image.height, offset_x=1 / 35, offset_y=13 / 15, wrap_width=wrap_width) image.paste(botleft_text, (0, 0), mask=botleft_text) buffer = save_image(image, format=image.format) await ctx.channel.messages.upload(buffer, filename='shoutouts.' + image.format)
def paint(self, draw: ImageDraw.Draw, regions: RegionMap) -> None: xy = list(map(tuple, self.region.poly.exterior.coords[:-1])) draw.polygon(xy, self.fill, self.color) regions.append(RegionNode(self.region))