Пример #1
0
    def render_cover(self, book_id):
        if self.ignore_render_requests.is_set():
            return
        tcdata, timestamp = self.thumbnail_cache[book_id]
        use_cache = False
        if timestamp is None:
            # Not in cache
            has_cover, cdata, timestamp = self.model(
            ).db.new_api.cover_or_cache(book_id, 0)
        else:
            has_cover, cdata, timestamp = self.model(
            ).db.new_api.cover_or_cache(book_id, timestamp)
            if has_cover and cdata is None:
                # The cached cover is fresh
                cdata = tcdata
                use_cache = True

        if has_cover:
            p = QImage()
            p.loadFromData(cdata, CACHE_FORMAT if cdata is tcdata else 'JPEG')
            dpr = self.device_pixel_ratio
            p.setDevicePixelRatio(dpr)
            if p.isNull() and cdata is tcdata:
                # Invalid image in cache
                self.thumbnail_cache.invalidate((book_id, ))
                self.update_item.emit(book_id)
                return
            cdata = None if p.isNull() else p
            if not use_cache:  # cache is stale
                if cdata is not None:
                    width, height = p.width(), p.height()
                    scaled, nwidth, nheight = fit_image(
                        width, height,
                        int(dpr * self.delegate.cover_size.width()),
                        int(dpr * self.delegate.cover_size.height()))
                    if scaled:
                        if self.ignore_render_requests.is_set():
                            return
                        p = p.scaled(nwidth, nheight, Qt.IgnoreAspectRatio,
                                     Qt.SmoothTransformation)
                        p.setDevicePixelRatio(dpr)
                    cdata = p
                # update cache
                if cdata is None:
                    self.thumbnail_cache.invalidate((book_id, ))
                else:
                    try:
                        self.thumbnail_cache.insert(book_id, timestamp,
                                                    image_to_data(cdata))
                    except EncodeError as err:
                        self.thumbnail_cache.invalidate((book_id, ))
                        prints(err)
                    except Exception:
                        import traceback
                        traceback.print_exc()
        elif tcdata is not None:
            # Cover was removed, but it exists in cache, remove from cache
            self.thumbnail_cache.invalidate((book_id, ))
        self.delegate.cover_cache.set(book_id, cdata)
        self.update_item.emit(book_id)
Пример #2
0
    def render_cover(self, book_id):
        if self.ignore_render_requests.is_set():
            return
        dpr = self.device_pixel_ratio
        page_width = int(dpr * self.delegate.cover_size.width())
        page_height = int(dpr * self.delegate.cover_size.height())
        tcdata, timestamp = self.thumbnail_cache[book_id]
        use_cache = False
        if timestamp is None:
            # Not in cache
            has_cover, cdata, timestamp = self.model().db.new_api.cover_or_cache(book_id, 0)
        else:
            has_cover, cdata, timestamp = self.model().db.new_api.cover_or_cache(book_id, timestamp)
            if has_cover and cdata is None:
                # The cached cover is fresh
                cdata = tcdata
                use_cache = True

        if has_cover:
            p = QImage()
            p.loadFromData(cdata, CACHE_FORMAT if cdata is tcdata else 'JPEG')
            p.setDevicePixelRatio(dpr)
            if p.isNull() and cdata is tcdata:
                # Invalid image in cache
                self.thumbnail_cache.invalidate((book_id,))
                self.update_item.emit(book_id)
                return
            cdata = None if p.isNull() else p
            if not use_cache:  # cache is stale
                if cdata is not None:
                    width, height = p.width(), p.height()
                    scaled, nwidth, nheight = fit_image(
                        width, height, page_width, page_height)
                    if scaled:
                        if self.ignore_render_requests.is_set():
                            return
                        p = p.scaled(nwidth, nheight, Qt.IgnoreAspectRatio, Qt.SmoothTransformation)
                        p.setDevicePixelRatio(dpr)
                    cdata = p
                # update cache
                if cdata is None:
                    self.thumbnail_cache.invalidate((book_id,))
                else:
                    try:
                        self.thumbnail_cache.insert(book_id, timestamp, image_to_data(cdata))
                    except EncodeError as err:
                        self.thumbnail_cache.invalidate((book_id,))
                        prints(err)
                    except Exception:
                        import traceback
                        traceback.print_exc()
        elif tcdata is not None:
            # Cover was removed, but it exists in cache, remove from cache
            self.thumbnail_cache.invalidate((book_id,))
        self.delegate.cover_cache.set(book_id, cdata)
        self.update_item.emit(book_id)
