Switch to thumbnails and thumbnail creation on the sample grid page until clicked.
This commit is contained in:
@@ -1227,6 +1227,58 @@ class GenerateImageConfig:
|
||||
# join with folder
|
||||
return os.path.join(self.output_folder, filename)
|
||||
|
||||
def save_image_atomic(self, image, count: int = 0, max_count=0):
|
||||
# write into a hidden tmp subfolder, then atomically move into place so
|
||||
# watchers (UI/CDN) never see and cache a partially written file. Wraps
|
||||
# self.save_image so it also covers models that replace that function.
|
||||
real_folder = self.output_folder
|
||||
tmp_folder = os.path.join(real_folder, '.tmp')
|
||||
os.makedirs(tmp_folder, exist_ok=True)
|
||||
self.output_folder = tmp_folder
|
||||
try:
|
||||
self.save_image(image, count, max_count)
|
||||
finally:
|
||||
self.output_folder = real_folder
|
||||
files = os.listdir(tmp_folder)
|
||||
# thumbs move into place first so they already exist when the media
|
||||
# file appears in the samples folder
|
||||
thumbs_folder = os.path.join(real_folder, '.thumbs')
|
||||
for file in files:
|
||||
tmp_thumb = os.path.join(tmp_folder, file + '.thumb')
|
||||
try:
|
||||
if self._generate_thumbnail(os.path.join(tmp_folder, file), tmp_thumb):
|
||||
os.makedirs(thumbs_folder, exist_ok=True)
|
||||
os.replace(tmp_thumb, os.path.join(thumbs_folder, file + '.jpg'))
|
||||
except Exception as e:
|
||||
print(f"Failed to generate thumbnail for {file}: {e}")
|
||||
for file in files:
|
||||
os.replace(os.path.join(tmp_folder, file), os.path.join(real_folder, file))
|
||||
|
||||
def _generate_thumbnail(self, media_path, thumb_path):
|
||||
# 300x300 center-cropped 90% jpg. Returns True if one was written.
|
||||
from PIL import Image as PILImage
|
||||
ext = os.path.splitext(media_path)[1].lower()
|
||||
img = None
|
||||
if ext in ['.png', '.jpg', '.jpeg', '.webp', '.gif', '.bmp']:
|
||||
img = PILImage.open(media_path) # animated formats open on the first frame
|
||||
elif ext == '.mp4':
|
||||
import cv2
|
||||
cap = cv2.VideoCapture(media_path)
|
||||
ok, frame = cap.read()
|
||||
cap.release()
|
||||
if ok:
|
||||
img = PILImage.fromarray(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB))
|
||||
if img is None:
|
||||
return False
|
||||
img = img.convert('RGB')
|
||||
w, h = img.size
|
||||
side = min(w, h)
|
||||
left = (w - side) // 2
|
||||
top = (h - side) // 2
|
||||
img = img.crop((left, top, left + side, top + side)).resize((300, 300), PILImage.LANCZOS)
|
||||
img.save(thumb_path, format='JPEG', quality=90)
|
||||
return True
|
||||
|
||||
def save_image(self, image, count: int = 0, max_count=0):
|
||||
# make parent dirs
|
||||
os.makedirs(self.output_folder, exist_ok=True)
|
||||
|
||||
Reference in New Issue
Block a user