コード例 #1
0
    def GetTile(self, image_renderer: ClientRendering.ImageRenderer, media,
                clip_rect, target_resolution):

        hash = media.GetHash()

        key = (hash, clip_rect.left(), clip_rect.top(), clip_rect.right(),
               clip_rect.bottom(), target_resolution.width(),
               target_resolution.height())

        result = self._data_cache.GetIfHasData(key)

        if result is None:

            qt_pixmap = image_renderer.GetQtPixmap(
                clip_rect=clip_rect, target_resolution=target_resolution)

            tile = ClientRendering.ImageTile(hash, clip_rect, qt_pixmap)

            self._data_cache.AddData(key, tile)

        else:

            tile = result

        return tile
コード例 #2
0
    def GetImageRenderer(self, media):

        hash = media.GetHash()

        key = hash

        result = self._data_cache.GetIfHasData(key)

        if result is None:

            image_renderer = ClientRendering.ImageRenderer(media)

            # we are no longer going to let big lads flush the whole cache. they can render on demand

            image_cache_storage_limit_percentage = self._controller.new_options.GetInteger(
                'image_cache_storage_limit_percentage')

            if image_renderer.GetEstimatedMemoryFootprint(
            ) < self._data_cache.GetSizeLimit() * (
                    image_cache_storage_limit_percentage / 100):

                self._data_cache.AddData(key, image_renderer)

        else:

            image_renderer = result

        return image_renderer
コード例 #3
0
ファイル: ClientCaches.py プロジェクト: HOZHENWAI/hydrus
 def Clear( self ):
     
     with self._lock:
         
         self._data_cache.Clear()
         
         self._special_thumbs = {}
         
         names = [ 'hydrus', 'pdf', 'psd', 'audio', 'video', 'zip' ]
         
         bounding_dimensions = self._controller.options[ 'thumbnail_dimensions' ]
         
         for name in names:
             
             path = os.path.join( HC.STATIC_DIR, name + '.png' )
             
             numpy_image = ClientImageHandling.GenerateNumPyImage( path, HC.IMAGE_PNG )
             
             numpy_image_resolution = HydrusImageHandling.GetResolutionNumPy( numpy_image )
             
             target_resolution = HydrusImageHandling.GetThumbnailResolution( numpy_image_resolution, bounding_dimensions )
             
             numpy_image = HydrusImageHandling.ResizeNumPyImage( numpy_image, target_resolution )
             
             hydrus_bitmap = ClientRendering.GenerateHydrusBitmapFromNumPyImage( numpy_image )
             
             self._special_thumbs[ name ] = hydrus_bitmap
             
         
         self._controller.pub( 'notify_complete_thumbnail_reset' )
         
         self._waterfall_queue_quick = set()
         self._delayed_regeneration_queue_quick = set()
         
         self._RecalcQueues()
コード例 #4
0
    def GetImageRenderer(self, media):

        hash = media.GetHash()

        key = hash

        result = self._data_cache.GetIfHasData(key)

        if result is None:

            image_renderer = ClientRendering.ImageRenderer(media)

            self._data_cache.AddData(key, image_renderer)

        else:

            image_renderer = result

        return image_renderer
コード例 #5
0
 def Clear( self ):
     
     with self._lock:
         
         self._data_cache.Clear()
         
         self._special_thumbs = {}
         
         names = [ 'hydrus', 'pdf', 'psd', 'clip', 'audio', 'video', 'zip' ]
         
         bounding_dimensions = self._controller.options[ 'thumbnail_dimensions' ]
         thumbnail_scale_type = self._controller.new_options.GetInteger( 'thumbnail_scale_type' )
         
         # it would be ideal to replace this with mimes_to_default_thumbnail_paths at a convenient point
         
         for name in names:
             
             path = os.path.join( HC.STATIC_DIR, '{}.png'.format( name ) )
             
             numpy_image = ClientImageHandling.GenerateNumPyImage( path, HC.IMAGE_PNG )
             
             numpy_image_resolution = HydrusImageHandling.GetResolutionNumPy( numpy_image )
             
             ( clip_rect, target_resolution ) = HydrusImageHandling.GetThumbnailResolutionAndClipRegion( numpy_image_resolution, bounding_dimensions, thumbnail_scale_type )
             
             if clip_rect is not None:
                 
                 numpy_image = HydrusImageHandling.ClipNumPyImage( numpy_image, clip_rect )
                 
             
             numpy_image = HydrusImageHandling.ResizeNumPyImage( numpy_image, target_resolution )
             
             hydrus_bitmap = ClientRendering.GenerateHydrusBitmapFromNumPyImage( numpy_image )
             
             self._special_thumbs[ name ] = hydrus_bitmap
             
         
         self._controller.pub( 'notify_complete_thumbnail_reset' )
         
         self._waterfall_queue_quick = set()
         self._delayed_regeneration_queue_quick = set()
         
         self._RecalcQueues()
