Beispiel #1
0
def drag_icon(self, cover, multiple):
    cover = cover.scaledToHeight(120, Qt.SmoothTransformation)
    if multiple:
        base_width = cover.width()
        base_height = cover.height()
        base = QImage(base_width+21, base_height+21,
                QImage.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(p.CompositionMode_SourceAtop)
        p.drawImage(rect.topLeft(), cover)
        p.restore()
        p.drawRect(rect)
        p.end()
        cover = base
    return QPixmap.fromImage(cover)
Beispiel #2
0
def scale_image(data, width=60, height=80, compression_quality=70, as_png=False, preserve_aspect_ratio=True):
    ''' Scale an image, returning it as either JPEG or PNG data (bytestring).
    Transparency is alpha blended with white when converting to JPEG. Is thread
    safe and does not require a QApplication. '''
    # We use Qt instead of ImageMagick here because ImageMagick seems to use
    # some kind of memory pool, causing memory consumption to sky rocket.
    if isinstance(data, QImage):
        img = data
    else:
        img = QImage()
        if not img.loadFromData(data):
            raise ValueError('Could not load image for thumbnail generation')
    if preserve_aspect_ratio:
        scaled, nwidth, nheight = fit_image(img.width(), img.height(), width, height)
        if scaled:
            img = img.scaled(nwidth, nheight, Qt.KeepAspectRatio, Qt.SmoothTransformation)
    else:
        if img.width() != width or img.height() != height:
            img = img.scaled(width, height, Qt.IgnoreAspectRatio, Qt.SmoothTransformation)
    if not as_png and img.hasAlphaChannel():
        nimg = QImage(img.size(), QImage.Format_RGB32)
        nimg.fill(Qt.white)
        p = QPainter(nimg)
        p.drawImage(0, 0, img)
        p.end()
        img = nimg
    ba = QByteArray()
    buf = QBuffer(ba)
    buf.open(QBuffer.WriteOnly)
    fmt = 'PNG' if as_png else 'JPEG'
    if not img.save(buf, fmt, quality=compression_quality):
        raise ValueError('Failed to export thumbnail image to: ' + fmt)
    return img.width(), img.height(), ba.data()
Beispiel #3
0
def drag_icon(self, cover, multiple):
    cover = cover.scaledToHeight(120, Qt.SmoothTransformation)
    if multiple:
        base_width = cover.width()
        base_height = cover.height()
        base = QImage(base_width+21, base_height+21,
                QImage.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(p.CompositionMode_SourceAtop)
        p.drawImage(rect.topLeft(), cover)
        p.restore()
        p.drawRect(rect)
        p.end()
        cover = base
    return QPixmap.fromImage(cover)
Beispiel #4
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.black).rgba() and
            img.colorTable().at(1) == QColor(Qt.white).rgba()):
            if fmt == QImage.Format_MonoLSB:
                image = image.convertToFormat(QImage.Format_Mono)
            fmt = QImage.Format_Mono
        else:
            if (fmt != QImage.Format_RGB32 and fmt != QImage.Format_ARGB32):
                image = image.convertToFormat(QImage.Format_ARGB32)
                fmt = QImage.Format_ARGB32

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

        if fmt == QImage.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_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_ARGB32_Premultiplied)
                background.fill(Qt.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)
Beispiel #5
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.black).rgba() and
            img.colorTable().at(1) == QColor(Qt.white).rgba()):
            if fmt == QImage.Format_MonoLSB:
                image = image.convertToFormat(QImage.Format_Mono)
            fmt = QImage.Format_Mono
        else:
            if (fmt != QImage.Format_RGB32 and fmt != QImage.Format_ARGB32):
                image = image.convertToFormat(QImage.Format_ARGB32)
                fmt = QImage.Format_ARGB32

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

        if fmt == QImage.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_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_ARGB32_Premultiplied)
                background.fill(Qt.white)
                painter = QPainter(background)
                painter.drawImage(0, 0, image)
                painter.end()
                image = background

        ba = QByteArray()
        buf = QBuffer(ba)
        image.save(buf, 'jpeg', 94)
        data = bytes(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)
Beispiel #6
0
 def __call__(self, canvas):
     if canvas.has_selection and canvas.selection_state.rect is not None:
         pimg = self.after_image
         img = self.after_image = QImage(canvas.current_image)
         rect = QRectF(*get_selection_rect(img, canvas.selection_state.rect, canvas.target))
         p = QPainter(img)
         p.setRenderHint(p.SmoothPixmapTransform, True)
         p.drawImage(rect, pimg, QRectF(pimg.rect()))
         p.end()
     return self.after_image
Beispiel #7
0
 def __call__(self, canvas):
     if canvas.has_selection and canvas.selection_state.rect is not None:
         pimg = self.after_image
         img = self.after_image = QImage(canvas.current_image)
         rect = QRectF(*get_selection_rect(img, canvas.selection_state.rect, canvas.target))
         p = QPainter(img)
         p.setRenderHint(p.SmoothPixmapTransform, True)
         p.drawImage(rect, pimg, QRectF(pimg.rect()))
         p.end()
     return self.after_image
Beispiel #8
0
 def makeQPixmap(self, width, height):
     data = numpy.zeros((width, height), float)
     data[...] = (numpy.arange(width) / (width - 1.))[:, numpy.newaxis]
     # make brush image -- diag background, with colormap on top
     img = QPixmap(width, height)
     painter = QPainter(img)
     painter.fillRect(0, 0, width, height, QBrush(QColor("white")))
     painter.fillRect(0, 0, width, height, QBrush(Qt.BDiagPattern))
     painter.drawImage(0, 0, self.colorize(data))
     painter.end()
     return img
