Пример #1
0
def rescale_image(data, scale_news_images, compress_news_images_max_size, compress_news_images_auto_size):
    orig_data = data  # save it in case compression fails
    img = image_from_data(data)
    orig_w, orig_h = img.width(), img.height()
    if scale_news_images is not None:
        wmax, hmax = scale_news_images
        if wmax < orig_w or hmax < orig_h:
            orig_w, orig_h, data = scale_image(img, wmax, hmax, compression_quality=95)
    if compress_news_images_max_size is None:
        if compress_news_images_auto_size is None:  # not compressing
            return data
        maxsizeb = (orig_w * orig_h)/compress_news_images_auto_size
    else:
        maxsizeb = compress_news_images_max_size * 1024

    if len(data) <= maxsizeb:  # no compression required
        return data

    scaled_data = data  # save it in case compression fails
    quality = 90
    while len(data) >= maxsizeb and quality >= 5:
        data = image_to_data(image_from_data(scaled_data), compression_quality=quality)
        quality -= 5

    if len(data) >= len(scaled_data):  # compression failed
        return orig_data if len(orig_data) <= len(scaled_data) else scaled_data

    if len(data) >= len(orig_data):  # no improvement
        return orig_data

    return data
Пример #2
0
    def get_cover(self, id, thumbnail=False, thumb_width=60, thumb_height=80):
        try:
            cherrypy.response.headers['Content-Type'] = 'image/jpeg'
            cherrypy.response.timeout = 3600
            cover = self.db.cover(id, index_is_id=True)
            if cover is None:
                cover = self.default_cover
                updated = self.build_time
            else:
                updated = self.db.cover_last_modified(id, index_is_id=True)
            cherrypy.response.headers['Last-Modified'] = self.last_modified(updated)

            if thumbnail:
                quality = tweaks['content_server_thumbnail_compression_quality']
                if quality < 50:
                    quality = 50
                elif quality > 99:
                    quality = 99
                return scale_image(cover, thumb_width, thumb_height, compression_quality=quality)[-1]

            return save_cover_data_to(cover, None, minify_to=(self.max_cover_width, self.max_cover_height))
        except Exception as err:
            import traceback
            cherrypy.log.error('Failed to generate cover:')
            cherrypy.log.error(traceback.print_exc())
            raise cherrypy.HTTPError(404, 'Failed to generate cover: %r'%err)
Пример #3
0
    def browse_icon(self, name='blank.png'):
        cherrypy.response.headers['Content-Type'] = 'image/png'
        cherrypy.response.headers['Last-Modified'] = self.last_modified(
            self.build_time)

        if not hasattr(self, '__browse_icon_cache__'):
            self.__browse_icon_cache__ = {}
        if name not in self.__browse_icon_cache__:
            if name.startswith('_'):
                name = sanitize_file_name2(name[1:])
                try:
                    with open(os.path.join(config_dir, 'tb_icons', name),
                              'rb') as f:
                        data = f.read()
                except:
                    raise cherrypy.HTTPError(404, 'no icon named: %r' % name)
            else:
                try:
                    data = I(name, data=True)
                except:
                    raise cherrypy.HTTPError(404, 'no icon named: %r' % name)
            self.__browse_icon_cache__[name] = scale_image(data,
                                                           48,
                                                           48,
                                                           as_png=True)[-1]
        return self.__browse_icon_cache__[name]
Пример #4
0
def icon(ctx, rd, which):
    sz = rd.query.get('sz')
    if sz != 'full':
        try:
            sz = int(rd.query.get('sz', 48))
        except Exception:
            sz = 48
    if which in {'', '_'}:
        raise HTTPNotFound()
    if which.startswith('_'):
        base = os.path.join(config_dir, 'tb_icons')
        path = os.path.abspath(os.path.join(base, *which[1:].split('/')))
        if not path.startswith(base) or ':' in which:
            raise HTTPNotFound('Naughty, naughty!')
    else:
        base = P('images', allow_user_override=False)
        path = os.path.abspath(os.path.join(base, *which.split('/')))
        if not path.startswith(base) or ':' in which:
            raise HTTPNotFound('Naughty, naughty!')
        path = os.path.relpath(path, base).replace(os.sep, '/')
        path = P('images/' + path)
    if sz == 'full':
        try:
            return share_open(path, 'rb')
        except EnvironmentError:
            raise HTTPNotFound()
    with lock:
        tdir = os.path.join(rd.tdir, 'icons')
        cached = os.path.join(tdir, '%d-%s.png' % (sz, which))
        try:
            return share_open(cached, 'rb')
        except EnvironmentError:
            pass
        try:
            src = share_open(path, 'rb')
        except EnvironmentError:
            raise HTTPNotFound()
        with src:
            idata = src.read()
            img = image_from_data(idata)
        scaled, width, height = fit_image(img.width(), img.height(), sz, sz)
        if scaled:
            idata = scale_image(img, width, height, as_png=True)[-1]
        try:
            ans = share_open(cached, 'w+b')
        except EnvironmentError:
            try:
                os.mkdir(tdir)
            except EnvironmentError:
                pass
            ans = share_open(cached, 'w+b')
        ans.write(idata)
        ans.seek(0)
        return ans