Пример #3
0
    def imageForDomain(cls, url, allowNull=False):
        '''
        @param: url QUrl
        @return: QIcon
        '''
        if not url.host():
            if allowNull:
                return QImage()
            return cls.emptyWebImage()

        with cls.instance()._iconCacheMutex:
            for url0, img in cls.instance()._iconBuffer:
                if url0.host() == url.host():
                    return img

            # TODO: is it necessary to use escapeSqlGlobString
            escapedHost = gVar.appTools.escapeSqlGlobString(url.host())
            hostPattern = '*%s*' % escapedHost
            icon = IconsDbModel.select().filter(
                IconsDbModel.url.contains(hostPattern)).first()
            img = QImage()
            if icon:
                img.loadFromData(icon.icon)

            if not img.isNull():
                return img
            if not allowNull:
                return cls.emptyWebImage()
            return img
Пример #4
0
    def createThumb (self,path_to_perso):

        list_pic = os.listdir (path_to_perso)
        if len(list_pic) > 0 : 
            find = False
            for pic in list_pic :
                self.success = True
                if self.thumb_ext not in pic : 
                    if "portrait" in pic :
                        find = True    
                        thumbnail = QImage(os.path.join(path_to_perso,pic))
                        if (thumbnail.isNull()):
                            print ('IMAGE NULL',os.path.join(path_to_perso,pic))
                        thumbnail = thumbnail.scaledToWidth(self.thumb_width)
                        pic_basename = pic.split(".")
                        result = thumbnail.save(os.path.join(path_to_perso,self.thumb_ext+".jpg"))
                            
                        try:
                            os.rename(os.path.join(path_to_perso,pic),os.path.join(path_to_perso,self.portrait_ext+".jpg"))
                            self.nb_rename[1] = self.nb_rename[1]+1
                        except FileExistsError :
                            self.nb_rename_failed[1] = self.nb_rename_failed[1]+1
                            pass
                        if result == False :
                            self.nb_echec_thumb_creation[1] = self.nb_echec_thumb_creation[1]+ 1
                            try : 
                                qDebug("Echec de la creation de la miniature :"+os.path.join(path_to_perso,self.thumb_ext+".jpg"))
                                self.echec_list.append("FAILED save"+str(os.path.join(path_to_perso,self.thumb_ext+".jpg")))
                                
                            except UnicodeEncodeError :
                                qDebug("echec sauvegarde ****")

                        else:
                            self.nb_success_thumb_creation[1] = self.nb_success_thumb_creation[1]+1
                    else :
                        pass 
            #une image principale n existe pas
            if find == False : 
                #on fait l hypothese que portrai_ext et thumb_ext contienne tous 2 le mot "portrait"
                thumbnail = QImage(os.path.join(path_to_perso,pic))
                thumbnail = thumbnail.scaledToWidth(self.thumb_width)
                pic_basename = pic.split(".")
                result = thumbnail.save(os.path.join(path_to_perso,self.thumb_ext+".jpg"))
                if result == False : 
                    try : 
                        qDebug("Echec de la creation de la miniature :"+str(os.path.join(path_to_perso,self.thumb_ext+".jpg")))
                        self.echec_list.append("FAILED save"+str(os.path.join(path_to_perso,self.thumb_ext+".jpg")))
                    except UnicodeEncodeError :
                        qDebug("echec sauvegarde ****")
                    self.nb_echec_thumb_creation[1] = self.nb_echec_thumb_creation[1]+1
                else:
                    self.nb_success_thumb_creation[1] = self.nb_success_thumb_creation[1] + 1
                try:
                    os.rename(os.path.join(path_to_perso,pic), os.path.join(path_to_perso,self.portrait_ext+".jpg"))
                    self.nb_rename[1] = self.nb_rename[1] + 1
                except FileExistsError :
                    self.nb_rename_failed[1] = self.nb_rename_failed[1] + 1
                    pass
            else: 
                self.echec_list.append("FAILED no portrait found"+str(path_to_perso))