Beispiel #9
0
    def paint(self,
              paint: QPainter,
              style: QStyleOptionGraphicsItem,
              widget=None):
        qpen = QPen()
        qpen.setColor(Qt.white)
        # paint.setBackground()
        paint.setPen(qpen)
        aspect = self.head_img.width() / self.head_img.height()
        ratio = self.height * 0.2
        target = QRectF(0, 0, aspect * ratio, ratio)
        source = QRectF(0, 0, self.head_img.width(), self.head_img.height())

        paint.drawImage(target, self.head_img, source)
Beispiel #10
0
def image_to_data(img, compression_quality=95, fmt='JPEG'):
    ba = QByteArray()
    buf = QBuffer(ba)
    buf.open(QBuffer.WriteOnly)
    fmt = fmt.upper()
    if img.hasAlphaChannel() and fmt in 'JPEG JPG'.split():
        nimg = QImage(img.size(), QImage.Format_RGB32)
        nimg.fill(Qt.white)
        p = QPainter(nimg)
        p.drawImage(0, 0, img)
        p.end()
        img = nimg
    if not img.save(buf, fmt, quality=compression_quality):
        raise ValueError('Failed to export image as ' + fmt)
    return ba.data()
Beispiel #11
0
def overlay_image(img, canvas=None, left=0, top=0):
    if canvas is None:
        canvas = QImage(img.size(), QImage.Format_RGB32)
        canvas.fill(Qt.white)
    if imageops is None:
        # This is for people running from source who have not updated the
        # binary and so do not have the imageops module
        from PyQt5.Qt import QPainter
        from calibre.gui2 import ensure_app
        ensure_app()
        p = QPainter(canvas)
        p.drawImage(left, top, img)
        p.end()
    else:
        imageops.overlay(img, canvas, left, top)
    return canvas
Beispiel #12
0
def scale_image(data,
                width=60,
                height=80,
                compression_quality=70,
                as_png=False,
                preserve_aspect_ratio=True):
    ''' Scale an image, returning it as either JPEG or PNG data (bytestring).
    Transparency is alpha blended with white when converting to JPEG. Is thread
    safe and does not require a QApplication. '''
    # We use Qt instead of ImageMagick here because ImageMagick seems to use
    # some kind of memory pool, causing memory consumption to sky rocket.
    if isinstance(data, QImage):
        img = data
    else:
        img = QImage()
        if not img.loadFromData(data):
            raise ValueError('Could not load image for thumbnail generation')
    if preserve_aspect_ratio:
        scaled, nwidth, nheight = fit_image(img.width(), img.height(), width,
                                            height)
        if scaled:
            img = img.scaled(nwidth, nheight, Qt.KeepAspectRatio,
                             Qt.SmoothTransformation)
    else:
        if img.width() != width or img.height() != height:
            img = img.scaled(width, height, Qt.IgnoreAspectRatio,
                             Qt.SmoothTransformation)
    if not as_png and img.hasAlphaChannel():
        nimg = QImage(img.size(), QImage.Format_RGB32)
        nimg.fill(Qt.white)
        p = QPainter(nimg)
        p.drawImage(0, 0, img)
        p.end()
        img = nimg
    ba = QByteArray()
    buf = QBuffer(ba)
    buf.open(QBuffer.WriteOnly)
    fmt = 'PNG' if as_png else 'JPEG'
    if not img.save(buf, fmt, quality=compression_quality):
        raise ValueError('Failed to export thumbnail image to: ' + fmt)
    return img.width(), img.height(), ba.data()
Beispiel #13
0
    def paintEvent(self, event):
        '''
        @param: event QPaintEvent
        '''
        if not (self._options & self._MultiIconOption):
            super().paintEvent(event)
            return

        p = QPainter(self)

        w = self._multiIcon.width()
        h4 = self._multiIcon.height() / 4

        if not self.isEnabled():
            p.drawImage(0, 0, self._multiIcon, 0, h4 * 3, w, h4)
        elif self.isDown():
            p.drawImage(0, 0, self._multiIcon, 0, h4 * 2, w, h4)
        elif self.underMouse():
            p.drawImage(0, 0, self._multiIcon, 0, h4 * 1, w, h4)
        else:
            p.drawImage(0, 0, self._multiIcon, 0, h4 * 0, w, h4)
    def run(self):

        time.sleep(0.5)
        # create hash dict of current list
        self._hash_item_dict = {}
        for item in self._item_list:
            self._hash_item_dict[item.hash] = item

        # compare and swap between lists if new item is not generated
        for new_hash in self._hash_item_dict.keys():
            if new_hash in self._old_hash_item_dict.keys():
                # swap to avoid generating uselessly :
                self._hash_item_dict[
                    new_hash] = self._old_hash_item_dict[new_hash]
            else:  # generate
                _ = self._hash_item_dict[new_hash].image

        # append generated images
        # images_list.append()
        pix_list = []
        for new_item in self._item_list:
            usable_item = self._hash_item_dict[new_item.hash]
            pix_list.append(usable_item.image)

        # draw pixmaps in one :
        image = QImage(20, 20, QImage.Format_ARGB32_Premultiplied)
        image.fill(Qt.white)
        point = QPoint(0, 0)
        width_list = [pix.width() for pix in pix_list]
        max_width = max(width_list)
        self._max_width_found = max([max_width, self._max_width_found])
        for pix in pix_list:

            last_image = image
            image = QImage(self._max_width_found, image.height(
            ) + pix.height(), QImage.Format_ARGB32_Premultiplied)
            pix_paint = QPainter(image)
            image.fill(Qt.white)
            pix_paint.drawImage(0, 0, last_image)
            pix_paint.drawImage(point, pix)
            point = QPoint(0, point.y() + pix.height())
            pix_paint.end()
        '''
        pixmap = QImage(21,21, QImage.Format_ARGB32_Premultiplied) # temp
        pixPaint = QPainter(pixmap)
        myPen = QPen( Qt.black)
        pixPaint.setPen(myPen)
        pixPaint.drawRect(0,0, 20,20);
        pixPaint.end()
        image = pixmap

            painter.drawImage(point, pix)
            point = QPoint(0, point.y() + pix.height())
        painter.end()
          '''

        final_pixmap = QPixmap.fromImage(image, Qt.AutoColor)
        self.image_generated.emit(final_pixmap)

        self._old_item_list = self._item_list
        self._old_hash_item_dict = self._hash_item_dict