Пример #5
0
 def run(self):
     while self._run and not self.tasks.empty():
         try:
             result, callback, timeout = self.tasks.get()
             if result and result.cover_url:
                 with closing(self.br.open(result.cover_url, timeout=timeout)) as f:
                     result.cover_data = f.read()
                 result.cover_data = scale_image(result.cover_data, 64, 64)[2]
                 callback()
             self.tasks.task_done()
         except:
             if DEBUG:
                 traceback.print_exc()
Пример #6
0
 def run(self):
     while self._run and not self.tasks.empty():
         try:
             result, callback, timeout = self.tasks.get()
             if result and result.cover_url:
                 if result.cover_url.startswith('data:'):
                     result.cover_data = decode_data_url(result.cover_url)
                 else:
                     with closing(self.br.open(result.cover_url, timeout=timeout)) as f:
                         result.cover_data = f.read()
                 result.cover_data = scale_image(result.cover_data, 256, 256)[2]
                 callback()
             self.tasks.task_done()
         except:
             if DEBUG:
                 traceback.print_exc()
Пример #7
0
 def render(self):
     from calibre.utils.img import image_from_data, scale_image, crop_image
     with lopen(self.path_to_page, 'rb') as f:
         img = image_from_data(f.read())
     width, height = img.width(), img.height()
     if self.num == 0:  # First image so create a thumbnail from it
         with lopen(os.path.join(self.dest, 'thumbnail.png'), 'wb') as f:
             f.write(scale_image(img, as_png=True)[-1])
     self.pages = [img]
     if width > height:
         if self.opts.landscape:
             self.rotate = True
         else:
             half = int(width/2)
             split1 = crop_image(img, 0, 0, half, height)
             split2 = crop_image(img, half, 0, width - half, height)
             self.pages = [split2, split1] if self.opts.right2left else [split1, split2]
     self.process_pages()
Пример #8
0
    def upload_cover(self, path, filename, metadata, filepath):
        from calibre.ebooks.covers import calibre_cover2
        from calibre.utils.img import scale_image
        coverdata = getattr(metadata, 'thumbnail', None)
        if coverdata and coverdata[2]:
            cover = coverdata[2]
        else:
            cover = calibre_cover2(metadata.get('title', _('Unknown')),
                    metadata.get('authors', _('Unknown')))

        cover = scale_image(cover, width=self.THUMBNAIL_HEIGHT,
                height=self.THUMBNAIL_HEIGHT, as_png=True)[-1]

        cpath = self.alex_cpath(os.path.join(path, filename))
        cdir = os.path.dirname(cpath)
        if not os.path.exists(cdir):
            os.makedirs(cdir)
        with lopen(cpath, 'wb') as coverfile:
            coverfile.write(cover)
            fsync(coverfile)
Пример #9
0
    def browse_icon(self, name='blank.png'):
        cherrypy.response.headers['Content-Type'] = 'image/png'
        cherrypy.response.headers['Last-Modified'] = self.last_modified(self.build_time)

        if not hasattr(self, '__browse_icon_cache__'):
            self.__browse_icon_cache__ = {}
        if name not in self.__browse_icon_cache__:
            if name.startswith('_'):
                name = sanitize_file_name2(name[1:])
                try:
                    with open(os.path.join(config_dir, 'tb_icons', name), 'rb') as f:
                        data = f.read()
                except:
                    raise cherrypy.HTTPError(404, 'no icon named: %r'%name)
            else:
                try:
                    data = I(name, data=True)
                except:
                    raise cherrypy.HTTPError(404, 'no icon named: %r'%name)
            self.__browse_icon_cache__[name] = scale_image(data, 48, 48, as_png=True)[-1]
        return self.__browse_icon_cache__[name]
Пример #10
0
def rescale_image(data, maxsizeb=IMAGE_MAX_SIZE, dimen=None):
    '''
    Convert image setting all transparent pixels to white and changing format
    to JPEG. Ensure the resultant image has a byte size less than
    maxsizeb.

    If dimen is not None, generate a thumbnail of
    width=dimen, height=dimen or width, height = dimen (depending on the type
    of dimen)

    Returns the image as a bytestring
    '''
    if dimen is not None:
        if hasattr(dimen, '__len__'):
            width, height = dimen
        else:
            width = height = dimen
        data = scale_image(data, width=width, height=height, compression_quality=90)[-1]
    else:
        # Replace transparent pixels with white pixels and convert to JPEG
        data = save_cover_data_to(data)
    if len(data) <= maxsizeb:
        return data
    orig_data = data  # save it in case compression fails
    quality = 90
    while len(data) > maxsizeb and quality >= 5:
        data = image_to_data(image_from_data(orig_data), compression_quality=quality)
        quality -= 5
    if len(data) <= maxsizeb:
        return data
    orig_data = data

    scale = 0.9
    while len(data) > maxsizeb and scale >= 0.05:
        img = image_from_data(data)
        w, h = img.width(), img.height()
        img = resize_image(img, int(scale*w), int(scale*h))
        data = image_to_data(img, compression_quality=quality)
        scale -= 0.05
    return data
Пример #11
0
 def copy_func(dest):
     buf = BytesIO()
     db.copy_cover_to(book_id, buf)
     quality = min(99, max(50, tweaks['content_server_thumbnail_compression_quality']))
     data = scale_image(buf.getvalue(), width=width, height=height, compression_quality=quality)[-1]
     dest.write(data)