Added PIL support for images like webp
This commit is contained in:
parent
38464c84b9
commit
622a4f979e
|
@ -2,10 +2,17 @@
|
||||||
import os, subprocess, threading, hashlib
|
import os, subprocess, threading, hashlib
|
||||||
from os.path import isfile
|
from os.path import isfile
|
||||||
|
|
||||||
# Gtk imports
|
# Lib imports
|
||||||
import gi
|
import gi
|
||||||
gi.require_version('GdkPixbuf', '2.0')
|
gi.require_version('GdkPixbuf', '2.0')
|
||||||
from gi.repository import GdkPixbuf
|
from gi.repository import GdkPixbuf, GLib
|
||||||
|
|
||||||
|
|
||||||
|
try:
|
||||||
|
from PIL import Image as PImage
|
||||||
|
except Exception as e:
|
||||||
|
PImage = None
|
||||||
|
|
||||||
|
|
||||||
# Application imports
|
# Application imports
|
||||||
from .mixins.desktopiconmixin import DesktopIconMixin
|
from .mixins.desktopiconmixin import DesktopIconMixin
|
||||||
|
@ -30,7 +37,7 @@ class Icon(DesktopIconMixin, VideoIconMixin):
|
||||||
if file.lower().endswith(self.fvideos): # Video icon
|
if file.lower().endswith(self.fvideos): # Video icon
|
||||||
thumbnl = self.create_thumbnail(dir, file)
|
thumbnl = self.create_thumbnail(dir, file)
|
||||||
elif file.lower().endswith(self.fimages): # Image Icon
|
elif file.lower().endswith(self.fimages): # Image Icon
|
||||||
thumbnl = self.create_scaled_image(full_path, self.video_icon_wh)
|
thumbnl = self.create_scaled_image(full_path)
|
||||||
elif full_path.lower().endswith( ('.desktop',) ): # .desktop file parsing
|
elif full_path.lower().endswith( ('.desktop',) ): # .desktop file parsing
|
||||||
thumbnl = self.parse_desktop_files(full_path)
|
thumbnl = self.parse_desktop_files(full_path)
|
||||||
|
|
||||||
|
@ -38,13 +45,13 @@ class Icon(DesktopIconMixin, VideoIconMixin):
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def create_thumbnail(self, dir, file):
|
def create_thumbnail(self, dir, file, scrub_percent = "65%"):
|
||||||
full_path = f"{dir}/{file}"
|
full_path = f"{dir}/{file}"
|
||||||
try:
|
try:
|
||||||
file_hash = hashlib.sha256(str.encode(full_path)).hexdigest()
|
file_hash = hashlib.sha256(str.encode(full_path)).hexdigest()
|
||||||
hash_img_pth = f"{self.ABS_THUMBS_PTH}/{file_hash}.jpg"
|
hash_img_pth = f"{self.ABS_THUMBS_PTH}/{file_hash}.jpg"
|
||||||
if isfile(hash_img_pth) == False:
|
if isfile(hash_img_pth) == False:
|
||||||
self.generate_video_thumbnail(full_path, hash_img_pth)
|
self.generate_video_thumbnail(full_path, hash_img_pth, scrub_percent)
|
||||||
|
|
||||||
thumbnl = self.create_scaled_image(hash_img_pth, self.video_icon_wh)
|
thumbnl = self.create_scaled_image(hash_img_pth, self.video_icon_wh)
|
||||||
if thumbnl == None: # If no icon whatsoever, return internal default
|
if thumbnl == None: # If no icon whatsoever, return internal default
|
||||||
|
@ -57,12 +64,18 @@ class Icon(DesktopIconMixin, VideoIconMixin):
|
||||||
return GdkPixbuf.Pixbuf.new_from_file(f"{self.DEFAULT_ICONS}/video.png")
|
return GdkPixbuf.Pixbuf.new_from_file(f"{self.DEFAULT_ICONS}/video.png")
|
||||||
|
|
||||||
|
|
||||||
def create_scaled_image(self, path, wxh):
|
def create_scaled_image(self, path, wxh = None):
|
||||||
|
if not wxh:
|
||||||
|
wxh = self.video_icon_wh
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if path.lower().endswith(".gif"):
|
if path.lower().endswith(".gif"):
|
||||||
return GdkPixbuf.PixbufAnimation.new_from_file(path) \
|
return GdkPixbuf.PixbufAnimation.new_from_file(path) \
|
||||||
.get_static_image() \
|
.get_static_image() \
|
||||||
.scale_simple(wxh[0], wxh[1], GdkPixbuf.InterpType.BILINEAR)
|
.scale_simple(wxh[0], wxh[1], GdkPixbuf.InterpType.BILINEAR)
|
||||||
|
else:
|
||||||
|
if PImage and path.lower().endswith(".webp"):
|
||||||
|
return self.image2pixbuf(path, wxh)
|
||||||
else:
|
else:
|
||||||
return GdkPixbuf.Pixbuf.new_from_file_at_scale(path, wxh[0], wxh[1], True)
|
return GdkPixbuf.Pixbuf.new_from_file_at_scale(path, wxh[0], wxh[1], True)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
@ -70,6 +83,18 @@ class Icon(DesktopIconMixin, VideoIconMixin):
|
||||||
print( repr(e) )
|
print( repr(e) )
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def image2pixbuf(self, path, wxh):
|
||||||
|
"""Convert Pillow image to GdkPixbuf"""
|
||||||
|
im = PImage.open(path)
|
||||||
|
data = im.tobytes()
|
||||||
|
data = GLib.Bytes.new(data)
|
||||||
|
w, h = im.size
|
||||||
|
|
||||||
|
pixbuf = GdkPixbuf.Pixbuf.new_from_bytes(data, GdkPixbuf.Colorspace.RGB,
|
||||||
|
False, 8, w, h, w * 3)
|
||||||
|
|
||||||
|
return pixbuf.scale_simple(wxh[0], wxh[1], 2) # BILINEAR = 2
|
||||||
|
|
||||||
def create_from_file(self, path):
|
def create_from_file(self, path):
|
||||||
try:
|
try:
|
||||||
return GdkPixbuf.Pixbuf.new_from_file(path)
|
return GdkPixbuf.Pixbuf.new_from_file(path)
|
||||||
|
|
|
@ -7,9 +7,9 @@ import subprocess
|
||||||
|
|
||||||
|
|
||||||
class VideoIconMixin:
|
class VideoIconMixin:
|
||||||
def generate_video_thumbnail(self, full_path, hash_img_pth):
|
def generate_video_thumbnail(self, full_path, hash_img_pth, scrub_percent = "65%"):
|
||||||
try:
|
try:
|
||||||
proc = subprocess.Popen([self.FFMPG_THUMBNLR, "-t", "65%", "-s", "300", "-c", "jpg", "-i", full_path, "-o", hash_img_pth])
|
proc = subprocess.Popen([self.FFMPG_THUMBNLR, "-t", scrub_percent, "-s", "300", "-c", "jpg", "-i", full_path, "-o", hash_img_pth])
|
||||||
proc.wait()
|
proc.wait()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.logger.debug(repr(e))
|
self.logger.debug(repr(e))
|
||||||
|
|
Loading…
Reference in New Issue