Пример #5
0
def get_icon(path, pixmap_to_data=None, as_data=False, size=64):
    if not path:
        return
    with TemporaryDirectory() as tdir:
        iconset = os.path.join(tdir, 'output.iconset')
        try:
            subprocess.check_call(
                ['iconutil', '-c', 'iconset', '-o', 'output.iconset', path],
                cwd=tdir)
        except subprocess.CalledProcessError:
            return
        try:
            names = os.listdir(iconset)
        except EnvironmentError:
            return
        if not names:
            return
        from PyQt5.Qt import QImage, Qt
        names.sort(key=numeric_sort_key)
        for name in names:
            m = re.search(r'(\d+)x\d+', name)
            if m is not None and int(m.group(1)) >= size:
                ans = QImage(os.path.join(iconset, name))
                if not ans.isNull():
                    break
        else:
            return
    ans = ans.scaled(size, size, transformMode=Qt.SmoothTransformation)
    if as_data:
        ans = pixmap_to_data(ans)
    return ans
Пример #6
0
def get_icon(path, pixmap_to_data=None, as_data=False, size=64):
    if not path:
        return
    with TemporaryDirectory() as tdir:
        iconset = os.path.join(tdir, 'output.iconset')
        try:
            subprocess.check_call(['iconutil', '-c', 'iconset', '-o', 'output.iconset', path], cwd=tdir)
        except subprocess.CalledProcessError:
            return
        try:
            names = os.listdir(iconset)
        except EnvironmentError:
            return
        if not names:
            return
        from PyQt5.Qt import QImage, Qt
        names.sort(key=numeric_sort_key)
        for name in names:
            m = re.search('(\d+)x\d+', name)
            if m is not None and int(m.group(1)) >= size:
                ans = QImage(os.path.join(iconset, name))
                if not ans.isNull():
                    break
        else:
            return
    ans = ans.scaled(size, size, transformMode=Qt.SmoothTransformation)
    if as_data:
        ans = pixmap_to_data(ans)
    return ans
Пример #7
0
 def paste(self):
     clipboard = QApplication.clipboard()
     md = clipboard.mimeData()
     if md.hasImage():
         img = QImage(md.imageData())
         if not img.isNull():
             self.undo_stack.push(Replace(img, _("Paste image"), self))
     else:
         error_dialog(self, _("No image"), _("No image available in the clipboard"), show=True)
Пример #8
0
 def paste(self):
     clipboard = QApplication.clipboard()
     md = clipboard.mimeData()
     if md.hasImage():
         img = QImage(md.imageData())
         if not img.isNull():
             self.undo_stack.push(Replace(img, _('Paste image'), self))
     else:
         error_dialog(self, _('No image'), _(
             'No image available in the clipboard'), show=True)
Пример #9
0
 def __init__(self, dirpath):
     pictureflow.FlowImages.__init__(self)
     self.images = []
     self.captions = []
     self.subtitles = []
     for f in os.listdir(dirpath):
         f = os.path.join(dirpath, f)
         img = QImage(f)
         if not img.isNull():
             self.images.append(img)
             self.captions.append(os.path.basename(f))
             self.subtitles.append('%d bytes'%os.stat(f).st_size)
Пример #10
0
def getImage(name: str, get_null: bool = False) -> QImage:
    """PNG image called name in assets."""

    if name in imageResources:
        return imageResources[name]
    else:
        resource = QImage(os.path.join(wd, "assets", name + ".png"))
        if resource.isNull():
            if not get_null:
                raise ValueError(f"Resource {name}.png doesn't exist")
        else:
            imageResources[name] = resource
        return resource
Пример #11
0
 def __call__(self, container):
     from PyQt5.Qt import QImage
     from calibre.gui2 import pixmap_to_data
     ext = container.mime_map[self.name].split('/')[-1].upper()
     if ext == 'JPG':
         ext = 'JPEG'
     if ext not in ('PNG', 'JPEG', 'GIF'):
         return False
     with container.open(self.name, 'r+b') as f:
         raw = f.read()
         i = QImage()
         i.loadFromData(raw)
         if i.isNull():
             return False
         raw = pixmap_to_data(i, format=ext, quality=95)
         f.seek(0)
         f.truncate()
         f.write(raw)
     return True
