def score_hour_lines(draw: ImageDraw): for hour in range(HOURS): y = hour * HOUR_HEIGHT draw.line(( (0, y), (NUM_DAYS * DAY_WIDTH, y), ), fill='grey')
def verification_code(request): """ :param request: :return: about:生成4位随机验证码图 """ mode = 'RGB' size = (100, 34) color_bg = (get_bg_color(), get_bg_color(), get_bg_color()) # 画布 image = Image.new(mode=mode, size=size, color=color_bg) # 画笔 image_draw = ImageDraw(image, mode=mode) image_font = ImageFont.truetype(settings.FONT_PATH, random.randrange(30, 34)) # 绘制文字 code = get_code() request.session['verification_code'] = code for i in range(4): fill = (get_color(), get_color(), get_color()) image_draw.text(xy=(i * random.randrange(18, 28), random.randrange(5)), text=code[i], font=image_font, fill=fill) for i in range(2): fill = (get_color(), get_color(), get_color()) xy1 = ((random.randrange(100), random.randrange(50)), (random.randrange(75), random.randrange(25))) image_draw.line(xy=xy1, fill=fill) xy2 = ((random.randrange(50), random.randrange(100)), (random.randrange(34), random.randrange(13))) image_draw.line(xy=xy2, fill=fill) for i in range(10): fill = (get_color(), get_color(), get_color()) xy1 = ((random.randrange(100), random.randrange(50)), (random.randrange(75), random.randrange(25))) image_draw.point(xy=xy1, fill=fill) # 变成比特流 fp = BytesIO() image.save(fp, 'png') return HttpResponse(fp.getvalue(), content_type='image/png')
def draw_eye_vector(drawer: ImageDraw.ImageDraw, eye_3d_vector: np.ndarray, solver: PNP_solver.PoseEstimator, rotation: np.ndarray, translation: np.ndarray, eye_pos: str) -> None: """Draw gaze vector eye from eye on a picture drawer :param drawer: where to draw :param eye_3d_vector: what vector(in camera coordinate system) :param solver: :param rotation: head rotation :param translation: head translation :param eye_pos: "l" for left, "r" for right :return: """ if eye_pos == "l": eye_pos = (solver.model_points_68[36] + solver.model_points_68[39]) / 2. else: eye_pos = (solver.model_points_68[42] + solver.model_points_68[45]) / 2. eye_3d_vector = copy.deepcopy(eye_3d_vector) * -50 # eye coordinate in camera coordinate system is determined to_camera_matrix = get_world_to_camera_projection_matrix(solver, rotation, translation) eye_pos = np.matmul(to_camera_matrix, [*eye_pos, 1]) no_rot_vector, _ = cv2.Rodrigues(np.array([[1., 0., 0.], [0., 1., 0.], [0., 0., 1.]])) vect_start, _ = cv2.projectPoints(eye_pos, no_rot_vector, [0, 0, 0], solver.camera_matrix, solver.dist_coeefs) vect_finish, _ = cv2.projectPoints(eye_3d_vector + eye_pos, no_rot_vector, [0, 0, 0], solver.camera_matrix, solver.dist_coeefs) drawer.line([*vect_start, vect_start[0] + vect_finish[0], vect_start[1] + vect_finish[1]], fill=(0, 255, 0)) drawer.ellipse([vect_start[0] - 2, vect_start[1] - 2, vect_start[0] + 2, vect_start[1] + 2])
def run(self): # no need to overwrite parent's init turtle = self.turtle colors = self.colors if self.load_from_cache(): return self.canvas.begin_new() im_draw = ImageDraw(self.canvas.pil_image) color = self.colors["1"] # Calculate size, and scale to fill the frame t_width = turtle.rightmost[0] - turtle.leftmost[0] t_height = turtle.bottommost[1] - turtle.topmost[1] if t_width / t_height > 1: # fat image scale according to width scale_factor = self.canvas.c_width / t_width else: scale_factor = self.canvas.c_height / t_height left_margin = (self.canvas.c_width - scale_factor * t_width) / 2 top_margin = (self.canvas.c_height - scale_factor * t_height) / 2 x_shift = left_margin - scale_factor * turtle.leftmost[0] y_shift = top_margin - scale_factor * turtle.topmost[1] coordinates = [] for item in turtle.lines: if self._stop_drawing.isSet(): return if isinstance(item, PlaceHolder): coordinates.append(item) else: coordinates.append((item[0] * scale_factor + x_shift, item[1] * scale_factor + y_shift, item[2] * scale_factor + x_shift, item[3] * scale_factor + y_shift)) i = 0 for item in coordinates: if self._stop_drawing.isSet(): return "Update canvas after each 3000 stroke" i += 1 if i > 3000: self.canvas.update_image() i = 0 if isinstance(item, PlaceHolder): # not a list of coordinates if item.value in colors: color = colors[item.value] else: im_draw.line(item, color) self.canvas.update_image() self.save_to_cache()
def getcode(request): mode = 'RGB' size = [200, 100] color_bg = getcolor() image = Image.new(mode=mode, size=size, color=color_bg) imagedraw = ImageDraw(image, mode=mode) iamgefont = ImageFont.truetype(settings.FONT_PATH, 30) verify_code = 'Come' for i in range(len(verify_code)): # file text填充色 fill = getcolor() imagedraw.text(xy=(30 * i, 30), text=verify_code[i], font=iamgefont, fill=fill) # 干扰点 for i in range(1000): xy = (random.randrange(size[0]), random.randrange(size[1])) fill = getcolor() imagedraw.point(xy=xy, fill=fill) # 画圆 xy区域,四元数组 start int end int 圆经过strat和end start = random.randrange(size[0]) end = random.randrange(size[1]) fill = getcolor() imagedraw.arc(xy=(0, 0, 200, 100), start=start, end=end, fill=fill) for i in range(10): imagedraw.line(xy=( random.randrange(size[0]), random.randrange(size[1]), (random.randrange(size[0]), random.randrange(size[1]))), fill=getcolor()) fp = BytesIO() image.save(fp, 'png') cache.set('code', verify_code) return HttpResponse(fp.getvalue(), content_type='image/png')
def line(draw: ImageDraw, coord1: Coordinate, coord2: Coordinate): """Draws a line between two given Coordinates. The color of the line depends on the Y value (low = black, high = white) Arguments: draw {ImageDraw} -- The ImageDraw to draw on coord1 {Coordinate} -- Coordinate of the original position coord2 {Coordinate} -- Coordinate of the next position """ # R G B # low black: 0 0 0 # high white: 225 225 255 # Limit elevation to be between 70 and 120 ll = 70.0 ul = 120.0 pos1 = coord1.coord_3d pos2 = coord2.coord_3d elev = max(ll, min(pos1[1], ul)) # The RGB tuple to make the gray for the given elevation gray = (int(scale(elev, (ll, ul), (0.0, 255.0))), ) * 3 draw.line([(pos1[0], pos1[2]), (pos2[0], pos2[2])], gray, 4)
def draw_route_frame(self, route: list, frame: int, draw: ImageDraw.ImageDraw) -> None: """Draws single frame of route for single player.""" first_pos = (self.gran * int((route[frame]['x_pos']) + 20), self.gran * int(route[frame]['y_pos'])) second_pos = (self.gran * int((route[frame + 1]['x_pos']) + 20), self.gran * int(route[frame + 1]['y_pos'])) draw.line((first_pos, second_pos), fill=255, width=self.gran*1)
def draw_line(draw: ImageDraw.ImageDraw, target, offset=(0, 0), scale=1.0): vertexes = [] for vertex in target['vertexes']: x = vertex['x'] * scale + offset[0] y = vertex['y'] * scale + offset[1] vertexes.append((int(x), int(y))) # draw draw.line(vertexes)
def draw(self, verbose=False): """ Draw map out to a PIL.Image and return it. """ # image and filename img = Image.new('RGB', (self.width, self.height), 0x00) if verbose: print 'Laying out faces...' face = icosahedron.vertex2face(icosahedron.latlon2vertex(self.latitude, self.longitude)) face.orient_north(self.latitude, self.longitude) face.center_on(self.latitude, self.longitude) face.scale(self.side) face.translate(img.size[0]/2, img.size[1]/2) faces = face.arrange_neighbors(self.join) if verbose: print 'Drawing faces...' applied = [] for f, face in icosahedron.faces.items(): if face in faces: applied += apply_face(img, ['%02d' % f], face, UP, verbose=verbose) lock = threading.Lock() pasters = [TilePaster(img, srcPath, affineData, lock, verbose) for (srcPath, affineData) in applied] for paster in pasters: paster.start() while True: time.sleep(.25) remaining = sum(map(int, [paster.isAlive() for paster in pasters])) if remaining == 0: break if verbose: print 'Drawing lines...' draw = ImageDraw(img) for face in faces: for edge in face.edges(): x1, y1 = face.project_vertex(edge.vertexA) x2, y2 = face.project_vertex(edge.vertexB) if edge.kind == icosahedron.LAND: draw.line((x1, y1, x2, y2), fill=(0x00, 0xCC, 0x00, 0x80)) elif edge.kind == icosahedron.WATER: draw.line((x1, y1, x2, y2), fill=(0x00, 0x66, 0xFF, 0x80)) return img
def draw(self, canvas: ImageDraw.ImageDraw, color='black', width=1, text_color='black'): # canvas.rectangle((self.p1.as_tuple, self.p3.as_tuple), outline=color,) canvas.line((self.p1.as_tuple, self.p2.as_tuple), color, width) canvas.line((self.p2.as_tuple, self.p3.as_tuple), color, width) canvas.line((self.p3.as_tuple, self.p4.as_tuple), color, width) canvas.line((self.p4.as_tuple, self.p1.as_tuple), color, width) if self.text: canvas.text((self.p1.x + 3, self.p1.y + 3), self.text, fill=text_color, font=self.font)
def fill_rainbows(image, angle=0): draw_api = ImageDraw(image) for col in range(IMG_SIZE): hue = (col * MAX_HUE / IMG_SIZE + angle) % MAX_HUE colour_string = "hsl(%d, 100%%, 50%%)" % (hue) # logging.warning("colour_string: %s" % colour_string) rgb = ImageColor.getrgb(colour_string) # logging.warning("rgb: %s" % (rgb,)) draw_api.line([(col, 0), (col, IMG_SIZE)], fill=rgb)
def draw_linestring(image, linestring, color=255): """Draw a linestring in the given color at the given location""" pil_image = fromarray(image) validated_color = color draw = ImageDraw(pil_image) if len(image.shape) > 2 and image.shape[2] > 1: validated_color = tuple(color) draw.line(linestring.coords, fill=validated_color) return np.asarray(pil_image)
def score_hour_lines(draw: ImageDraw): for hour in range(HOURS): y = hour * HOUR_HEIGHT draw.line( ( (0, y), (NUM_DAYS * DAY_WIDTH, y), ), fill='grey' )
def draw_ant(draw: ImageDraw.ImageDraw, ant: Ant): y, x = ant.position pos = (np.array([x, y]) + .5) * c.C2P rot = rotation(-ant.direction * TAU / 8) start = rot @ np.array([0., -c.C2P / 3]) + pos end = rot @ np.array([0., c.C2P / 3]) + pos color = (255, 0, 0) if ant.food else (0, 0, 0) draw.line(start.tolist() + end.tolist(), fill=color, width=2)
def draw_flag_path(self, image, flag_path): flag_path = flag_path[0] pen = ImageDraw(image) x = 0 while x < len(flag_path) - 1: x1, y1 = flag_path[x] x2, y2 = flag_path[x + 1] pen.line(((x1 * 40) + 20, (y1 * 40) + 20, (x2 * 40) + 20, (y2 * 40) + 20), "yellow", width=4) x += 1
def draw(self, features: List, osm_helper: OsmHelper, camera: Camera, image_draw: ImageDraw): width = int(self.width * (camera.px_per_meter()**self.exponent)) if self.draws_at_zoom(None, camera, osm_helper): for lines in features: for line in transform_shapes(lines, camera): image_draw.line(line, fill=self.fill, width=width, joint='curve')
def create_test_image(w, h, c='RGB'): colors = { 'RGB': {1: '#DDEEFF', 2: '#667788', 3: '#887766'}, 'CMYK': {1: (120, 130, 140, 25), 2: (80, 100, 120, 50), 3: (120, 100, 80, 75)}, } color = colors[c] img = Image.new(c, (w, h), color=color[1]) d = ImageDraw(img) d.line((-1, -1) + img.size, fill=color[2], width=2) d.line((-1, img.size[1], img.size[0], -1), fill=color[3], width=2) return img
def drawStreet(draw: ImageDraw.ImageDraw, geometry: list, coef: float, width: int): street = pd.DataFrame(geometry) street['lon'] = coef * (street['lon'] - minlon) street['lat'] = coef * (street['lat'] - minlat) points = np.ravel( np.asarray((street['lon'].tolist(), street['lat'].tolist())).T).tolist() draw.line(points, fill=255, width=width)
def to_image(self): a = np.zeros((self._height, self._width), dtype=np.uint8) im = Image.fromarray(a, mode='L') canvas = ImageDraw(im, mode='L') for x, y, prev_point in self.points_generator(): if prev_point: canvas.line((prev_point, (x, y)), width=12, fill=255) return im
def draw_scene(self, draw: ImageDraw.ImageDraw, player_radians: float, projection_plane: float, wall_height: int, hits: List[Hit]): y = self.height / 2 precomputed = wall_height * projection_plane for x, hit in enumerate(hits): correct_distance = hit.length * glm.cos(hit.radians - player_radians) column_height = precomputed / correct_distance draw.line((x, y - column_height, x, y + column_height), COLOR_GRAY)
def get_code(request): mode = 'RGB' size = (200, 100) red = get_color() green = get_color() blue = get_color() # 随机画布的背景颜色 color_bg = (red, green, blue) # 构造画布 image = Image.new(mode=mode, size=size, color=color_bg) # 初始化画笔 imagedraw =ImageDraw(image, mode=mode) # 设置字体和字体大小 imagefont = ImageFont.truetype(settings.FONT_PATH, 100) verify_code = generate_verification_code() # 通过session记录这个验证码并且设置过期时间为60秒 request.session['verifycode'] = verify_code request.session.set_expiry(20) # 随机每个验证码的颜色 for i in range(4): # 随机颜色 fill = (get_color(),get_color(),get_color()) imagedraw.text(xy=(50*i, 0), text=verify_code[i], font=imagefont,fill=fill) # 生成验证码图片上的干扰点 for i in range(1000): # 随机颜色 fill = (get_color(), get_color(), get_color()) # xy的随机坐标和画布的大小size一样 也就是画布整体都加干扰点 xy = (random.randrange(201),random.randrange(100)) imagedraw.point(xy=xy, fill=fill) # 生成验证码图片上的干扰线 for i in range(5): # 随机颜色 fill = (get_color(), get_color(), get_color()) # xy的随机坐标和画布的大小size一样 也就是画布整体都加干扰点 x1 = (random.randrange(200)) x2 = (random.randrange(200)) y1 = (random.randrange(100)) y2 = (random.randrange(100)) imagedraw.line(xy=(x1,y1,x2,y2),fill=fill,width=2) # 内存流 fp = BytesIO() # 将验证码图片存在内存流中 image.save(fp, 'png') return HttpResponse(fp.getvalue(), content_type='image/png')
def gen_code(self): """ 生成验证码 """ # 1.使用随机数生成验证码字符串 code = self._get_vcode() # 2. 把验证码存在session self.dj_request.session[self.session_key] = code # 3.准备随机元素(背景颜色、验证码文字的颜色、干扰线) font_color = [ 'black', 'darkblue', 'darkred', 'yellow', 'brown', 'blue', 'pink' ] # RGB随机背景色 bg_color = (random.randrange(230, 255), random.randrange(230, 255), random.randrange(230, 255)) font_path = os.path.join(settings.BASE_DIR, 'static', 'fonts', 'char.ttf') # 创建图片 im = Image.new('RGB', (self.img_width, self.img_height), bg_color) draw = ImageDraw(im) # 画干扰线 # 随机条数,到底画几条 for i in range(random.randrange(1, (self.code_len / 2) + 1)): # 线条的颜色 line_color = random.choice(font_color) # 线条的位置 point = (random.randrange(0, self.img_width * 0.2), random.randrange(0, self.img_height * 0.2), random.randrange(self.img_width - self.img_width * 0.2, self.img_width), random.randrange(0, self.img_height)) # 线条的宽度 width = random.randrange(1, 4) draw.line(point, fill=line_color, width=width) # 画验证码 for index, char in enumerate(code): code_color = random.choice(font_color) # 指定字体 # font_size = random.choice(font_color) font_size = random.randrange(15, 20) font = ImageFont.truetype(font_path, font_size) point = (index * self.img_width / self.code_len, random.randrange(0, self.img_height / 3)) draw.text(point, char, font=font, fill=code_color) buf = BytesIO() im.save(buf, 'gif') return HttpResponse(buf.getvalue(), 'image/gif')
def wireframe(ipse, margin=150): mx, my = ipse.bbox() sz = int(sum(mx)) + margin * 2, int(sum(my)) + margin * 2 im = Image.new(mode="RGB", size=sz, color=(255, 255, 255)) draw = ImageDraw(im) draw.rectangle(xy=(margin, margin, int(sum(mx)) + margin, int(sum(my)) + margin), outline=(0, 0, 255)) p = DParse() x, y = 0, 0 for q in p(ipse.path): cmd = q[0] x0, y0 = x, y if cmd.lower() == "m": if cmd.islower(): x, y = x + q[-2], y + q[-1] else: x, y = q[-2:] m = x, y continue elif cmd.lower() == "z": x, y = m elif cmd.lower() == "h": if cmd.islower(): x = x + q[-1] else: x = q[-1] elif cmd.lower() == "v": if cmd.islower(): y = y + q[-1] else: y = q[-1] else: if cmd.islower(): x, y = x + q[-2], y + q[-1] else: x, y = q[-2:] draw.line((x + margin, y + margin, x0 + margin, y0 + margin), fill=(0, 0, 0)) draw.ellipse(xy=(x - 2 + margin, y - 2 + margin, x + 2 + margin, y + 2 + margin), fill=(0, 255, 0)) x, y = ipse.origin draw.ellipse(xy=(x - 2 + margin, y - 2 + margin, x + 2 + margin, y + 2 + margin), fill=(255, 0, 0)) return im
def draw(self, canvas: ImageDraw.ImageDraw, color='red'): canvas.ellipse((self.x - self.hr, self.y - self.hr, self.x + self.hr, self.y + self.hr), fill=color) if self.down: canvas.line(((self.x, self.y), (self.x, self.y + self.tail)), 'blue') if self.up: canvas.line(((self.x, self.y), (self.x, self.y - self.tail)), 'blue') if self.left: canvas.line(((self.x, self.y), (self.x - self.tail, self.y)), 'blue') if self.right: canvas.line(((self.x, self.y), (self.x + self.tail, self.y)), 'blue')
def draw_keypoints_connections_single_object( draw: ImageDraw.ImageDraw, keypoints: np.ndarray, connection_map: Dict[str, list], colors: Dict[str, list], thickness: int = 1, ): """ Draw connections between keypoints according to connection map Parameters ---------- draw image draw keypoints keypoints with shape [num_keypoints, 2] in global, e.g. image coordinates and coordinates in format [y, x] connection_map connection as list of lists of connections specifying connected keypoints indices colors list of rgb values for each connection index thickness thickness of the connection Returns ------- image image with connections drawn """ valid_keypoints = np.any(keypoints > 0, -1) for each_connection_name in connection_map: connection_start, connection_end = connection_map[each_connection_name] color = colors[each_connection_name] is_valid_connection = np.all([ valid_keypoints[connection_start], valid_keypoints[connection_end] ]) if not is_valid_connection: continue coordinates = np.concatenate([ keypoints[connection_start][::-1], keypoints[connection_end][::-1] ], 0).astype(np.int32).tolist() draw.line(coordinates, fill=tuple(color), width=thickness)
def draw_bound_box_on_image(image, xmin, ymin, xmax, ymax, vis=True): """ :param image: :param xmin, ymin, xmax, ymax: 归一化后的边角坐标 :param vis: :return: """ pil_image = PIL.Image.fromarray(image) draw = ImageDraw(pil_image) xmin *= pil_image.width xmax *= pil_image.width ymin *= pil_image.height ymax *= pil_image.height xmin, ymin, xmax, ymax = [int(it) for it in [xmin, ymin, xmax, ymax]] draw.line([(xmin, ymin), (xmax, ymin), (xmax, ymax), (xmin, ymax), (xmin, ymin)], width=4, fill='blue') np.copyto(image, np.array(pil_image))
def get_gradient_pixmap(self, size: Tuple[int, int], coloring_mode: ColoringMode) -> QPixmap: """Returns color gradient pixmap for the specified coloring mode. Parameters ---------- size : Tuple[int, int] Size in pixels (width, height). coloring_mode : ColoringMode Returns ------- pixmap : QPixmap Color gradient pixmap for the specified coloring mode. """ width, height = size if coloring_mode == ColoringMode.CONSTANT: color_linspace = self._color_gradient(start=self.color_constant, end=self.color_constant, num_steps=width) else: color_linspace = self._color_gradient( start=self.color_gradient_start, end=self.color_gradient_end, num_steps=width, ) gradient_colors_8bit = np.round(color_linspace * 255, 0).astype(int) image = Image.new(mode="RGBA", size=size, color="white") draw = ImageDraw(image) for x in range(width): draw.line( xy=[(x, 0), (x, height - 1)], fill=tuple(gradient_colors_8bit[x]), width=1, ) q_image = ImageQt(image) pixmap = QPixmap.fromImage(q_image) return pixmap
def draw_dragon_curve(self, start: Point, end: Point, draw: ImageDraw.ImageDraw): length = distance(start, end) if length < 1: draw.line((int(round(start.x)), int(round(start.y)), int(round(end.x)), int(round(end.y))), fill=ImageColor.getrgb("red")) else: if (end.x - start.x) == 0: line_angle = math.atan((start.y - end.y)) else: line_angle = math.atan((start.y - end.y) / (end.x - start.x)) if end.x < start.x: line_angle += math.pi point3_angle = line_angle + math.pi / 4 point3_x = start.x + math.cos(point3_angle) * length / math.sqrt(2) point3_y = start.y - math.sin(point3_angle) * length / math.sqrt(2) point3 = Point(point3_x, point3_y) self.draw_dragon_curve(start, point3, draw) self.draw_dragon_curve(end, point3, draw)
def draw_help_map(self, draw: ImageDraw.ImageDraw, ray_origin: glm.vec2, grid: GridMap, scale: glm.ivec2, hits: List[Hit]): self.clear_buffer(draw, (0, 0, scale.x, scale.y)) scale = scale / grid.size for x in range(grid.size.x): for y in range(grid.size.y): xx, yy = x * scale.x, y * scale.y if grid.get(x, y) == ord('#'): draw.rectangle((xx, yy, xx + scale.x, yy + scale.y), fill=COLOR_RED) else: draw.rectangle((xx, yy, xx + scale.x, yy + scale.y), outline=COLOR_GREEN) player = ray_origin / grid.cell_size * scale draw.rectangle((*(player - 1), *(player + 1)), COLOR_WHITE) for hit in hits: point = hit.point / grid.cell_size * scale draw.line((*player, *point), COLOR_YELLOW)
def get_drawn_img(img_file: BytesIO) -> InputFile: img: Image.Image = Image.open(img_file) draw = ImageDraw(img) font: str if platform == "linux" or platform == "linux2": font = "DejaVuSans.ttf" elif platform == "win32" or platform == "windows": font = "arial.ttf" fnt = ImageFont.truetype(font, 70) draw.line((0, 0, 0, img.size[1]), width=12, fill=65280) draw.text((15, 0), str(0), font=fnt, fill=65280) draw.text((15, img.size[1] - 70), str(img.size[1]), font=fnt, fill=65280) drawn_img_file = BytesIO() img.save(drawn_img_file, format="png") drawn_img_file.seek(0) return InputFile(drawn_img_file)
def _render(self, draw: ImageDraw.ImageDraw, image: Image.Image): rect = (self._position[0], self._position[1], self._position[0] + self._width, self._position[1] + self._height) # Border draw.rectangle(rect, fill=0, outline=1) # Fill p_range = abs(self._min_value) + abs(self._max_value) zero_pct = (0 + abs(self._min_value)) / p_range zero_pt = (self._position[0] + 2 + (zero_pct * (self._width - 4)), self._position[1] + 2) val_pct = self._value / (self._max_value - self._min_value) fill_rect = (zero_pt[0], zero_pt[1], zero_pt[0] + (val_pct * (self._width - 4)), zero_pt[1] + self._height - 4) draw.rectangle(fill_rect, fill=1) # Draw Zero Indicator draw.line((zero_pt[0], zero_pt[1] - 1, zero_pt[0], zero_pt[1] + self._height - 2), fill=255, width=1) # Draw Intervals if self._interval > 0: for i in range(0, self._max_value + 1, self._interval): itv_pct = i / p_range itv_pos = (zero_pt[0] + (itv_pct * (self._width - 4)), zero_pt[1] + (self._height / 2)) draw.line((itv_pos[0], itv_pos[1], itv_pos[0], zero_pt[1] + self._height - 3), fill=255, width=1) for i in range(0, self._min_value - 1, -self._interval): itv_pct = i / p_range itv_pos = (zero_pt[0] + (itv_pct * (self._width - 4)), zero_pt[1] + (self._height / 2)) draw.line((itv_pos[0], itv_pos[1], itv_pos[0], zero_pt[1] + self._height - 3), fill=255, width=1)
def main(progname, **kwargs): options = {"save": "./ttellipse.png"} options.update(**kwargs) im = Image.new("RGBA", (800, 800)) imd = ImageDraw(im) # background pattern imd.rectangle((0, 0, 800, 800), (0, 0, 255)) for i in range(400): imd.polygon( tuple( tt.tellipse(9, offset=(40 * (i % 20 + .5), 40 * (i // 20 + .5)))), (0, 255, 0)) # fill for i in range(441): imd.polygon( tuple(tt.tellipse(4.5, offset=(40 * (i % 21), 40 * (i // 21)))), (255, 0, 0)) # fill # bigger xy = tuple(tt.tellipse(300, offset=(400, 400))) imd.polygon(xy, (255, 255, 0)) # fill imd.line(xy + xy[0], (255, 0, 255), 18) # stroke # smaller n_xy = 400 xy = tuple(tt.tellipse(200, 0, 1, count=n_xy)) x0, y0 = xy[0] for i_xy in range(1, n_xy): x1, y1 = xy[i_xy] a, b = (x0, x1) if x0 < x1 else (x1, x0) c, d = (y0, y1) if y0 < y1 else (y1, y0) imd.rectangle((400 - a, 400 + c, 400 + b, 400 + d), (0, 255, 255)) x0, y0 = x1, y1 if options["save"] and type(options["save"]) is str: im.save(options["save"]) print("{:}: image written to {:s}".format(progname, options["save"])) if "show" in options: im.show()
def draw_rounded_rectangle(draw: ImageDraw, xy, corner_radius, fill=None, outline=None, width=None): rad = corner_radius upper_left = xy[0] bottom_right = xy[1] draw.rectangle( [ (upper_left[0], upper_left[1] + rad), (bottom_right[0], bottom_right[1] - rad) ], fill=fill, ) draw.rectangle( [ (upper_left[0] + rad, upper_left[1]), (bottom_right[0] - rad, bottom_right[1]) ], fill=fill, ) draw.pieslice([upper_left, (upper_left[0] + rad * 2, upper_left[1] + rad * 2)], 180, 270, fill=fill ) draw.pieslice([(bottom_right[0] - rad * 2, bottom_right[1] - rad * 2), bottom_right], 0, 90, fill=fill ) draw.pieslice([(upper_left[0], bottom_right[1] - rad * 2), (upper_left[0] + rad * 2, bottom_right[1])], 90, 180, fill=fill ) draw.pieslice([(bottom_right[0] - rad * 2, upper_left[1]), (bottom_right[0], upper_left[1] + rad * 2)], 270, 360, fill=fill ) border_delta = width/2 - 1 if width > 0: draw.line([(upper_left[0] + rad, upper_left[1] + border_delta), (bottom_right[0] - rad, upper_left[1] + border_delta)], fill=outline, width=width) draw.line([(bottom_right[0] - border_delta, upper_left[1] + rad), (bottom_right[0] - border_delta, bottom_right[1] - rad)], fill=outline, width=width) draw.line([(bottom_right[0] - rad, bottom_right[1] - border_delta), (upper_left[0] + rad, bottom_right[1] - border_delta)], fill=outline, width=width) draw.line([(upper_left[0] + border_delta, bottom_right[1] - rad), (upper_left[0] + border_delta, upper_left[1] + rad)], fill=outline, width=width) draw.arc([upper_left, (upper_left[0] + rad * 2, upper_left[1] + rad * 2)], 180, 270, fill=outline, width=width) draw.arc([(bottom_right[0] - rad * 2, upper_left[1]), (bottom_right[0], upper_left[1] + rad * 2)], 270, 360, fill=outline, width=width) draw.arc([(bottom_right[0] - rad * 2, bottom_right[1] - rad * 2), bottom_right], 0, 90, fill=outline, width=width) draw.arc([(upper_left[0], bottom_right[1] - rad * 2), (upper_left[0] + rad * 2, bottom_right[1])], 90, 180, fill=outline, width=width)
def gradient_pixmap( color_start: TupleFloat4, color_end: TupleFloat4, size: Tuple[int, int], ) -> QPixmap: """Generate color gradient pixmap. Parameters ---------- color_start : Tuple[float, float, float] RGBA color tuple, values [0;1]. color_end : Tuple[float, float, float] RGBA color tuple, values [0;1]. size : Tuple[int, int] Size in pixels (width, height). Returns ------- pixmap : QPixmap """ width, height = size gradient_colors = np.linspace(np.array(color_start), np.array(color_end), num=width, endpoint=True) gradient_colors *= 255 gradient_colors = np.round(gradient_colors, 0).astype(int) image = Image.new(mode="RGBA", size=size, color="white") draw = ImageDraw(image) for x in range(width): draw.line(xy=[(x, 0), (x, height - 1)], fill=tuple(gradient_colors[x]), width=1) q_image = ImageQt(image) pixmap = QPixmap.fromImage(q_image) return pixmap
def run(self): # no need to overwrite parent's init turtle = self.turtle colors = self.colors if self.load_from_cache(): return self.canvas.begin_new() im_draw = ImageDraw(self.canvas.pil_image) color = self.colors["1"] # Calculate size, and scale to fill the frame t_width = turtle.rightmost[0] - turtle.leftmost[0] t_height = turtle.bottommost[1] - turtle.topmost[1] if t_width / t_height > 1: # fat image scale according to width scale_factor = self.canvas.c_width / t_width else: scale_factor = self.canvas.c_height / t_height left_margin = (self.canvas.c_width - scale_factor*t_width) / 2 top_margin = (self.canvas.c_height - scale_factor*t_height) / 2 x_shift = left_margin - scale_factor*turtle.leftmost[0] y_shift = top_margin - scale_factor*turtle.topmost[1] coordinates = [] for item in turtle.lines: if self._stop_drawing.isSet(): return if isinstance(item, PlaceHolder): coordinates.append(item) else: coordinates.append((item[0]*scale_factor+x_shift, item[1]*scale_factor+y_shift, item[2]*scale_factor+x_shift, item[3]*scale_factor+y_shift)) i = 0 for item in coordinates: if self._stop_drawing.isSet(): return "Update canvas after each 3000 stroke" i += 1 if i > 3000: self.canvas.update_image() i = 0 if isinstance(item, PlaceHolder): # not a list of coordinates if item.value in colors: color = colors[item.value] else: im_draw.line(item, color) self.canvas.update_image() self.save_to_cache()
def renderTile(self, width, height, srs, coord): # return an object with a PIL-like save() method for a tile _width, _height = width / self.scale, height / self.scale img = Image.new("RGB", (_width, _height), (0, 0, 0)) draw = ImageDraw(img) # # Prepare query geometry. # ul = self.layer.projection.coordinateProj(coord) lr = self.layer.projection.coordinateProj(coord.down().right()) x_offset, y_offset = -ul.x, -ul.y x_scale, y_scale = _width / (lr.x - ul.x), _height / (lr.y - ul.y) transform = x_offset, y_offset, x_scale, y_scale buf = (lr.x - ul.x) / 2 bbox = ( "ST_SetSRID(ST_Buffer(ST_MakeBox2D(ST_MakePoint(%.3f, %.3f), ST_MakePoint(%.3f, %.3f)), %.3f, 2), 900913)" % (ul.x, ul.y, lr.x, lr.y, buf) ) colors = product(range(0, 0xFF, 4), range(0, 0xFF, 4), range(0x66, 0xFF, 4)) # # Draw the grid itself and note object color keys as we go. # objects = {} db = connect(database="geodata", user="******").cursor() for (id, type, name, shape) in get_landusages_imposm(db, bbox, *transform): rgb = colors.next() objects[rgb] = "land", type, name, id for geom in getattr(shape, "geoms", [shape]): for ring in [geom.exterior] + list(geom.interiors): draw.polygon(list(ring.coords), fill=rgb) if coord.zoom >= 17: for (id, type, shape) in get_buildings_imposm(db, bbox, *transform): rgb = colors.next() objects[rgb] = "building", name, id for geom in getattr(shape, "geoms", [shape]): for ring in [geom.exterior] + list(geom.interiors): draw.polygon(list(ring.coords), fill=rgb) if coord.zoom >= 15: road_lines = get_roads_imposm(db, bbox, *transform) else: road_lines = get_mainroads_imposm(db, bbox, *transform) + get_motorways_imposm(db, bbox, *transform) for (id, type, name, way) in road_lines: rgb = colors.next() objects[rgb] = "road", type, name, id for geom in getattr(way, "geoms", [way]): stroke = {18: 4, 17: 3}.get(coord.zoom, 2) draw.line(list(geom.coords), fill=rgb, width=stroke) db.close() # # Collect actual rgb values from image and sort them by frequency # so we can build up a grid with the most number of one-and-two-digit # numbers that are also keys into the details array. # data = [(r, g, b) for (r, g, b) in img.getdata()] rgb_counts = {} for rgb in data: rgb_counts[rgb] = rgb_counts.get(rgb, 0) + 1 rgb_counts = sorted(rgb_counts.items(), key=itemgetter(1), reverse=True) rgb_indexes = [key for (key, count) in rgb_counts] # # Build a details array and a two-dimensional column-major grid. # details = [objects.get(rgb, None) for rgb in rgb_indexes] grid = [] for row in range(_height): row, data = data[:_width], data[_width:] row = [rgb_indexes.index(rgb) for rgb in row] grid.append(row) return GridResponse(img.resize((width, height), Image.NEAREST), [details, grid])