Beispiel #15
0
class PaintBoard(QWidget):


    def __init__(self):
        QWidget.__init__(self)

        # self.label = QLabel(self)
        # self.gridLayout = QGridLayout(self)
        # self.gridLayout.addWidget(self.label)

        self.pixmap = QPixmap(1,1)
        self.pixmap.fill(Qt.white)
        self.img = QImage(self.pixmap.toImage())

        # self.label.setFrameShape(1)
        # # self.label.setPixmap(self.pixmap)
        # self.label.setScaledContents(True)
        # self.label.setVisible(False)

        self.pen = QPainter()

    def paintEvent(self, paintEvent):
        self.pixmap = self.pixmap.scaled(self.width(), self.height())
        self.pen.begin(self)
        # self.pen.drawPixmap(0, 0, self.pixmap)
        self.img = QImage(self.pixmap.toImage())
        self.pen.drawImage(0, 0, self.img)
        self.pen.end()

    def drawPoints(self, x, y):
        # print(self.width(),self.height())
        m = int(self.width()/2) + x
        n = int(self.height()/2) - y
        self.pen.begin(self.pixmap)
        self.pen.setPen(QPen(Qt.black,1))
        self.pen.drawPoint(m, n)
        self.pen.end()
        self.update()
        # self.repaint()

    def load_img(self, img):
        self.pixmap.load(img)
        self.update()

    #DDA
    def drawLine(self, x0, y0, x1, y1):
        self.Clear()
        dx = x1 - x0
        dy = y1 - y0
        if fabs(dx) > fabs(dy):
            steps = fabs(dx)
        else:
            steps = fabs(dy)
        self.drawPoints(int(x0+0.5), int(y0+0.5))
        xInc = dx/steps
        yInc = dy/steps
        for i in range(int(steps+0.5)):
            x0 += xInc
            y0 += yInc
            self.drawPoints(int(x0+0.5), int(y0+0.5))

    #中点法画圆
    def CirclePlot(self, xc, yc, x, y):
        self.drawPoints(x+xc, y+yc)
        self.drawPoints(-x+xc, y+yc)
        self.drawPoints(x+xc, -y+yc)
        self.drawPoints(-x+xc, -y+yc)
        self.drawPoints(y+xc, x+yc)
        self.drawPoints(y+xc, -x+yc)
        self.drawPoints(-y+xc, x+yc)
        self.drawPoints(-y+xc, -x+yc)
    def drawRound(self, xc, yc, r):
        self.Clear()
        x = 0
        y = r
        d = 3-2*r
        self.CirclePlot(xc, yc, x, y)
        while x<y:
            if d<0:
                d = d+4*x+6
            else:
                d = d+4*(x-y)+10
                y -= 1
            x +=1
            self.CirclePlot(xc, yc, x, y)
            
    '''
    # 边界填充
    def fill(self, x, y):
        w = int(self.width()/2)
        h = int(self.height()/2)
        block = deque([(x, y)])
        while 1:
            if len(block) == 0:
                break
            else:
                # print(block)
                point = block.popleft()
                m = point[0]
                n = point[1]
                # c = self.img.pixel(w+m, h+n)
                # colors = QColor(c).getRgb()
                # if colors != (0, 0, 0, 255):
                self.drawPoints(m, n)
                # result.append((m,n))
    
                c = self.img.pixel(w+m, h+n-1)
                colors = QColor(c).getRgb()
                if colors != (0, 0, 0, 255):
                    if (m,n-1) not in block:
                        block.append((m,n-1))
    
                c = self.img.pixel(w+m, h+n+1)
                colors = QColor(c).getRgb()
                if colors != (0, 0, 0, 255):
                    if (m,n+1) not in block:
                        block.append((m,n+1))
    
                c = self.img.pixel(w+m-1, h+n)
                colors = QColor(c).getRgb()
                if colors != (0, 0, 0, 255):
                    if (m-1,n) not in block:
                        block.append((m-1,n))
    
                c = self.img.pixel(w+m+1, h+n)
                colors = QColor(c).getRgb()
                if colors != (0, 0, 0, 255):
                    if (m+1,n) not in block:
                        block.append((m+1,n))
        print(results)
    '''

    #边界填充
    #种子边界填充
    def fill(self, x, y):
        w = int(self.width()/2)
        h = int(self.height()/2)
        block = deque([(x, y)])
        results = []
        while 1:
            if len(block) == 0:
                break
            else:
                point = block.popleft()
                m = point[0]
                n = point[1]
                results.append((m,n))

                c = self.img.pixel(w+m, h+n-1)
                colors = QColor(c).getRgb()
                if colors != (0, 0, 0, 255):
                    if (m,n-1) not in block:
                        if (m,n-1) not in results:
                            block.append((m,n-1))

                c = self.img.pixel(w+m, h+n+1)
                colors = QColor(c).getRgb()
                if colors != (0, 0, 0, 255):
                    if (m,n+1) not in block:
                        if (m,n+1) not in results:
                            block.append((m,n+1))

                c = self.img.pixel(w+m-1, h+n)
                colors = QColor(c).getRgb()
                if colors != (0, 0, 0, 255):
                    if (m-1,n) not in block:
                        if (m-1,n) not in results:
                            block.append((m-1,n))

                c = self.img.pixel(w+m+1, h+n)
                colors = QColor(c).getRgb()
                if colors != (0, 0, 0, 255):
                    if (m+1,n) not in block:
                        if (m+1,n) not in results:
                            block.append((m+1,n))
        for point in results:
            self.drawPoints(point[0], point[1])

    def Clear(self):
        self.pixmap.fill(Qt.white)
        self.update()
    def _populate_covers(self):
        '''
        Display calibre cover for both unless mismatch
        '''
        def _fetch_marvin_cover(border_width=0):
            '''
            Retrieve LargeCoverJpg from cache
            '''
            #self._log_location('border_width: {0}'.format(border_width))
            con = sqlite3.connect(self.marvin_db_path)
            with con:
                con.row_factory = sqlite3.Row

                # Fetch Hash from mainDb
                cover_cur = con.cursor()
                cover_cur.execute('''SELECT
                                      Hash
                                     FROM Books
                                     WHERE ID = '{0}'
                                  '''.format(self.book_id))
                row = cover_cur.fetchone()

            book_hash = row[b'Hash']
            large_covers_subpath = self.connected_device._cover_subpath(size="large")
            cover_path = '/'.join([large_covers_subpath, '%s.jpg' % book_hash])
            stats = self.parent.ios.exists(cover_path)
            if stats:
                self._log("fetching large cover from cache")
                #self._log("cover size: {:,} bytes".format(int(stats['st_size'])))
                cover_bytes = self.parent.ios.read(cover_path, mode='rb')
                m_image = QImage()
                m_image.loadFromData(cover_bytes)

                if border_width:
                    # Construct a QPixmap with oversized yellow background
                    m_image = m_image.scaledToHeight(
                        self.COVER_ICON_SIZE - border_width * 2,
                        Qt.SmoothTransformation)

                    self.m_pixmap = QPixmap(
                        QSize(m_image.width() + border_width * 2,
                              m_image.height() + border_width * 2))

                    m_painter = QPainter(self.m_pixmap)
                    m_painter.setRenderHints(m_painter.Antialiasing)

                    m_painter.fillRect(self.m_pixmap.rect(), self.MISMATCH_COLOR)
                    m_painter.drawImage(border_width,
                                        border_width,
                                        m_image)
                else:
                    m_image = m_image.scaledToHeight(
                        self.COVER_ICON_SIZE,
                        Qt.SmoothTransformation)

                    self.m_pixmap = QPixmap(
                        QSize(m_image.width(),
                              m_image.height()))

                    m_painter = QPainter(self.m_pixmap)
                    m_painter.setRenderHints(m_painter.Antialiasing)

                    m_painter.drawImage(0, 0, m_image)

                self.marvin_cover.setPixmap(self.m_pixmap)
            else:
                # No cover available, use generic
                self._log("No cached cover, using generic")
                pixmap = QPixmap()
                pixmap.load(I('book.png'))
                pixmap = pixmap.scaled(self.COVER_ICON_SIZE,
                                       self.COVER_ICON_SIZE,
                                       aspectRatioMode=Qt.KeepAspectRatio,
                                       transformMode=Qt.SmoothTransformation)
                self.marvin_cover.setPixmap(pixmap)

        self.calibre_cover.setMaximumSize(QSize(self.COVER_ICON_SIZE, self.COVER_ICON_SIZE))
        self.calibre_cover.setText('')
        self.calibre_cover.setScaledContents(False)

        self.marvin_cover.setMaximumSize(QSize(self.COVER_ICON_SIZE, self.COVER_ICON_SIZE))
        self.marvin_cover.setText('')
        self.marvin_cover.setScaledContents(False)

        if self.cid:
            db = self.opts.gui.current_db
            if 'cover_hash' not in self.mismatches:
                mi = db.get_metadata(self.cid, index_is_id=True, get_cover=True, cover_as_data=True)

                c_image = QImage()
                if mi.has_cover:
                    c_image.loadFromData(mi.cover_data[1])
                    c_image = c_image.scaledToHeight(self.COVER_ICON_SIZE,
                                                     Qt.SmoothTransformation)
                    self.c_pixmap = QPixmap(QSize(c_image.width(),
                                                  c_image.height()))
                    c_painter = QPainter(self.c_pixmap)
                    c_painter.setRenderHints(c_painter.Antialiasing)
                    c_painter.drawImage(0, 0, c_image)
                else:
                    c_image.load(I('book.png'))
                    c_image = c_image.scaledToWidth(135,
                                                    Qt.SmoothTransformation)
                    # Construct a QPixmap with dialog background
                    self.c_pixmap = QPixmap(
                        QSize(c_image.width(),
                              c_image.height()))
                    c_painter = QPainter(self.c_pixmap)
                    c_painter.setRenderHints(c_painter.Antialiasing)
                    bgcolor = self.palette().color(QPalette.Background)
                    c_painter.fillRect(self.c_pixmap.rect(), bgcolor)
                    c_painter.drawImage(0, 0, c_image)

                # Set calibre cover
                self.calibre_cover.setPixmap(self.c_pixmap)

                if self.opts.prefs.get('development_mode', False):
                    # Show individual covers
                    _fetch_marvin_cover()
                else:
                    # Show calibre cover on both sides
                    self.marvin_cover.setPixmap(self.c_pixmap)

            else:
                # Covers don't match - render with border
                # Construct a QImage with the cover sized to fit inside border
                c_image = QImage()
                cdata = db.cover(self.cid, index_is_id=True)
                if cdata is None:
                    c_image.load(I('book.png'))
                    self.calibre_cover.setScaledContents(True)
                else:
                    c_image.loadFromData(cdata)

                c_image = c_image.scaledToHeight(
                    self.COVER_ICON_SIZE - self.BORDER_WIDTH * 2,
                    Qt.SmoothTransformation)

                # Construct a QPixmap with yellow background
                self.c_pixmap = QPixmap(
                    QSize(c_image.width() + self.BORDER_WIDTH * 2,
                          c_image.height() + self.BORDER_WIDTH * 2))
                c_painter = QPainter(self.c_pixmap)
                c_painter.setRenderHints(c_painter.Antialiasing)
                c_painter.fillRect(self.c_pixmap.rect(),self.MISMATCH_COLOR)
                c_painter.drawImage(self.BORDER_WIDTH, self.BORDER_WIDTH, c_image)
                self.calibre_cover.setPixmap(self.c_pixmap)

                # Render Marvin cover with small border if different covers,
                # large cover if no cover hash (loaded via OPDS)
                border_width = self.BORDER_WIDTH
                if self.mismatches['cover_hash']['Marvin'] is None:
                    border_width = self.BORDER_WIDTH * 3
                _fetch_marvin_cover(border_width=border_width)
        else:
            _fetch_marvin_cover()
