import requests import io from PIL import Image, ImageFilter from django.conf import settings from gm_upload.utils.filenameutils import store_picture_and_get_key from utils.rpc import logging_exception class BlurVideoImage(object): PIC_BASE_URL = '?vframe/jpg/offset/{0}/rotate/auto' def __init__(self, handler, uploader): self.handler = handler self.uploader = uploader def run(self, url, second=0, video_pic_url=settings.VIDEO_PIC_URL, video_host=settings.VIDEO_HOST, radius=50, blurimg_size=(800, 450), cropimg_size=(650, 450)): if isinstance(url,bytes): url = url.decode('utf-8') video_pic_url = video_pic_url if not second else self.PIC_BASE_URL.format(second) url = self.clean_video_url(url) img = self.handler.handler(url, video_pic_url, video_host, radius, blurimg_size, cropimg_size) return self.uploader(img) def uploader(self, img): return store_picture_and_get_key(img) @staticmethod def clean_video_url(video_url): return video_url.replace(settings.VIDEO_HOST, '') class EditImage(object): @classmethod def handler(cls, url, video_pic_url, video_host, radius, blurimg_size, cropimg_size): image = cls.open_image(url, video_pic_url, video_host) width, hight = image.size if width < 1.7 * hight: # 针对竖版视频做处理 cropimg_size = cls.adaptsize(blurimg_size, cropimg_size) _squre = min(image.size) _padding = int((width - hight) / 2) x, y = (_padding, 0) if _padding > 0 else (0, -_padding) croped_im = image.crop((x, y, x + _squre, y + _squre)).resize(cropimg_size, Image.ANTIALIAS) blur_image = image.filter(ImageFilter.GaussianBlur(radius=radius)).resize(blurimg_size, Image.ANTIALIAS) x, y = int((blur_image.size[0] - croped_im.size[0]) / 2), int((blur_image.size[1] - croped_im.size[1]) / 2) blur_image.paste(croped_im, (x, y)) else: blur_image = image # convert pillow.image.image to bytesio that can upload to qiniu output = io.BytesIO() blur_image.save(output, format='JPEG') return output.getvalue() @staticmethod def open_image(url, video_pic_url, video_host): url = video_host + url + video_pic_url try: response = requests.get(url, stream=True, timeout=5) if response.status_code == 200: response.raw.decode_content = True return Image.open(response.raw) except RuntimeError: logging_exception() raise @classmethod def adaptsize(cls, blurimg_size, cropimg_size): if max(cropimg_size) > min(blurimg_size): cropimg_size = (min(blurimg_size), min(blurimg_size)) else: cropimg_size = (min(cropimg_size), min(cropimg_size)) return cropimg_size UploadVideoPicture = BlurVideoImage(EditImage, store_picture_and_get_key).run