コード例 #6
0
    def _GetThumbnailHydrusBitmap(self, display_media):

        bounding_dimensions = self._controller.options['thumbnail_dimensions']

        hash = display_media.GetHash()
        mime = display_media.GetMime()

        locations_manager = display_media.GetLocationsManager()

        try:

            path = self._controller.client_files_manager.GetThumbnailPath(
                display_media)

        except HydrusExceptions.FileMissingException as e:

            if locations_manager.IsLocal():

                summary = 'Unable to get thumbnail for file {}.'.format(
                    hash.hex())

                self._HandleThumbnailException(e, summary)

            return self._special_thumbs['hydrus']

        try:

            numpy_image = ClientImageHandling.GenerateNumPyImage(path, mime)

        except Exception as e:

            try:

                # file is malformed, let's force a regen
                self._controller.files_maintenance_manager.RunJobImmediately(
                    [display_media],
                    ClientFiles.REGENERATE_FILE_DATA_JOB_FORCE_THUMBNAIL,
                    pub_job_key=False)

            except Exception as e:

                summary = 'The thumbnail for file {} was not loadable. An attempt to regenerate it failed.'.format(
                    hash.hex())

                self._HandleThumbnailException(e, summary)

                return self._special_thumbs['hydrus']

            try:

                numpy_image = ClientImageHandling.GenerateNumPyImage(
                    path, mime)

            except Exception as e:

                summary = 'The thumbnail for file {} was not loadable. It was regenerated, but that file would not render either. Your image libraries or hard drive connection are unreliable. Please inform the hydrus developer what has happened.'.format(
                    hash.hex())

                self._HandleThumbnailException(e, summary)

                return self._special_thumbs['hydrus']

        (current_width,
         current_height) = HydrusImageHandling.GetResolutionNumPy(numpy_image)

        (media_width, media_height) = display_media.GetResolution()

        (expected_width,
         expected_height) = HydrusImageHandling.GetThumbnailResolution(
             (media_width, media_height), bounding_dimensions)

        exactly_as_expected = current_width == expected_width and current_height == expected_height

        rotation_exception = current_width == expected_height and current_height == expected_width

        correct_size = exactly_as_expected or rotation_exception

        if not correct_size:

            it_is_definitely_too_big = current_width >= expected_width and current_height >= expected_height

            if it_is_definitely_too_big:

                if HG.file_report_mode:

                    HydrusData.ShowText('Thumbnail {} too big.'.format(
                        hash.hex()))

                # the thumb we have is larger than desired. we can use it to generate what we actually want without losing significant data

                # this is _resize_, not _thumbnail_, because we already know the dimensions we want
                # and in some edge cases, doing getthumbresolution on existing thumb dimensions results in float/int conversion imprecision and you get 90px/91px regen cycles that never get fixed
                numpy_image = HydrusImageHandling.ResizeNumPyImage(
                    numpy_image, (expected_width, expected_height))

                if locations_manager.IsLocal():

                    # we have the master file, so it is safe to save our resized thumb back to disk since we can regen from source if needed

                    if HG.file_report_mode:

                        HydrusData.ShowText(
                            'Thumbnail {} too big, saving back to disk.'.
                            format(hash.hex()))

                    try:

                        try:

                            thumbnail_bytes = HydrusImageHandling.GenerateThumbnailBytesNumPy(
                                numpy_image, mime)

                        except HydrusExceptions.CantRenderWithCVException:

                            thumbnail_bytes = HydrusImageHandling.GenerateThumbnailBytesFromStaticImagePath(
                                path, (expected_width, expected_height), mime)

                    except:

                        summary = 'The thumbnail for file {} was too large, but an attempt to shrink it failed.'.format(
                            hash.hex())

                        self._HandleThumbnailException(e, summary)

                        return self._special_thumbs['hydrus']

                    try:

                        self._controller.client_files_manager.AddThumbnailFromBytes(
                            hash, thumbnail_bytes, silent=True)

                        self._controller.files_maintenance_manager.ClearJobs(
                            {hash}, ClientFiles.
                            REGENERATE_FILE_DATA_JOB_REFIT_THUMBNAIL)

                    except:

                        summary = 'The thumbnail for file {} was too large, but an attempt to save back the shrunk file failed.'.format(
                            hash.hex())

                        self._HandleThumbnailException(e, summary)

                        return self._special_thumbs['hydrus']

            else:

                # the thumb we have is either too small or completely messed up due to a previous ratio misparse

                media_is_same_size_as_current_thumb = current_width == media_width and current_height == media_height

                if media_is_same_size_as_current_thumb:

                    # the thumb is smaller than expected, but this is a 32x32 pixilart image or whatever, so no need to scale

                    if HG.file_report_mode:

                        HydrusData.ShowText(
                            'Thumbnail {} too small due to small source file.'.
                            format(hash.hex()))

                else:

                    numpy_image = HydrusImageHandling.ResizeNumPyImage(
                        numpy_image, (expected_width, expected_height))

                    if locations_manager.IsLocal():

                        # we have the master file, so we should regen the thumb from source

                        if HG.file_report_mode:

                            HydrusData.ShowText(
                                'Thumbnail {} too small, scheduling regeneration from source.'
                                .format(hash.hex()))

                        delayed_item = display_media.GetMediaResult()

                        with self._lock:

                            if delayed_item not in self._delayed_regeneration_queue_quick:

                                self._delayed_regeneration_queue_quick.add(
                                    delayed_item)

                                self._delayed_regeneration_queue.append(
                                    delayed_item)

                    else:

                        # we do not have the master file, so we have to scale up from what we have

                        if HG.file_report_mode:

                            HydrusData.ShowText(
                                'Thumbnail {} was too small, only scaling up due to no local source.'
                                .format(hash.hex()))

        hydrus_bitmap = ClientRendering.GenerateHydrusBitmapFromNumPyImage(
            numpy_image)

        return hydrus_bitmap