Beispiel #17
0
    def drawIconWithShadow(self,
                           icon,
                           rect,
                           painter,
                           iconMode,
                           radius=3,
                           color=QColor(0, 0, 0, 130),
                           offset=QPoint(1, -2)):
        '''
        @brief: Draw a cached pixmap with shadow
        @param: icon QIcon
        @param: rect QRect
        @param: painter QPainter
        @param: iconMode QIcon.Mode
        @param: radius int
        @param: color QColor
        @param: offset QPoint
        '''
        cache = QPixmap()
        pixmapName = 'icon %s %s %s' % (icon.cacheKey(), iconMode,
                                        rect.height())

        cache = QPixmapCache.find(pixmapName)
        if not cache:
            px = icon.pixmap(rect.size(), iconMode)
            px.setDevicePixelRatio(gVar.app.devicePixelRatio())
            cache = QPixmap(px.size() + QSize(radius * 2, radius * 2))
            cache.setDevicePixelRatio(px.devicePixelRatioF())
            cache.fill(Qt.transparent)

            cachePainter = QPainter(cache)

            # Draw shadow
            tmp = QImage(px.size() + QSize(radius * 2, radius * 2 + 1),
                         QImage.Format_ARGB32_Premultiplied)
            tmp.setDevicePixelRatio(px.devicePixelRatioF())
            tmp.fill(Qt.transparent)

            tmpPainter = QPainter(tmp)

            tmpPainter.setCompositionMode(QPainter.CompositionMode_Source)
            tmpPainter.drawPixmap(QPoint(radius, radius), px)
            tmpPainter.end()

            # blur the alpha channel
            blurred = QImage(tmp.size(), QImage.Format_ARGB32_Premultiplied)
            blurred.fill(Qt.transparent)
            blurPainter = QPainter(blurred)
            # TODO:
            #qt_blurImage(blurPainter, tmp, radius, False, True)
            blurPainter.end()

            tmp = blurred

            # blacken the image...
            tmpPainter.begin(tmp)
            tmpPainter.setCompositionMode(QPainter.CompositionMode_SourceIn)
            tmpPainter.fillRect(tmp.rect(), color)
            tmpPainter.end()

            tmpPainter.begin(tmp)
            tmpPainter.setCompositionMode(QPainter.CompositionMode_SourceIn)
            tmpPainter.fillRect(tmp.rect(), color)
            tmpPainter.end()

            # draw the blurred drop shadow...
            cachePainter.drawImage(
                QRect(0, 0,
                      cache.rect().width() / cache.devicePixelRatioF(),
                      cache.rect().height() / cache.devicePixelRatioF()), tmp)
            # Draw the actual pixmap...
            cachePainter.drawPixmap(QPoint(radius, radius) + offset, px)
            if self.usePixmapCache():
                QPixmapCache.insert(pixmapName, cache)

            sip.delete(cachePainter)
            sip.delete(tmpPainter)
            sip.delete(blurPainter)

        targetRect = QRect(cache.rect())
        targetRect.setWidth(cache.rect().width() / cache.devicePixelRatioF())
        targetRect.setHeight(cache.rect().height() / cache.devicePixelRatioF())
        targetRect.moveCenter(rect.center())
        painter.drawPixmap(targetRect.topLeft() - offset, cache)
