def img_save(): img_path = PATH.rsplit('.', 1)[0] font = TTFont( PATH) # it would work just as well with fontTools.t1Lib.T1Font glyf = font['glyf'] if not os.path.exists(img_path): os.makedirs(img_path) for glyphName in glyf.keys(): gs = font.getGlyphSet() pen = ReportLabPen(gs, Path(fillColor=colors.black, strokeWidth=1)) g = gs[glyphName] g.draw(pen) # 调整图片大小 w, h = 800, 800 g = Group(pen.path) g.translate(10, 200) g.scale(0.3, 0.3) d = Drawing(w, h) d.add(g) image = renderPM.drawToPIL(d) little_image = image.resize((180, 180)) fromImage = Image.new('RGBA', (360, 360), color=(255, 255, 255)) fromImage.paste(little_image, (0, 0)) # fromImage.show() glyphName = glyphName.replace('uni', '&#x') imageFile = img_path + "/%s.png" % glyphName fromImage.save(imageFile) break
def get_png(self, e=None): with self.lock: d = self._create_drawing() self._render(d) rect = shapes.Rect(0, 0, d.width, d.height) rect.fillColor = colors.HexColor(0xeeeeee) rect.strokeWidth = 0 d.background = rect im = renderPM.drawToPIL(d, dpi=self.DPI) bg = PIL.Image.new("RGB", im.size, 0xffffff) diff = PIL.ImageChops.difference(im, bg) bbox = diff.getbbox() if bbox: # center bbox width = im.size[0] minx, miny, maxx, maxy = bbox width2 = width / 2 if width2 - minx < maxx - width2: minx = width - maxx # width2 - (maxx - width2) else: maxx = width - minx # width2 + (width2 - minx) im = im.crop((minx, miny, maxx, maxy)) imgdata = StringIO.StringIO() im.save(imgdata, 'PNG') return imgdata.getvalue()
def generate_pic(glyphname, font: TTFont, size=120, scale=0.1): """ 生成图片 -> 预处理 -> 保存到本地 Args: glyphname: font: file_suffix: size: scale: Returns: """ gs = font.getGlyphSet() pen = ReportLabPen(gs, Path(fillColor=colors.black, strokeWidth=1)) g = gs[glyphname] g.draw(pen) w, h = size, size # Everything is wrapped in a group to allow transformations. g = Group(pen.path) # g.translate(10, 20) g.scale(scale, scale) d = Drawing(w, h) d.add(g) return renderPM.drawToPIL(d)
def make_number_image(n: int, font_size=80.9) -> Image: canvas_size = font_size * Size.from_tuple(Ratio.FONT_CANVAS_SIZE) dwg = svgwrite.Drawing('test.svg', size=canvas_size) text = f'no.{n:04}' params = dict( fill='black', font_size=f'{font_size}pt', font_family="DXGulimB-KSCpc-EUC-H", lengthAdjust="spacing", # font_weight='bold', kerning='5px', letter_spacing="4", ) dwg.add(dwg.text(text, insert=('0%', '85%'), **params)) dwg.add(dwg.text(text, insert=('1%', '85%'), **params)) with io.StringIO() as svg: dwg.write(svg) svg.seek(0) svg_text = svg.read() with io.BytesIO() as svg: svg.write(svg_text.encode()) svg.seek(0) drawing = svg2rlg(svg) img = renderPM.drawToPIL(drawing, 300) return trim(img)
def residue_to_Image(self, resname, size=(200, 200)): '''Returns PIL image of chemical structure Parameters ----------- resname: str Name of residue size: (float,float), optional dimensions of image saved to file Returns -------- img: :class:`PIL.Image.Image` ''' try: from rdkit import Chem from rdkit.Chem import Draw except (ModuleNotFoundError, ImportError) as e: raise ModuleNotFoundError( "RDKit is required for visualization of chemical structures. See https://www.rdkit.org/docs/Install.html" ) from e if resname in self.residues or resname in self.eta_moieties: if "CUST" in resname: raise KeyError("Not available for user defined residues.") elif resname[:3] in clusters: cluster_img_name = os.path.abspath(os.path.dirname( __file__)) + '/data/clusters/' + resname[:3] + '.svg' drawing = svg2rlg(cluster_img_name) img = renderPM.drawToPIL(drawing) return img else: mol = Chem.MolFromSmarts(self.smiles[resname]) img = Draw.MolToImage(mol, kekulize=False, size=size) return img else: raise KeyError("No record of any residue by that name.")
def ttf_to_image(self): """ 将ttf字体文件的字体绘制在Image对象上 :return: """ glyphset = self.font.getGlyphSet() size = (BASE_BACKGOUND_WIDTH * FONT_NUMS_PER_LINE, ceil(len(self.glyphnames) / FONT_NUMS_PER_LINE) * BASE_BACKGOUND_HEIGHT) # 背景图片尺寸 image = Image.new("RGB", size=size, color=(255, 255, 255)) # 初始化背景图片 name_list, image_dict = [], {} for index, glyphname in enumerate(self.glyphnames): if glyphname[0] in ['.', 'g'] or glyphname in self.ignore_names: # 跳过'.notdef', '.null' continue g = glyphset[glyphname] pen = ReportLabPen(self.glyphnames, Path(fillColor=colors.black, strokeWidth=1)) g.draw(pen) # w, h = g.width, g.width w, h = g.width if g.width > 1000 else 1000, g.width if g.width > 1000 else 1000 g = Group(pen.path) g.translate(0, 200) d = Drawing(w, h) d.add(g) im = renderPM.drawToPIL(d, dpi=72).resize((FONT_WIDTH, FONT_HEIGHT)) box = ( (index % FONT_NUMS_PER_LINE) * BASE_BACKGOUND_WIDTH, (index // FONT_NUMS_PER_LINE) * BASE_BACKGOUND_HEIGHT) image.paste(im, box=box) name_list.append(glyphname) image_dict[glyphname] = im return image, name_list, image_dict
def make_ticket(fio, from_, to, date, person): im = Image.open(PATH) draw = ImageDraw.Draw(im) font = ImageFont.truetype(os.path.join("fonts", "ofont_ru_PetersburgITT.ttf"), size=20) data = {} x = 45 y = im.size[1] // 3 - 10 data[fio] = (x, y) y = im.size[1] // 3 + (10 + font.size) * 2 data[from_] = (x, y) y = im.size[1] // 2 + (10 + font.size) * 2 data[to] = (x, y) x = im.size[0] // 2.4 data[date] = (x, y) for key, value in data.items(): draw.text(value, key, font=font, fill=ImageColor.colormap['black']) url = f"https://joeschmoe.io/api/v1/{person}" response = requests.get(url, stream=True).content avatar_file_like = BytesIO(response) drawing = svg2rlg(avatar_file_like) avatar = renderPM.drawToPIL(drawing) im.paste(avatar, (400, 70)) path_out = Path.cwd() / "images" / f"ticket_filled_{fio}_{date}.png" im.save(path_out) return path_out
def _load_svg(self, value): manager = getManager(self.context) width = self.context.element.get('width') if width is not None: width = Measurement().fromUnicode(width) height = self.context.element.get('height') if height is not None: height = Measurement().fromUnicode(height) preserve = self.context.element.get('preserveAspectRatio') if preserve is not None: preserve = Boolean().fromUnicode(preserve) cache_key = f'{value}-{width}x{height}-{preserve}' if cache_key in manager.svgs: return manager.svgs[cache_key] from gzip import GzipFile from xml.etree import cElementTree from reportlab.graphics import renderPM from z3c.rml.svg2rlg import Renderer fileObj = super().fromUnicode(value) svg = fileObj.getvalue() if svg[:2] == b'\037\213': svg = GzipFile(fileobj=fileObj).read() svg = cElementTree.fromstring(svg) svg = Renderer(value).render(svg) if preserve: if width is not None or height is not None: if width is not None and height is None: height = svg.height * width / svg.width elif height is not None and width is None: width = svg.width * height / svg.height elif float(width) / height > float(svg.width) / svg.height: width = svg.width * height / svg.height else: height = svg.height * width / svg.width else: if width is None: width = svg.width if height is None: height = svg.height svg.scale(width / svg.width, height / svg.height) svg.width = width svg.height = height svg = renderPM.drawToPIL(svg, dpi=300) svg = reportlab.lib.utils.ImageReader(svg) # A hack to getImageReader through as an open Image when used with # imageAndFlowables svg.read = True manager.svgs[cache_key] = svg return svg
def makeThumbnail(self, size): folder, basename = os.path.split(self.output_path) name, ext = os.path.splitext(basename) drawing = svg2rlg(self.output_path) im = renderPM.drawToPIL(drawing) # bg=0xe5e5e5, configPIL={'transparent': True} # See https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.Image.thumbnail im.thumbnail((size, size)) png_file = os.path.join(folder, name + '.png') im.save(png_file)
def _load_svg(self, value): manager = getManager(self.context) width = self.context.element.get('width') if width is not None: width = Measurement().fromUnicode(width) height = self.context.element.get('height') if height is not None: height = Measurement().fromUnicode(height) preserve = self.context.element.get('preserveAspectRatio') if preserve is not None: preserve = Boolean().fromUnicode(preserve) cache_key = '%s-%sx%s-%s' % (value, width, height, preserve) if cache_key in manager.svgs: return manager.svgs[cache_key] from gzip import GzipFile from reportlab.graphics import renderPM from xml.etree import cElementTree from z3c.rml.svg2rlg import Renderer fileObj = super(Image, self).fromUnicode(value) svg = fileObj.getvalue() if svg[:2] == b'\037\213': svg = GzipFile(fileobj=fileObj).read() svg = cElementTree.fromstring(svg) svg = Renderer(value).render(svg) if preserve: if width is not None or height is not None: if width is not None and height is None: height = svg.height * width / svg.width elif height is not None and width is None: width = svg.width * height / svg.height elif float(width) / height > float(svg.width) / svg.height: width = svg.width * height / svg.height else: height = svg.height * width / svg.width else: if width is None: width = svg.width if height is None: height = svg.height svg.scale(width / svg.width, height / svg.height) svg.width = width svg.height = height svg = renderPM.drawToPIL(svg, dpi=300) svg = reportlab.lib.utils.ImageReader(svg) svg.read = True # A hack to get ImageReader through as an open Image # when used with imageAndFlowables manager.svgs[cache_key] = svg return svg
def printLabel(name): width = 500 height = 100 d = Drawing(width, height) d.add(String(5, 5, name, fontSize=40, fontName='Helvetica')) #d.add(String(5, 5, name, fontSize=60, fontName='Helvetica')) qlr = BrotherQLRaster('QL-1050') #qlr = BrotherQLRaster('QL-800') create_label(qlr, renderPM.drawToPIL(d), LABEL_NAME, rotate=0, cut=True, dpi_600=DPI_600) send(qlr.data, PRINTER)
def one_to_image(self, glyph_name): glyphset = self.font.getGlyphSet() try: glyph = glyphset[glyph_name] except KeyError as e: raise KeyError("{} dont't in {}".format(glyph_name, self.font_file_name)) pen = ReportLabPen(self.glyphnames, Path(fillColor=colors.black, strokeWidth=1)) glyph.draw(pen) w, h = glyph.width if glyph.width > 1000 else 1000, glyph.width if glyph.width > 1000 else 1000 d = Drawing(w, h) g = Group(pen.path) g.translate(0, 150) d.add(g) im = renderPM.drawToPIL(d, dpi=72).resize((FONT_WIDTH, FONT_HEIGHT)) return im
def draw_one(self, unicode, font_io): ttf_font = TTFont(font_io) glyphSet = ttf_font.getGlyphSet() if unicode not in glyphSet: return None glyph = glyphSet[unicode] pen = reportLabPen.ReportLabPen( glyphSet, Path(fillColor=colors.black, strokeWidth=1)) glyph.draw(pen) w, h = glyph.width, glyph._glyph.yMax - glyph._glyph.yMin yOffset = -glyph._glyph.yMin * \ self.font_scale + h * (1 - self.font_scale) / 2 glyph = Group(pen.path) glyph.translate(w * (1 - self.font_scale) / 2, yOffset) glyph.scale(self.font_scale, self.font_scale) draw = Drawing(w, h) draw.add(glyph) PIL_image = renderPM.drawToPIL(draw) return PIL_image
def get_frame(terminal_width: int = 80) -> str: pixel_width = terminal_width * 2 cutoff = get_cutoff(pixel_width) base_path = path.dirname(__file__) world_path = path.abspath(path.join(base_path, "world.svg")) drawing = svg2rlg(world_path) image = renderPM.drawToPIL(drawing) height, width = image.size image = image.resize((pixel_width, int(width / height * pixel_width))) height, width = image.size canvas = Canvas() for x in range(0, height): for y in range(0, width): pixel = image.getpixel((x, y)) if pixel[0] < cutoff and pixel[1] < cutoff and pixel[2] < cutoff: canvas.set(x, y) return canvas.frame()
def draw_all(self, font_io): ttf_font = TTFont(font_io) glyphSet = ttf_font.getGlyphSet() font_image_dict = {} for glyphName in glyphSet.keys(): if (not glyphName.startswith('uni')): continue pen = reportLabPen.ReportLabPen( glyphSet, Path(fillColor=colors.black, strokeWidth=1)) glyph = glyphSet[glyphName] glyph.draw(pen) w, h = glyph.width, glyph._glyph.yMax - glyph._glyph.yMin yOffset = -glyph._glyph.yMin * \ self.font_scale + h * (1 - self.font_scale) / 2 glyph = Group(pen.path) glyph.translate(w * (1 - self.font_scale) / 2, yOffset) glyph.scale(self.font_scale, self.font_scale) draw = Drawing(w, h) draw.add(glyph) PIL_image = renderPM.drawToPIL(draw) font_image_dict[glyphName] = PIL_image return font_image_dict
def editSVG( self, sizepxl, ThrD=0 ): #this function edits the svg and makes the squares in the QR code small tree = etree.parse(open('QRSVGpy.svg')) pxl = str(int(sizepxl / 10)) + "mm" dessiz = 0.8 #desired size for the reduced square QR code, recommended 0.8 for element in tree.iter( ): #this loop finds all squares and makes them small if element.tag.split("}")[1] == "rect": if element.get("width") == pxl: element.set( "width", str(int(element.get("width")[0]) * dessiz) + "mm") element.set( "height", str(int(element.get("height")[0]) * dessiz) + "mm") tree.write('QRSVGpysmall.svg') #saves modified SVG into file #svg=tree2.findall(".//{http://www.w3.org/2000/svg}rect") #find all rect elements COULD USE THIS TO FIND AND LEAVE THE BIG SQUARES BIG drawing = svg2rlg('QRSVGpysmall.svg') #renderPM.drawToFile(drawing, "QRSVGpysmall.png", fmt="PNG") #Uncomment this line to save automatically a png of the QR code with the smaller squares QRcodesmallsq = renderPM.drawToPIL( drawing ) #This line saves the svg into a png to work with later with numpy as an array if ThrD == 1: enc.extrudeSVG(QRcodesmallsq)