コード例 #7
0
 def _GetThumbnailHydrusBitmap( self, display_media ):
     
     hash = display_media.GetHash()
     mime = display_media.GetMime()
     
     thumbnail_mime = HC.IMAGE_JPEG
     
     # we don't actually know this, it comes down to detailed stuff, but since this is png vs jpeg it isn't a huge deal down in the guts of image loading
     # only really matters with transparency, so anything that can be transparent we'll prime with a png thing
     # ain't like I am encoding EXIF rotation in my jpeg thumbs
     if mime in ( HC.IMAGE_APNG, HC.IMAGE_PNG, HC.IMAGE_GIF, HC.IMAGE_ICON, HC.IMAGE_WEBP ):
         
         thumbnail_mime = HC.IMAGE_PNG
         
     
     locations_manager = display_media.GetLocationsManager()
     
     try:
         
         path = self._controller.client_files_manager.GetThumbnailPath( display_media )
         
     except HydrusExceptions.FileMissingException as e:
         
         if locations_manager.IsLocal():
             
             summary = 'Unable to get thumbnail for file {}.'.format( hash.hex() )
             
             self._HandleThumbnailException( e, summary )
             
         
         return self._special_thumbs[ 'hydrus' ]
         
     
     try:
         
         numpy_image = ClientImageHandling.GenerateNumPyImage( path, thumbnail_mime )
         
     except Exception as e:
         
         try:
             
             # file is malformed, let's force a regen
             self._controller.files_maintenance_manager.RunJobImmediately( [ display_media ], ClientFiles.REGENERATE_FILE_DATA_JOB_FORCE_THUMBNAIL, pub_job_key = False )
             
         except Exception as e:
             
             summary = 'The thumbnail for file {} was not loadable. An attempt to regenerate it failed.'.format( hash.hex() )
             
             self._HandleThumbnailException( e, summary )
             
             return self._special_thumbs[ 'hydrus' ]
             
         
         try:
             
             numpy_image = ClientImageHandling.GenerateNumPyImage( path, thumbnail_mime )
             
         except Exception as e:
             
             summary = 'The thumbnail for file {} was not loadable. It was regenerated, but that file would not render either. Your image libraries or hard drive connection are unreliable. Please inform the hydrus developer what has happened.'.format( hash.hex() )
             
             self._HandleThumbnailException( e, summary )
             
             return self._special_thumbs[ 'hydrus' ]
             
         
     
     ( current_width, current_height ) = HydrusImageHandling.GetResolutionNumPy( numpy_image )
     
     ( media_width, media_height ) = display_media.GetResolution()
     
     bounding_dimensions = self._controller.options[ 'thumbnail_dimensions' ]
     
     thumbnail_scale_type = self._controller.new_options.GetInteger( 'thumbnail_scale_type' )
     
     ( clip_rect, ( expected_width, expected_height ) ) = HydrusImageHandling.GetThumbnailResolutionAndClipRegion( ( media_width, media_height ), bounding_dimensions, thumbnail_scale_type )
     
     exactly_as_expected = current_width == expected_width and current_height == expected_height
     
     rotation_exception = current_width == expected_height and current_height == expected_width
     
     correct_size = exactly_as_expected or rotation_exception
     
     if not correct_size:
         
         numpy_image = HydrusImageHandling.ResizeNumPyImage( numpy_image, ( expected_width, expected_height ) )
         
         if locations_manager.IsLocal():
             
             # we have the master file, so we should regen the thumb from source
             
             if HG.file_report_mode:
                 
                 HydrusData.ShowText( 'Thumbnail {} too small, scheduling regeneration from source.'.format( hash.hex() ) )
                 
             
             delayed_item = display_media.GetMediaResult()
             
             with self._lock:
                 
                 if delayed_item not in self._delayed_regeneration_queue_quick:
                     
                     self._delayed_regeneration_queue_quick.add( delayed_item )
                     
                     self._delayed_regeneration_queue.append( delayed_item )
                     
                 
             
         else:
             
             # we do not have the master file, so we have to scale up from what we have
             
             if HG.file_report_mode:
                 
                 HydrusData.ShowText( 'Stored thumbnail {} was the wrong size, only scaling due to no local source.'.format( hash.hex() ) )
                 
             
         
     
     hydrus_bitmap = ClientRendering.GenerateHydrusBitmapFromNumPyImage( numpy_image )
     
     return hydrus_bitmap