Beispiel #18
0
        def _fetch_marvin_cover(border_width=0):
            '''
            Retrieve LargeCoverJpg from cache
            '''
            #self._log_location('border_width: {0}'.format(border_width))
            con = sqlite3.connect(self.marvin_db_path)
            with con:
                con.row_factory = sqlite3.Row

                # Fetch Hash from mainDb
                cover_cur = con.cursor()
                cover_cur.execute('''SELECT
                                      Hash
                                     FROM Books
                                     WHERE ID = '{0}'
                                  '''.format(self.book_id))
                row = cover_cur.fetchone()

            book_hash = row[b'Hash']
            large_covers_subpath = self.connected_device._cover_subpath(
                size="large")
            cover_path = '/'.join([large_covers_subpath, '%s.jpg' % book_hash])
            stats = self.parent.ios.exists(cover_path)
            if stats:
                self._log("fetching large cover from cache")
                #self._log("cover size: {:,} bytes".format(int(stats['st_size'])))
                cover_bytes = self.parent.ios.read(cover_path, mode='rb')
                m_image = QImage()
                m_image.loadFromData(cover_bytes)

                if border_width:
                    # Construct a QPixmap with oversized yellow background
                    m_image = m_image.scaledToHeight(
                        self.COVER_ICON_SIZE - border_width * 2,
                        Qt.SmoothTransformation)

                    self.m_pixmap = QPixmap(
                        QSize(m_image.width() + border_width * 2,
                              m_image.height() + border_width * 2))

                    m_painter = QPainter(self.m_pixmap)
                    m_painter.setRenderHints(m_painter.Antialiasing)

                    m_painter.fillRect(self.m_pixmap.rect(),
                                       self.MISMATCH_COLOR)
                    m_painter.drawImage(border_width, border_width, m_image)
                else:
                    m_image = m_image.scaledToHeight(self.COVER_ICON_SIZE,
                                                     Qt.SmoothTransformation)

                    self.m_pixmap = QPixmap(
                        QSize(m_image.width(), m_image.height()))

                    m_painter = QPainter(self.m_pixmap)
                    m_painter.setRenderHints(m_painter.Antialiasing)

                    m_painter.drawImage(0, 0, m_image)

                self.marvin_cover.setPixmap(self.m_pixmap)
            else:
                # No cover available, use generic
                self._log("No cached cover, using generic")
                pixmap = QPixmap()
                pixmap.load(I('book.png'))
                pixmap = pixmap.scaled(self.COVER_ICON_SIZE,
                                       self.COVER_ICON_SIZE,
                                       aspectRatioMode=Qt.KeepAspectRatio,
                                       transformMode=Qt.SmoothTransformation)
                self.marvin_cover.setPixmap(pixmap)