Пример #12
0
 def __call__(self, container):
     from PyQt5.Qt import QImage
     from calibre.gui2 import pixmap_to_data
     ext = container.mime_map[self.name].split('/')[-1].upper()
     if ext == 'JPG':
         ext = 'JPEG'
     if ext not in ('PNG', 'JPEG', 'GIF'):
         return False
     with container.open(self.name, 'r+b') as f:
         raw = f.read()
         i = QImage()
         i.loadFromData(raw)
         if i.isNull():
             return False
         raw = pixmap_to_data(i, format=ext, quality=95)
         f.seek(0)
         f.truncate()
         f.write(raw)
     return True
Пример #13
0
    def imageForUrl(cls, url, allowNull=False):
        '''
        @param: url QUrl
        @return: QImage
        '''
        if not url.path():
            return allowNull and QImage() or cls.emptyWebImage()

        with cls.instance()._iconCacheMutex:
            encUrl = encodeUrl(url)

            # find in urlImageCache
            img = cls.instance()._urlImageCache.get(encUrl, None)
            if img:
                if not img.isNull():
                    return img
                if not allowNull:
                    return cls.emptyWebImage()
                return img

            # find from icon buffer
            for url0, img in cls.instance()._iconBuffer:
                if encodeUrl(url0) == encUrl:
                    return img

            # TODO: is it necessary to use escapeSqlGlobString
            escapedUrl = gVar.appTools.escapeSqlGlobString(
                encUrl.data().decode())

            urlPattern = '%s*' % escapedUrl
            icon = IconsDbModel.select().filter(
                IconsDbModel.url.contains(urlPattern)).first()
            img = QImage()
            if icon:
                img.loadFromData(icon.icon)
            cls.instance()._urlImageCache[encUrl] = img

            if not img.isNull():
                return img
            if not allowNull:
                return cls.emptyWebImage()
            return img
Пример #14
0
    def dropEvent(self, event):
        event.setDropAction(Qt.CopyAction)
        md = event.mimeData()

        x, y = dnd_get_image(md)
        if x is not None:
            # We have an image, set cover
            event.accept()
            if y is None:
                # Local image
                self.undo_stack.push(Replace(x.toImage(), _('Drop image'), self))
            else:
                d = DownloadDialog(x, y, self.gui)
                d.start_download()
                if d.err is None:
                    with open(d.fpath, 'rb') as f:
                        img = QImage()
                        img.loadFromData(f.read())
                    if not img.isNull():
                        self.undo_stack.push(Replace(img, _('Drop image'), self))

        event.accept()
Пример #15
0
    def dropEvent(self, event):
        event.setDropAction(Qt.CopyAction)
        md = event.mimeData()

        x, y = dnd_get_image(md)
        if x is not None:
            # We have an image, set cover
            event.accept()
            if y is None:
                # Local image
                self.undo_stack.push(Replace(x.toImage(), _('Drop image'), self))
            else:
                d = DownloadDialog(x, y, self.gui)
                d.start_download()
                if d.err is None:
                    with open(d.fpath, 'rb') as f:
                        img = QImage()
                        img.loadFromData(f.read())
                    if not img.isNull():
                        self.undo_stack.push(Replace(img, _('Drop image'), self))

        event.accept()
