Exemplo n.º 1
0
 def __init__(self):
     pictureflow.FlowImages.__init__(self)
     self.num = 40000
     i1, i2 = QImage(300, 400, QImage.Format.Format_RGB32), QImage(
         300, 400, QImage.Format.Format_RGB32)
     i1.fill(Qt.GlobalColor.green), i2.fill(Qt.GlobalColor.blue)
     self.images = [i1, i2]
Exemplo n.º 2
0
def create_icon(text, palette=None, sz=None, divider=2, fill='white'):
    if isinstance(fill, string_or_bytes):
        fill = QColor(fill)
    sz = sz or int(
        math.ceil(tprefs['toolbar_icon_size'] *
                  QApplication.instance().devicePixelRatio()))
    if palette is None:
        palette = QApplication.palette()
    img = QImage(sz, sz, QImage.Format.Format_ARGB32)
    img.fill(Qt.GlobalColor.transparent)
    p = QPainter(img)
    p.setRenderHints(QPainter.RenderHint.TextAntialiasing
                     | QPainter.RenderHint.Antialiasing)
    if fill is not None:
        qDrawShadeRect(p,
                       img.rect(),
                       palette,
                       fill=fill,
                       lineWidth=1,
                       midLineWidth=1)
    f = p.font()
    f.setFamily('Liberation Sans'), f.setPixelSize(int(
        sz // divider)), f.setBold(True)
    p.setFont(f), p.setPen(QColor('#2271d5'))
    p.drawText(img.rect().adjusted(2, 2, -2, -2), Qt.AlignmentFlag.AlignCenter,
               text)
    p.end()
    return QIcon(QPixmap.fromImage(img))
Exemplo n.º 3
0
def generate_masthead(title,
                      output_path=None,
                      width=600,
                      height=60,
                      as_qimage=False,
                      font_family=None):
    init_environment()
    font_family = font_family or cprefs[
        'title_font_family'] or 'Liberation Serif'
    img = QImage(width, height, QImage.Format.Format_ARGB32)
    img.fill(Qt.GlobalColor.white)
    p = QPainter(img)
    p.setRenderHints(QPainter.RenderHint.Antialiasing
                     | QPainter.RenderHint.TextAntialiasing)
    f = QFont(font_family)
    f.setStyleStrategy(QFont.StyleStrategy.PreferAntialias)
    f.setPixelSize((height * 3) // 4), f.setBold(True)
    p.setFont(f)
    p.drawText(img.rect(),
               Qt.AlignmentFlag.AlignLeft | Qt.AlignmentFlag.AlignVCenter,
               sanitize(title))
    p.end()
    if as_qimage:
        return img
    data = pixmap_to_data(img)
    if output_path is None:
        return data
    with open(output_path, 'wb') as f:
        f.write(data)
Exemplo n.º 4
0
def drag_icon(self, cover, multiple):
    cover = cover.scaledToHeight(120,
                                 Qt.TransformationMode.SmoothTransformation)
    if multiple:
        base_width = cover.width()
        base_height = cover.height()
        base = QImage(base_width + 21, base_height + 21,
                      QImage.Format.Format_ARGB32_Premultiplied)
        base.fill(QColor(255, 255, 255, 0).rgba())
        p = QPainter(base)
        rect = QRect(20, 0, base_width, base_height)
        p.fillRect(rect, QColor('white'))
        p.drawRect(rect)
        rect.moveLeft(10)
        rect.moveTop(10)
        p.fillRect(rect, QColor('white'))
        p.drawRect(rect)
        rect.moveLeft(0)
        rect.moveTop(20)
        p.fillRect(rect, QColor('white'))
        p.save()
        p.setCompositionMode(
            QPainter.CompositionMode.CompositionMode_SourceAtop)
        p.drawImage(rect.topLeft(), cover)
        p.restore()
        p.drawRect(rect)
        p.end()
        cover = base
    return QPixmap.fromImage(cover)
Exemplo n.º 5
0
 def __init__(self, stream, page_size, compress=False, mark_links=False,
              debug=print):
     self.stream = HashingStream(stream)
     self.compress = compress
     self.write_line(PDFVER)
     self.write_line('%íì¦"'.encode())
     creator = ('%s %s [https://calibre-ebook.com]'%(__appname__,
                                 __version__))
     self.write_line('%% Created by %s'%creator)
     self.objects = IndirectObjects()
     self.objects.add(PageTree(page_size))
     self.objects.add(Catalog(self.page_tree))
     self.current_page = Page(self.page_tree, compress=self.compress)
     self.info = Dictionary({
         'Creator':String(creator),
         'Producer':String(creator),
         'CreationDate': utcnow(),
                             })
     self.stroke_opacities, self.fill_opacities = {}, {}
     self.font_manager = FontManager(self.objects, self.compress)
     self.image_cache = {}
     self.pattern_cache, self.shader_cache = {}, {}
     self.debug = debug
     self.page_size = page_size
     self.links = Links(self, mark_links, page_size)
     i = QImage(1, 1, QImage.Format.Format_ARGB32)
     i.fill(qRgba(0, 0, 0, 255))
     self.alpha_bit = i.constBits().asstring(4).find(b'\xff')
Exemplo n.º 6
0
def overlay_image(img, canvas=None, left=0, top=0):
    ' Overlay the `img` onto the canvas at the specified position '
    if canvas is None:
        canvas = QImage(img.size(), QImage.Format.Format_RGB32)
        canvas.fill(Qt.GlobalColor.white)
    left, top = int(left), int(top)
    imageops.overlay(img, canvas, left, top)
    return canvas
Exemplo n.º 7
0
def add_borders_to_image(img, left=0, top=0, right=0, bottom=0, border_color='#ffffff'):
    img = image_from_data(img)
    if not (left > 0 or right > 0 or top > 0 or bottom > 0):
        return img
    canvas = QImage(img.width() + left + right, img.height() + top + bottom, QImage.Format.Format_RGB32)
    canvas.fill(QColor(border_color))
    overlay_image(img, canvas, left, top)
    return canvas
Exemplo n.º 8
0
def calibre_cover2(title,
                   author_string='',
                   series_string='',
                   prefs=None,
                   as_qimage=False,
                   logo_path=None):
    init_environment()
    title, subtitle, footer = '<b>' + escape_formatting(
        title), '<i>' + escape_formatting(
            series_string), '<b>' + escape_formatting(author_string)
    prefs = prefs or cprefs
    prefs = {k: prefs.get(k) for k in cprefs.defaults}
    scale = 800. / prefs['cover_height']
    scale_cover(prefs, scale)
    prefs = Prefs(**prefs)
    img = QImage(prefs.cover_width, prefs.cover_height,
                 QImage.Format.Format_ARGB32)
    img.fill(Qt.GlobalColor.white)
    # colors = to_theme('ffffff ffffff 000000 000000')
    color_theme = theme_to_colors(fallback_colors)

    class CalibeLogoStyle(Style):
        NAME = GUI_NAME = 'calibre'

        def __call__(self, painter, rect, color_theme, title_block,
                     subtitle_block, footer_block):
            top = title_block.position.y + 10
            extra_spacing = subtitle_block.line_spacing // 2 if subtitle_block.line_spacing else title_block.line_spacing // 3
            height = title_block.height + subtitle_block.height + extra_spacing + title_block.leading
            top += height + 25
            bottom = footer_block.position.y - 50
            logo = QImage(logo_path or I('library.png'))
            pwidth, pheight = rect.width(), bottom - top
            scaled, width, height = fit_image(logo.width(), logo.height(),
                                              pwidth, pheight)
            x, y = (pwidth - width) // 2, (pheight - height) // 2
            rect = QRect(x, top + y, width, height)
            painter.setRenderHint(QPainter.RenderHint.SmoothPixmapTransform)
            painter.drawImage(rect, logo)
            return self.ccolor1, self.ccolor1, self.ccolor1

    style = CalibeLogoStyle(color_theme, prefs)
    title_block, subtitle_block, footer_block = layout_text(
        prefs, img, title, subtitle, footer,
        img.height() // 3, style)
    p = QPainter(img)
    rect = QRect(0, 0, img.width(), img.height())
    colors = style(p, rect, color_theme, title_block, subtitle_block,
                   footer_block)
    for block, color in zip((title_block, subtitle_block, footer_block),
                            colors):
        p.setPen(color)
        block.draw(p)
    p.end()
    img.setText('Generated cover', '{} {}'.format(__appname__, __version__))
    if as_qimage:
        return img
    return pixmap_to_data(img)
Exemplo n.º 9
0
    def add_image(self, img, cache_key):
        ref = self.get_image(cache_key)
        if ref is not None:
            return ref

        fmt = img.format()
        image = QImage(img)
        if (image.depth() == 1 and img.colorTable().size() == 2 and
            img.colorTable().at(0) == QColor(Qt.GlobalColor.black).rgba() and
            img.colorTable().at(1) == QColor(Qt.GlobalColor.white).rgba()):
            if fmt == QImage.Format.Format_MonoLSB:
                image = image.convertToFormat(QImage.Format.Format_Mono)
            fmt = QImage.Format.Format_Mono
        else:
            if (fmt != QImage.Format.Format_RGB32 and fmt != QImage.Format.Format_ARGB32):
                image = image.convertToFormat(QImage.Format.Format_ARGB32)
                fmt = QImage.Format.Format_ARGB32

        w = image.width()
        h = image.height()
        d = image.depth()

        if fmt == QImage.Format.Format_Mono:
            bytes_per_line = (w + 7) >> 3
            data = image.constBits().asstring(bytes_per_line * h)
            return self.write_image(data, w, h, d, cache_key=cache_key)

        has_alpha = False
        soft_mask = None

        if fmt == QImage.Format.Format_ARGB32:
            tmask = image.constBits().asstring(4*w*h)[self.alpha_bit::4]
            sdata = bytearray(tmask)
            vals = set(sdata)
            vals.discard(255)  # discard opaque pixels
            has_alpha = bool(vals)
            if has_alpha:
                # Blend image onto a white background as otherwise Qt will render
                # transparent pixels as black
                background = QImage(image.size(), QImage.Format.Format_ARGB32_Premultiplied)
                background.fill(Qt.GlobalColor.white)
                painter = QPainter(background)
                painter.drawImage(0, 0, image)
                painter.end()
                image = background

        ba = QByteArray()
        buf = QBuffer(ba)
        image.save(buf, 'jpeg', 94)
        data = ba.data()

        if has_alpha:
            soft_mask = self.write_image(tmask, w, h, 8)

        return self.write_image(data, w, h, 32, dct=True,
                                soft_mask=soft_mask, cache_key=cache_key)
Exemplo n.º 10
0
def blend_on_canvas(img, width, height, bgcolor='#ffffff'):
    ' Blend the `img` onto a canvas with the specified background color and size '
    w, h = img.width(), img.height()
    scaled, nw, nh = fit_image(w, h, width, height)
    if scaled:
        img = img.scaled(nw, nh, Qt.AspectRatioMode.IgnoreAspectRatio, Qt.TransformationMode.SmoothTransformation)
        w, h = nw, nh
    canvas = QImage(width, height, QImage.Format.Format_RGB32)
    canvas.fill(QColor(bgcolor))
    overlay_image(img, canvas, (width - w)//2, (height - h)//2)
    return canvas
Exemplo n.º 11
0
def message_image(text, width=500, height=400, font_size=20):
    init_environment()
    img = QImage(width, height, QImage.Format.Format_ARGB32)
    img.fill(Qt.GlobalColor.white)
    p = QPainter(img)
    f = QFont()
    f.setPixelSize(font_size)
    p.setFont(f)
    r = img.rect().adjusted(10, 10, -10, -10)
    p.drawText(r, Qt.AlignmentFlag.AlignJustify | Qt.AlignmentFlag.AlignVCenter | Qt.TextFlag.TextWordWrap, text)
    p.end()
    return pixmap_to_data(img)
Exemplo n.º 12
0
    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(int(width), int(height),
                       Qt.AspectRatioMode.KeepAspectRatio)
        logger.info('Rasterizing %r to %dx%d' %
                    (elem, size.width(), size.height()))
        image = QImage(size, QImage.Format.Format_ARGB32_Premultiplied)
        image.fill(QColor("white").rgb())
        painter = QPainter(image)
        svg.render(painter)
        painter.end()
        array = QByteArray()
        buffer = QBuffer(array)
        buffer.open(QIODevice.OpenModeFlag.WriteOnly)
        image.save(buffer, format)
        return array.data()
Exemplo n.º 13
0
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.Format_RGB32)
        pd.fill(Qt.GlobalColor.white)
        p = QPainter(pd)
        rend.render(p)
        p.end()
        img = QPixmap.fromImage(pd)
        img.setDevicePixelRatio(dpr)
    return img
Exemplo n.º 14
0
class Canvas:

    def __init__(self, width, height, bgcolor='#ffffff'):
        self.img = QImage(width, height, QImage.Format.Format_RGB32)
        self.img.fill(QColor(bgcolor))

    def __enter__(self):
        return self

    def __exit__(self, *args):
        pass

    def compose(self, img, x=0, y=0):
        img = image_from_data(img)
        overlay_image(img, self.img, x, y)

    def export(self, fmt='JPEG', compression_quality=95):
        return image_to_data(self.img, compression_quality=compression_quality, fmt=fmt)
Exemplo n.º 15
0
 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(svgitem.bytes_representation)
     svg = QSvgRenderer(data)
     size = svg.defaultSize()
     size.scale(width, height, Qt.AspectRatioMode.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.Format_ARGB32_Premultiplied)
         image.fill(QColor("white").rgb())
         painter = QPainter(image)
         svg.render(painter)
         painter.end()
         array = QByteArray()
         buffer = QBuffer(array)
         buffer.open(QIODevice.OpenModeFlag.WriteOnly)
         image.save(buffer, 'PNG')
         data = array.data()
         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)
Exemplo n.º 16
0
 def failed_img(self):
     if self._failed_img is None:
         try:
             dpr = self.devicePixelRatioF()
         except AttributeError:
             dpr = self.devicePixelRatio()
         i = QImage(200, 150, QImage.Format.Format_ARGB32)
         i.setDevicePixelRatio(dpr)
         i.fill(Qt.GlobalColor.white)
         p = QPainter(i)
         r = i.rect().adjusted(10, 10, -10, -10)
         n = QPen(Qt.PenStyle.DashLine)
         n.setColor(Qt.GlobalColor.black)
         p.setPen(n)
         p.drawRect(r)
         p.setPen(Qt.GlobalColor.black)
         f = self.font()
         f.setPixelSize(20)
         p.setFont(f)
         p.drawText(r.adjusted(10, 0, -10, 0), Qt.AlignmentFlag.AlignCenter | Qt.TextFlag.TextWordWrap, _('Image could not be rendered'))
         p.end()
         self._failed_img = QPixmap.fromImage(i)
     return self._failed_img
Exemplo n.º 17
0
def decoration_for_style(palette, style, icon_size, device_pixel_ratio, is_dark):
    style_key = (is_dark, icon_size, device_pixel_ratio, tuple((k, style[k]) for k in sorted(style)))
    sentinel = object()
    ans = decoration_cache.get(style_key, sentinel)
    if ans is not sentinel:
        return ans
    ans = None
    kind = style.get('kind')
    if kind == 'color':
        key = 'dark' if is_dark else 'light'
        val = style.get(key)
        if val is None:
            which = style.get('which')
            val = (builtin_colors_dark if is_dark else builtin_colors_light).get(which)
        if val is None:
            val = style.get('background-color')
        if val is not None:
            ans = QColor(val)
    elif kind == 'decoration':
        which = style.get('which')
        if which is not None:
            q = builtin_decorations.get(which)
            if q is not None:
                style = q
        sz = int(math.ceil(icon_size * device_pixel_ratio))
        canvas = QImage(sz, sz, QImage.Format.Format_ARGB32)
        canvas.fill(Qt.GlobalColor.transparent)
        canvas.setDevicePixelRatio(device_pixel_ratio)
        p = QPainter(canvas)
        p.setRenderHint(QPainter.RenderHint.Antialiasing, True)
        p.setPen(palette.color(QPalette.ColorRole.WindowText))
        irect = QRect(0, 0, icon_size, icon_size)
        adjust = -2
        text_rect = p.drawText(irect.adjusted(0, adjust, 0, adjust), Qt.AlignmentFlag.AlignHCenter| Qt.AlignmentFlag.AlignTop, 'a')
        p.drawRect(irect)
        fm = p.fontMetrics()
        pen = p.pen()
        if 'text-decoration-color' in style:
            pen.setColor(QColor(style['text-decoration-color']))
        lstyle = style.get('text-decoration-style') or 'solid'
        q = {'dotted': Qt.PenStyle.DotLine, 'dashed': Qt.PenStyle.DashLine, }.get(lstyle)
        if q is not None:
            pen.setStyle(q)
        lw = fm.lineWidth()
        if lstyle == 'double':
            lw * 2
        pen.setWidth(fm.lineWidth())
        q = style.get('text-decoration-line') or 'underline'
        pos = text_rect.bottom()
        height = irect.bottom() - pos
        if q == 'overline':
            pos = height
        elif q == 'line-through':
            pos = text_rect.center().y() - adjust - lw // 2
        p.setPen(pen)
        if lstyle == 'wavy':
            p.drawPath(wavy_path(icon_size, height, pos))
        else:
            p.drawLine(0, pos, irect.right(), pos)
        p.end()
        ans = QPixmap.fromImage(canvas)
    elif 'background-color' in style:
        ans = QColor(style['background-color'])
    decoration_cache[style_key] = ans
    return ans
Exemplo n.º 18
0
def blend_image(img, bgcolor='#ffffff'):
    ' Used to convert images that have semi-transparent pixels to opaque by blending with the specified color '
    canvas = QImage(img.size(), QImage.Format.Format_RGB32)
    canvas.fill(QColor(bgcolor))
    overlay_image(img, canvas)
    return canvas
Exemplo n.º 19
0
def create_canvas(width, height, bgcolor='#ffffff'):
    'Create a blank canvas of the specified size and color '
    img = QImage(width, height, QImage.Format.Format_RGB32)
    img.fill(QColor(bgcolor))
    return img