Beispiel #19
0
    def _populate_covers(self):
        '''
        Display calibre cover for both unless mismatch
        '''
        def _fetch_marvin_cover(border_width=0):
            '''
            Retrieve LargeCoverJpg from cache
            '''
            #self._log_location('border_width: {0}'.format(border_width))
            con = sqlite3.connect(self.marvin_db_path)
            with con:
                con.row_factory = sqlite3.Row

                # Fetch Hash from mainDb
                cover_cur = con.cursor()
                cover_cur.execute('''SELECT
                                      Hash
                                     FROM Books
                                     WHERE ID = '{0}'
                                  '''.format(self.book_id))
                row = cover_cur.fetchone()

            book_hash = row[b'Hash']
            large_covers_subpath = self.connected_device._cover_subpath(
                size="large")
            cover_path = '/'.join([large_covers_subpath, '%s.jpg' % book_hash])
            stats = self.parent.ios.exists(cover_path)
            if stats:
                self._log("fetching large cover from cache")
                #self._log("cover size: {:,} bytes".format(int(stats['st_size'])))
                cover_bytes = self.parent.ios.read(cover_path, mode='rb')
                m_image = QImage()
                m_image.loadFromData(cover_bytes)

                if border_width:
                    # Construct a QPixmap with oversized yellow background
                    m_image = m_image.scaledToHeight(
                        self.COVER_ICON_SIZE - border_width * 2,
                        Qt.SmoothTransformation)

                    self.m_pixmap = QPixmap(
                        QSize(m_image.width() + border_width * 2,
                              m_image.height() + border_width * 2))

                    m_painter = QPainter(self.m_pixmap)
                    m_painter.setRenderHints(m_painter.Antialiasing)

                    m_painter.fillRect(self.m_pixmap.rect(),
                                       self.MISMATCH_COLOR)
                    m_painter.drawImage(border_width, border_width, m_image)
                else:
                    m_image = m_image.scaledToHeight(self.COVER_ICON_SIZE,
                                                     Qt.SmoothTransformation)

                    self.m_pixmap = QPixmap(
                        QSize(m_image.width(), m_image.height()))

                    m_painter = QPainter(self.m_pixmap)
                    m_painter.setRenderHints(m_painter.Antialiasing)

                    m_painter.drawImage(0, 0, m_image)

                self.marvin_cover.setPixmap(self.m_pixmap)
            else:
                # No cover available, use generic
                self._log("No cached cover, using generic")
                pixmap = QPixmap()
                pixmap.load(I('book.png'))
                pixmap = pixmap.scaled(self.COVER_ICON_SIZE,
                                       self.COVER_ICON_SIZE,
                                       aspectRatioMode=Qt.KeepAspectRatio,
                                       transformMode=Qt.SmoothTransformation)
                self.marvin_cover.setPixmap(pixmap)

        self.calibre_cover.setMaximumSize(
            QSize(self.COVER_ICON_SIZE, self.COVER_ICON_SIZE))
        self.calibre_cover.setText('')
        self.calibre_cover.setScaledContents(False)

        self.marvin_cover.setMaximumSize(
            QSize(self.COVER_ICON_SIZE, self.COVER_ICON_SIZE))
        self.marvin_cover.setText('')
        self.marvin_cover.setScaledContents(False)

        if self.cid:
            db = self.opts.gui.current_db
            if 'cover_hash' not in self.mismatches:
                mi = db.get_metadata(self.cid,
                                     index_is_id=True,
                                     get_cover=True,
                                     cover_as_data=True)

                c_image = QImage()
                if mi.has_cover:
                    c_image.loadFromData(mi.cover_data[1])
                    c_image = c_image.scaledToHeight(self.COVER_ICON_SIZE,
                                                     Qt.SmoothTransformation)
                    self.c_pixmap = QPixmap(
                        QSize(c_image.width(), c_image.height()))
                    c_painter = QPainter(self.c_pixmap)
                    c_painter.setRenderHints(c_painter.Antialiasing)
                    c_painter.drawImage(0, 0, c_image)
                else:
                    c_image.load(I('book.png'))
                    c_image = c_image.scaledToWidth(135,
                                                    Qt.SmoothTransformation)
                    # Construct a QPixmap with dialog background
                    self.c_pixmap = QPixmap(
                        QSize(c_image.width(), c_image.height()))
                    c_painter = QPainter(self.c_pixmap)
                    c_painter.setRenderHints(c_painter.Antialiasing)
                    bgcolor = self.palette().color(QPalette.Background)
                    c_painter.fillRect(self.c_pixmap.rect(), bgcolor)
                    c_painter.drawImage(0, 0, c_image)

                # Set calibre cover
                self.calibre_cover.setPixmap(self.c_pixmap)

                if self.opts.prefs.get('development_mode', False):
                    # Show individual covers
                    _fetch_marvin_cover()
                else:
                    # Show calibre cover on both sides
                    self.marvin_cover.setPixmap(self.c_pixmap)

            else:
                # Covers don't match - render with border
                # Construct a QImage with the cover sized to fit inside border
                c_image = QImage()
                cdata = db.cover(self.cid, index_is_id=True)
                if cdata is None:
                    c_image.load(I('book.png'))
                    self.calibre_cover.setScaledContents(True)
                else:
                    c_image.loadFromData(cdata)

                c_image = c_image.scaledToHeight(
                    self.COVER_ICON_SIZE - self.BORDER_WIDTH * 2,
                    Qt.SmoothTransformation)

                # Construct a QPixmap with yellow background
                self.c_pixmap = QPixmap(
                    QSize(c_image.width() + self.BORDER_WIDTH * 2,
                          c_image.height() + self.BORDER_WIDTH * 2))
                c_painter = QPainter(self.c_pixmap)
                c_painter.setRenderHints(c_painter.Antialiasing)
                c_painter.fillRect(self.c_pixmap.rect(), self.MISMATCH_COLOR)
                c_painter.drawImage(self.BORDER_WIDTH, self.BORDER_WIDTH,
                                    c_image)
                self.calibre_cover.setPixmap(self.c_pixmap)

                # Render Marvin cover with small border if different covers,
                # large cover if no cover hash (loaded via OPDS)
                border_width = self.BORDER_WIDTH
                if self.mismatches['cover_hash']['Marvin'] is None:
                    border_width = self.BORDER_WIDTH * 3
                _fetch_marvin_cover(border_width=border_width)
        else:
            _fetch_marvin_cover()
        def _fetch_marvin_cover(border_width=0):
            '''
            Retrieve LargeCoverJpg from cache
            '''
            #self._log_location('border_width: {0}'.format(border_width))
            con = sqlite3.connect(self.marvin_db_path)
            with con:
                con.row_factory = sqlite3.Row

                # Fetch Hash from mainDb
                cover_cur = con.cursor()
                cover_cur.execute('''SELECT
                                      Hash
                                     FROM Books
                                     WHERE ID = '{0}'
                                  '''.format(self.book_id))
                row = cover_cur.fetchone()

            book_hash = row[b'Hash']
            large_covers_subpath = self.connected_device._cover_subpath(size="large")
            cover_path = '/'.join([large_covers_subpath, '%s.jpg' % book_hash])
            stats = self.parent.ios.exists(cover_path)
            if stats:
                self._log("fetching large cover from cache")
                #self._log("cover size: {:,} bytes".format(int(stats['st_size'])))
                cover_bytes = self.parent.ios.read(cover_path, mode='rb')
                m_image = QImage()
                m_image.loadFromData(cover_bytes)

                if border_width:
                    # Construct a QPixmap with oversized yellow background
                    m_image = m_image.scaledToHeight(
                        self.COVER_ICON_SIZE - border_width * 2,
                        Qt.SmoothTransformation)

                    self.m_pixmap = QPixmap(
                        QSize(m_image.width() + border_width * 2,
                              m_image.height() + border_width * 2))

                    m_painter = QPainter(self.m_pixmap)
                    m_painter.setRenderHints(m_painter.Antialiasing)

                    m_painter.fillRect(self.m_pixmap.rect(), self.MISMATCH_COLOR)
                    m_painter.drawImage(border_width,
                                        border_width,
                                        m_image)
                else:
                    m_image = m_image.scaledToHeight(
                        self.COVER_ICON_SIZE,
                        Qt.SmoothTransformation)

                    self.m_pixmap = QPixmap(
                        QSize(m_image.width(),
                              m_image.height()))

                    m_painter = QPainter(self.m_pixmap)
                    m_painter.setRenderHints(m_painter.Antialiasing)

                    m_painter.drawImage(0, 0, m_image)

                self.marvin_cover.setPixmap(self.m_pixmap)
            else:
                # No cover available, use generic
                self._log("No cached cover, using generic")
                pixmap = QPixmap()
                pixmap.load(I('book.png'))
                pixmap = pixmap.scaled(self.COVER_ICON_SIZE,
                                       self.COVER_ICON_SIZE,
                                       aspectRatioMode=Qt.KeepAspectRatio,
                                       transformMode=Qt.SmoothTransformation)
                self.marvin_cover.setPixmap(pixmap)