Пример #16
0
    def rescale(self):
        from calibre.utils.magick.draw import Image

        is_image_collection = getattr(self.opts, 'is_image_collection', False)

        if is_image_collection:
            page_width, page_height = self.opts.dest.comic_screen_size
        else:
            page_width, page_height = self.opts.dest.width, self.opts.dest.height
            page_width -= (self.opts.margin_left +
                           self.opts.margin_right) * self.opts.dest.dpi / 72.
            page_height -= (self.opts.margin_top +
                            self.opts.margin_bottom) * self.opts.dest.dpi / 72.

        for item in self.oeb.manifest:
            if item.media_type.startswith('image'):
                ext = item.media_type.split('/')[-1].upper()
                if ext == 'JPG':
                    ext = 'JPEG'
                if ext not in ('PNG', 'JPEG', 'GIF'):
                    ext = 'JPEG'

                raw = item.data
                if hasattr(raw, 'xpath') or not raw:
                    # Probably an svg image
                    continue
                try:
                    img = Image()
                    img.load(raw)
                except:
                    continue
                width, height = img.size

                try:
                    if self.check_colorspaces and img.colorspace == 'CMYKColorspace':
                        # We cannot do an imagemagick conversion of CMYK to RGB as
                        # ImageMagick inverts colors if you just set the colorspace
                        # to rgb. See for example: https://bugs.launchpad.net/bugs/1246710
                        from PyQt5.Qt import QImage
                        from calibre.gui2 import pixmap_to_data
                        qimg = QImage()
                        qimg.loadFromData(raw)
                        if not qimg.isNull():
                            raw = item.data = pixmap_to_data(qimg,
                                                             format=ext,
                                                             quality=95)
                            img = Image()
                            img.load(raw)
                            self.log.warn(
                                'The image %s is in the CMYK colorspace, converting it '
                                'to RGB as Adobe Digital Editions cannot display CMYK'
                                % item.href)
                        else:
                            self.log.warn(
                                'The image %s is in the CMYK colorspace, you should convert'
                                ' it to sRGB as Adobe Digital Editions cannot render CMYK'
                                % item.href)
                except Exception:
                    pass

                scaled, new_width, new_height = fit_image(
                    width, height, page_width, page_height)
                if scaled:
                    new_width = max(1, new_width)
                    new_height = max(1, new_height)
                    self.log(
                        'Rescaling image from %dx%d to %dx%d' %
                        (width, height, new_width, new_height), item.href)
                    try:
                        img.size = (new_width, new_height)
                        data = img.export(ext.lower())
                    except KeyboardInterrupt:
                        raise
                    except:
                        self.log.exception('Failed to rescale image')
                    else:
                        item.data = data
                        item.unload_data_from_memory()
Пример #17
0
    def rescale(self):
        from calibre.utils.magick.draw import Image

        is_image_collection = getattr(self.opts, 'is_image_collection', False)

        if is_image_collection:
            page_width, page_height = self.opts.dest.comic_screen_size
        else:
            page_width, page_height = self.opts.dest.width, self.opts.dest.height
            page_width -= (self.opts.margin_left + self.opts.margin_right) * self.opts.dest.dpi/72.
            page_height -= (self.opts.margin_top + self.opts.margin_bottom) * self.opts.dest.dpi/72.

        for item in self.oeb.manifest:
            if item.media_type.startswith('image'):
                ext = item.media_type.split('/')[-1].upper()
                if ext == 'JPG':
                    ext = 'JPEG'
                if ext not in ('PNG', 'JPEG', 'GIF'):
                    ext = 'JPEG'

                raw = item.data
                if hasattr(raw, 'xpath') or not raw:
                    # Probably an svg image
                    continue
                try:
                    img = Image()
                    img.load(raw)
                except:
                    continue
                width, height = img.size

                try:
                    if self.check_colorspaces and img.colorspace == 'CMYKColorspace':
                        # We cannot do an imagemagick conversion of CMYK to RGB as
                        # ImageMagick inverts colors if you just set the colorspace
                        # to rgb. See for example: https://bugs.launchpad.net/bugs/1246710
                        from PyQt5.Qt import QImage
                        from calibre.gui2 import pixmap_to_data
                        qimg = QImage()
                        qimg.loadFromData(raw)
                        if not qimg.isNull():
                            raw = item.data = pixmap_to_data(qimg, format=ext, quality=95)
                            img = Image()
                            img.load(raw)
                            self.log.warn(
                                'The image %s is in the CMYK colorspace, converting it '
                                'to RGB as Adobe Digital Editions cannot display CMYK' % item.href)
                        else:
                            self.log.warn(
                                'The image %s is in the CMYK colorspace, you should convert'
                                ' it to sRGB as Adobe Digital Editions cannot render CMYK' % item.href)
                except Exception:
                    pass

                scaled, new_width, new_height = fit_image(width, height,
                        page_width, page_height)
                if scaled:
                    new_width = max(1, new_width)
                    new_height = max(1, new_height)
                    self.log('Rescaling image from %dx%d to %dx%d'%(
                        width, height, new_width, new_height), item.href)
                    try:
                        img.size = (new_width, new_height)
                        data = img.export(ext.lower())
                    except KeyboardInterrupt:
                        raise
                    except:
                        self.log.exception('Failed to rescale image')
                    else:
                        item.data = data
                        item.unload_data_from_memory()