일단 커밋. 오랫동안 커밋을 안해서 꼬였다.
리팩토리 중.
This commit is contained in:
124
.venv/lib/python3.12/site-packages/image/videothumbs.py
Normal file
124
.venv/lib/python3.12/site-packages/image/videothumbs.py
Normal file
@@ -0,0 +1,124 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
"""
|
||||
django-videothumbs
|
||||
"""
|
||||
|
||||
from six import StringIO
|
||||
from django.conf.global_settings import FILE_UPLOAD_TEMP_DIR
|
||||
import math
|
||||
import os
|
||||
import time
|
||||
from PIL import Image
|
||||
|
||||
TMP_DIR = FILE_UPLOAD_TEMP_DIR or '/tmp/'
|
||||
|
||||
def generate_thumb(storage, video_path, thumb_size=None, format='jpg', frames=100):
|
||||
histogram = []
|
||||
|
||||
http_status = 200
|
||||
|
||||
name = video_path
|
||||
path = storage.path(video_path)
|
||||
|
||||
if not storage.exists(video_path):
|
||||
return "", '404'
|
||||
|
||||
framemask = "%s%s%s%s" % (TMP_DIR,
|
||||
name.split('/')[-1].split('.')[0] + str(time.time()),
|
||||
'.%d.',
|
||||
format)
|
||||
# ffmpeg command for grabbing N number of frames
|
||||
cmd = "/usr/bin/ffmpeg -y -t 00:00:05 -i '%s' '%s'" % (path, framemask)
|
||||
|
||||
# make sure that this command worked or return.
|
||||
if os.system(cmd) != 0:
|
||||
return "", '500'
|
||||
|
||||
# loop through the generated images, open, and generate the image histogram.
|
||||
for i in range(1, frames + 1):
|
||||
fname = framemask % i
|
||||
|
||||
if not os.path.exists(os.path.join(TMP_DIR, fname)):
|
||||
break
|
||||
|
||||
image = Image.open(fname)
|
||||
|
||||
# Convert to RGB if necessary
|
||||
if image.mode not in ('L', 'RGB'):
|
||||
image = image.convert('RGB')
|
||||
|
||||
# The list of image historgrams
|
||||
histogram.append(image.histogram())
|
||||
|
||||
n = len(histogram)
|
||||
avg = []
|
||||
|
||||
# Get the image average of the first image
|
||||
for c in range(len(histogram[0])):
|
||||
ac = 0.0
|
||||
for i in range(n):
|
||||
ac = ac + (float(histogram[i][c]) / n)
|
||||
avg.append(ac)
|
||||
|
||||
minn = -1
|
||||
minRMSE = -1
|
||||
|
||||
# Compute the mean squared error
|
||||
for i in range(1, n + 1):
|
||||
results = 0.0
|
||||
num = len(avg)
|
||||
|
||||
for j in range(num):
|
||||
median_error = avg[j] - float(histogram[i - 1][j])
|
||||
results += (median_error * median_error) / num
|
||||
rmse = math.sqrt(results)
|
||||
|
||||
if minn == -1 or rmse < minRMSE:
|
||||
minn = i
|
||||
minRMSE = rmse
|
||||
|
||||
file_location = framemask % (minn)
|
||||
image = Image.open(file_location)
|
||||
|
||||
# If you want to generate a square thumbnail
|
||||
if not thumb_size is None:
|
||||
thumb_w, thumb_h = thumb_size
|
||||
|
||||
if thumb_w == thumb_h:
|
||||
# quad
|
||||
xsize, ysize = image.size
|
||||
# get minimum size
|
||||
minsize = min(xsize, ysize)
|
||||
# largest square possible in the image
|
||||
xnewsize = (xsize - minsize) / 2
|
||||
ynewsize = (ysize - minsize) / 2
|
||||
# crop it
|
||||
image2 = image.crop((xnewsize, ynewsize, xsize - xnewsize, ysize - ynewsize))
|
||||
# load is necessary after crop
|
||||
image2.load()
|
||||
# thumbnail of the cropped image (with ANTIALIAS to make it look better)
|
||||
image2.thumbnail(thumb_size, Image.ANTIALIAS)
|
||||
else:
|
||||
# not quad
|
||||
image2 = image
|
||||
image2.thumbnail(thumb_size, Image.ANTIALIAS)
|
||||
else:
|
||||
image2 = image
|
||||
|
||||
io = StringIO()
|
||||
|
||||
# PNG and GIF are the same, JPG is JPEG
|
||||
if format.upper() == 'JPG':
|
||||
format = 'JPEG'
|
||||
|
||||
image2.save(io, format)
|
||||
|
||||
# We don't know how many frames we capture. We just captured the first 5 seconds, so keep removing until not found
|
||||
for i in range(1, 9999):
|
||||
fname = framemask % i
|
||||
try:
|
||||
os.unlink(fname)
|
||||
except OSError:
|
||||
break
|
||||
|
||||
return io.getvalue(), http_status
|
||||
Reference in New Issue
Block a user