Beispiel #21
0
    def _generate_image(self):
        h = 2
        w = 1

        def draw_char(pos, pen_color):
            pix_paint.setPen(QPen(pen_color))

            rect = QRect(i * w + i, 1, w, h)
            pix_paint.drawRect(rect)
            pix_paint.fillRect(rect, pen_color)

        # range of tab:
        tab_default = 80

        text = "m"
        px = QPixmap(100, 100)
        p = QPainter(px)
        fm = p.fontMetrics()
        width = fm.width(text)
        p.end()
        number_chars_in_one_tab = int(tab_default / width)

        p_text = self._prepared_text()
        split_p_text = p_text.split("N")

        pix_list = []
        for text in split_p_text:
            line_num = 0
            i = 0
            length = len(text)
            if length == 0:
                length = 1
            pixmap = QImage(length * w + length, h * 2,
                            QImage.Format_ARGB32_Premultiplied)
            pixmap.fill(Qt.white)
            pix_paint = QPainter(pixmap)

            for char in text:
                if char == "c":
                    draw_char(i, Qt.black)
                if char == "t":
                    for _ in range(0, number_chars_in_one_tab):
                        draw_char(i, Qt.transparent)
                        i += 1
                if char == "_":
                    draw_char(i, Qt.transparent)
                i += 1

            pix_list.append(pixmap)
            line_num += 1
        pix_paint.end()
        # find max width:
        width_list = [pix.width() for pix in pix_list]
        max_width = max(width_list)

        image = QImage(max_width, pix_list[0].height() * len(pix_list),
                       QImage.Format_ARGB32_Premultiplied)
        image.fill(Qt.white)
        painter = QPainter(image)
        for pix in pix_list:
            y = pix_list[0].height() * pix_list.index(pix)
            painter.drawImage(0, y, pix)

        painter.end()
        return image
