Use psd-tools library for PSD thumbnails

This commit is contained in:
Paul Friederichsen 2023-07-16 07:52:54 -05:00
parent 64f946c58f
commit 8bc275e2d5
5 changed files with 62 additions and 26 deletions

View File

@ -6,6 +6,7 @@ from hydrus.core import HydrusAudioHandling
from hydrus.core import HydrusClipHandling
from hydrus.core import HydrusKritaHandling
from hydrus.core import HydrusSVGHandling
from hydrus.core import HydrusPSDHandling
from hydrus.core import HydrusConstants as HC
from hydrus.core import HydrusData
from hydrus.core import HydrusDocumentHandling
@ -118,14 +119,10 @@ def GenerateThumbnailBytes( path, target_resolution, mime, duration, num_frames,
elif mime == HC.APPLICATION_PSD:
( os_file_handle, temp_path ) = HydrusTemp.GetTempPath( suffix = '.png' )
try:
HydrusVideoHandling.RenderImageToImagePath( path, temp_path )
thumbnail_bytes = HydrusImageHandling.GenerateThumbnailBytesFromStaticImagePath( temp_path, target_resolution, HC.IMAGE_PNG, clip_rect = clip_rect )
thumbnail_bytes = HydrusPSDHandling.GenerateThumbnailBytesFromPSDPath( path, target_resolution, clip_rect = clip_rect )
except:
@ -133,10 +130,6 @@ def GenerateThumbnailBytes( path, target_resolution, mime, duration, num_frames,
thumbnail_bytes = HydrusImageHandling.GenerateThumbnailBytesFromStaticImagePath( thumb_path, target_resolution, HC.IMAGE_PNG, clip_rect = clip_rect )
finally:
HydrusTemp.CleanUpTempPath( os_file_handle, temp_path )
elif mime == HC.APPLICATION_CLIP:
@ -379,7 +372,7 @@ def GetFileInfo( path, mime = None, ok_to_look_for_hydrus_updates = False ):
elif mime == HC.APPLICATION_PSD:
( width, height ) = HydrusImageHandling.GetPSDResolution( path )
( width, height ) = HydrusPSDHandling.GetPSDResolution( path )
elif mime in HC.VIDEO:

View File

@ -793,21 +793,6 @@ def GetEmbeddedFileText( pil_image: PILImage.Image ) -> typing.Optional[ str ]:
return None
def GetPSDResolution( path ):
with open( path, 'rb' ) as f:
f.seek( 14 )
height_bytes = f.read( 4 )
width_bytes = f.read( 4 )
height = struct.unpack( '>L', height_bytes )[0]
width = struct.unpack( '>L', width_bytes )[0]
return ( width, height )
def GetResolutionNumPy( numpy_image ):

View File

@ -0,0 +1,54 @@
from psd_tools import PSDImage
from psd_tools.constants import ChannelID, Tag, ColorMode, Resource
from PIL import Image as PILImage
from hydrus.core import HydrusExceptions
from hydrus.core import HydrusImageHandling
def MergedPILImageFromPSD(path: str) -> PILImage:
psd = PSDImage.open(path)
return psd.topil()
def GenerateThumbnailBytesFromPSDPath(path: str, target_resolution: tuple[int, int], clip_rect = None) -> bytes:
psd = PSDImage.open(path)
pil_image = psd.topil()
no_alpha = psd._record.layer_and_mask_information.layer_info is not None and psd._record.layer_and_mask_information.layer_info.layer_count > 0
if(HydrusImageHandling.PILImageHasTransparency(pil_image) and no_alpha):
print("no alpha")
# merged image from psd-tools has transparency when it shouldn't
# see https://github.com/psd-tools/psd-tools/issues/369
# I think it's fine to convert to RGB in all cases since eventually
# that has to happen for the thumbnail anyway.
pil_image = pil_image.convert("RGB")
if clip_rect is not None:
pil_image = HydrusImageHandling.ClipPILImage( pil_image, clip_rect )
thumbnail_pil_image = pil_image.resize( target_resolution, PILImage.ANTIALIAS )
thumbnail_bytes = HydrusImageHandling.GenerateThumbnailBytesPIL( thumbnail_pil_image )
return thumbnail_bytes
def GetPSDResolution(path: str):
psd = PSDImage.open(path)
resolution = (psd.width, psd.height)
return resolution

View File

@ -29,3 +29,5 @@ QtPy==2.3.0
PySide6==6.4.1
setuptools==65.5.1
psd-tools>=1.9.28

View File

@ -23,3 +23,5 @@ Twisted>=20.3.0
requests==2.31.0
setuptools==65.5.1
psd-tools>=1.9.28