def get(self, size): if not self.defined: return None if self.size == size and self._pixmap is not None: #logging.debug("{}: already rendered".format(self.path)) return self._pixmap else: self.size = size if self.path.endswith(".svg"): renderer = QSvgRenderer(self.path) if size is None: self.size = size = renderer.defaultSize().width() #print("Rendering SVG {}: {}".format(self.path, size)) self._pixmap = QPixmap(size, size) self._pixmap.fill(Qt.transparent) painter = QPainter(self._pixmap) renderer.render(painter) painter.end() else: if size is None: self._pixmap = QPixmap(self.path) self.size = self._pixmap.width() else: self._pixmap = QPixmap(self.path).scaled(size, size) return self._pixmap
def rasterize_svg(self, elem, width=0, height=0, format='PNG'): view_box = elem.get('viewBox', elem.get('viewbox', None)) sizes = None logger = self.oeb.logger if view_box is not None: try: box = [ float(x) for x in [_f for _f in re.split('[, ]', view_box) if _f] ] sizes = [box[2] - box[0], box[3] - box[1]] except (TypeError, ValueError, IndexError): logger.warn( 'SVG image has invalid viewBox="%s", ignoring the viewBox' % view_box) else: for image in elem.xpath( 'descendant::*[local-name()="image" and ' '@height and contains(@height, "%")]'): logger.info( 'Found SVG image height in %, trying to convert...') try: h = float(image.get('height').replace('%', '')) / 100. image.set('height', str(h * sizes[1])) except: logger.exception( 'Failed to convert percentage height:', image.get('height')) data = QByteArray(xml2str(elem, with_tail=False)) svg = QSvgRenderer(data) size = svg.defaultSize() if size.width() == 100 and size.height() == 100 and sizes: size.setWidth(sizes[0]) size.setHeight(sizes[1]) if width or height: size.scale(width, height, Qt.KeepAspectRatio) logger.info('Rasterizing %r to %dx%d' % (elem, size.width(), size.height())) image = QImage(size, QImage.Format_ARGB32_Premultiplied) image.fill(QColor("white").rgb()) painter = QPainter(image) svg.render(painter) painter.end() array = QByteArray() buffer = QBuffer(array) buffer.open(QIODevice.WriteOnly) image.save(buffer, format) return str(array)
def render_svg(widget, path): img = QPixmap() rend = QSvgRenderer() if rend.load(path): dpr = getattr(widget, 'devicePixelRatioF', widget.devicePixelRatio)() sz = rend.defaultSize() h = (max_available_height() - 50) w = int(h * sz.height() / float(sz.width())) pd = QImage(w * dpr, h * dpr, QImage.Format_RGB32) pd.fill(Qt.white) p = QPainter(pd) rend.render(p) p.end() img = QPixmap.fromImage(pd) img.setDevicePixelRatio(dpr) return img
def rasterize_svg(self, elem, width=0, height=0, format='PNG'): view_box = elem.get('viewBox', elem.get('viewbox', None)) sizes = None logger = self.oeb.logger if view_box is not None: try: box = [float(x) for x in filter(None, re.split('[, ]', view_box))] sizes = [box[2]-box[0], box[3] - box[1]] except (TypeError, ValueError, IndexError): logger.warn('SVG image has invalid viewBox="%s", ignoring the viewBox' % view_box) else: for image in elem.xpath('descendant::*[local-name()="image" and ' '@height and contains(@height, "%")]'): logger.info('Found SVG image height in %, trying to convert...') try: h = float(image.get('height').replace('%', ''))/100. image.set('height', str(h*sizes[1])) except: logger.exception('Failed to convert percentage height:', image.get('height')) data = QByteArray(xml2str(elem, with_tail=False)) svg = QSvgRenderer(data) size = svg.defaultSize() if size.width() == 100 and size.height() == 100 and sizes: size.setWidth(sizes[0]) size.setHeight(sizes[1]) if width or height: size.scale(width, height, Qt.KeepAspectRatio) logger.info('Rasterizing %r to %dx%d' % (elem, size.width(), size.height())) image = QImage(size, QImage.Format_ARGB32_Premultiplied) image.fill(QColor("white").rgb()) painter = QPainter(image) svg.render(painter) painter.end() array = QByteArray() buffer = QBuffer(array) buffer.open(QIODevice.WriteOnly) image.save(buffer, format) return str(array)
def rasterize_external(self, elem, style, item, svgitem): width = style['width'] height = style['height'] width = (width / 72) * self.profile.dpi height = (height / 72) * self.profile.dpi data = QByteArray(str(svgitem)) svg = QSvgRenderer(data) size = svg.defaultSize() size.scale(width, height, Qt.KeepAspectRatio) key = (svgitem.href, size.width(), size.height()) if key in self.images: href = self.images[key] else: logger = self.oeb.logger logger.info('Rasterizing %r to %dx%d' % (svgitem.href, size.width(), size.height())) image = QImage(size, QImage.Format_ARGB32_Premultiplied) image.fill(QColor("white").rgb()) painter = QPainter(image) svg.render(painter) painter.end() array = QByteArray() buffer = QBuffer(array) buffer.open(QIODevice.WriteOnly) image.save(buffer, 'PNG') data = str(array) manifest = self.oeb.manifest href = os.path.splitext(svgitem.href)[0] + '.png' id, href = manifest.generate(svgitem.id, href) manifest.add(id, href, PNG_MIME, data=data) self.images[key] = href elem.tag = XHTML('img') for attr in elem.attrib: if attr not in KEEP_ATTRS: del elem.attrib[attr] elem.attrib['src'] = item.relhref(href) if elem.text: elem.attrib['alt'] = elem.text elem.text = None for child in elem: elem.remove(child)
def _get(self, size): self.size = size if self.is_image: if self.path.endswith(".svg"): renderer = QSvgRenderer(self.path) if size is None: self.size = size = renderer.defaultSize().width( ), renderer.defaultSize().height() #print("Rendering SVG {}: {}".format(self.path, size)) pixmap = QPixmap(*size) pixmap.fill(Qt.transparent) painter = QPainter(pixmap) renderer.render(painter) painter.end() else: if size is None: pixmap = QPixmap(self.path) self.size = pixmap.width(), pixmap.height() else: pixmap = QPixmap(self.path).scaled(*size) else: if size is None: pixmap = QPixmap(256, 256) self.size = pixmap.width(), pixmap.height() else: pixmap = QPixmap(*size) pixmap.fill(self.color) return pixmap
#!/usr/bin/env python3 # -*- coding: utf-8 -*- __author__ = 'ipetrash' # SOURCE: https://stackoverflow.com/a/8551810/5909792 from PyQt5.Qt import QApplication, QSvgRenderer, QImage, Qt, QPainter # A QApplication instance is necessary if fonts are used in the SVG app = QApplication([]) # Load your SVG renderer = QSvgRenderer("input.svg") for width, height in [(32, 32), (64, 64), (512, 512), (4096, 4096)]: # Prepare a QImage with desired characteritisc image = QImage(width, height, QImage.Format_ARGB32) # Partly transparent red-ish background image.fill(Qt.transparent) # Get QPainter that paints to the image painter = QPainter(image) renderer.render(painter) # Save, image format based on file extension image.save("output_{}x{}.png".format(width, height)) # FIX error: "Process finished with exit code -1073741819 (0xC0000005)" painter.end()