Beispiel #22
0
    def run(self):

        time.sleep(0.5)
        # create hash dict of current list
        self._hash_item_dict = {}
        for item in self._item_list:
            self._hash_item_dict[item.hash] = item

        # compare and swap between lists if new item is not generated
        for new_hash in self._hash_item_dict.keys():
            if new_hash in self._old_hash_item_dict.keys():
                # swap to avoid generating uselessly :
                self._hash_item_dict[new_hash] = self._old_hash_item_dict[
                    new_hash]
            else:  # generate
                _ = self._hash_item_dict[new_hash].image

        # append generated images
        # images_list.append()
        pix_list = []
        for new_item in self._item_list:
            usable_item = self._hash_item_dict[new_item.hash]
            pix_list.append(usable_item.image)

        # draw pixmaps in one :
        image = QImage(20, 20, QImage.Format_ARGB32_Premultiplied)
        image.fill(Qt.white)
        point = QPoint(0, 0)
        width_list = [pix.width() for pix in pix_list]
        max_width = max(width_list)
        self._max_width_found = max([max_width, self._max_width_found])
        for pix in pix_list:

            last_image = image
            image = QImage(self._max_width_found,
                           image.height() + pix.height(),
                           QImage.Format_ARGB32_Premultiplied)
            pix_paint = QPainter(image)
            image.fill(Qt.white)
            pix_paint.drawImage(0, 0, last_image)
            pix_paint.drawImage(point, pix)
            point = QPoint(0, point.y() + pix.height())
            pix_paint.end()
        '''
        pixmap = QImage(21,21, QImage.Format_ARGB32_Premultiplied) # temp
        pixPaint = QPainter(pixmap)
        myPen = QPen( Qt.black)
        pixPaint.setPen(myPen)
        pixPaint.drawRect(0,0, 20,20);
        pixPaint.end()
        image = pixmap

            painter.drawImage(point, pix)
            point = QPoint(0, point.y() + pix.height())
        painter.end()
          '''

        final_pixmap = QPixmap.fromImage(image, Qt.AutoColor)
        self.image_generated.emit(final_pixmap)

        self._old_item_list = self._item_list
        self._old_hash_item_dict = self._hash_item_dict
    def _generate_image(self):
        h = 2
        w = 1

        def draw_char(pos, pen_color):
            pix_paint.setPen(QPen(pen_color))

            rect = QRect(i * w + i, 1, w, h)
            pix_paint.drawRect(rect)
            pix_paint.fillRect(rect, pen_color)

        # range of tab:
        tab_default = 80

        text = "m"
        px = QPixmap(100, 100)
        p = QPainter(px)
        fm = p.fontMetrics()
        width = fm.width(text)
        p.end()
        number_chars_in_one_tab = int(tab_default / width)

        p_text = self._prepared_text()
        split_p_text = p_text.split("N")

        pix_list = []
        for text in split_p_text:
            line_num = 0
            i = 0
            length = len(text)
            if length == 0:
                length = 1
            pixmap = QImage(
                length * w + length, h * 2, QImage.Format_ARGB32_Premultiplied)
            pixmap.fill(Qt.white)
            pix_paint = QPainter(pixmap)

            for char in text:
                if char == "c":
                    draw_char(i, Qt.black)
                if char == "t":
                    for _ in range(0, number_chars_in_one_tab):
                        draw_char(i, Qt.transparent)
                        i += 1
                if char == "_":
                    draw_char(i, Qt.transparent)
                i += 1

            pix_list.append(pixmap)
            line_num += 1
        pix_paint.end()
        # find max width:
        width_list = [pix.width() for pix in pix_list]
        max_width = max(width_list)

        image = QImage(max_width, pix_list[
                       0].height() * len(pix_list), QImage.Format_ARGB32_Premultiplied)
        image.fill(Qt.white)
        painter = QPainter(image)
        for pix in pix_list:
            y = pix_list[0].height() * pix_list.index(pix)
            painter.drawImage(0, y, pix)

        painter.end()
        return image