Thumb Generator: switch to jpeg + lower quality when needed

The quality API doesn't work on the default PNG but works on JPG.

- Switching to JPEG (100%) produces a smaller image than the default PNG. This covers most scenes.

- For some scenes, the size could still be larger than 2MB, so retry with JPEG (80%). For a 1080p image, this action produces the file at <1MB range. The quality still looks ok, I think.
This commit is contained in:
infinite-persistence 2022-01-13 12:48:32 +08:00
parent 3c3d73a189
commit eb420af865
No known key found for this signature in database
GPG key ID: B9C3252EDC3D0AA0

View file

@ -3,8 +3,10 @@ import React, { useRef } from 'react';
import { Modal } from 'modal/modal'; import { Modal } from 'modal/modal';
import { formatFileSystemPath } from 'util/url'; import { formatFileSystemPath } from 'util/url';
const VANWA_SIZE_LIMIT = 2 * 1024 * 1024;
type Props = { type Props = {
upload: WebFile => void, upload: (WebFile) => void,
filePath: string, filePath: string,
closeModal: () => void, closeModal: () => void,
showToast: ({}) => void, showToast: ({}) => void,
@ -21,20 +23,27 @@ function ModalAutoGenerateThumbnail(props: Props) {
} }
function uploadImage() { function uploadImage() {
const imageBuffer = captureSnapshot(); const generateImg = (quality: number) => {
const imageBuffer = captureSnapshot(quality);
// $FlowFixMe // $FlowFixMe
const file = new File([imageBuffer], 'thumbnail.png', { type: 'image/png' }); const file = new File([imageBuffer], 'thumbnail.jpeg', { type: 'image/jpeg' });
return { imageBuffer, file };
};
if (imageBuffer) { let img = generateImg(1.0);
// $FlowFixMe if (img.file && img.file.size > VANWA_SIZE_LIMIT) {
upload(file); img = generateImg(0.8);
}
if (img.imageBuffer) {
upload(img.file);
closeModal(); closeModal();
} else { } else {
onError(); onError();
} }
} }
function captureSnapshot(): ?Buffer { function captureSnapshot(quality: number): ?Buffer {
const player = playerRef.current; const player = playerRef.current;
if (!player) { if (!player) {
return; return;
@ -45,7 +54,7 @@ function ModalAutoGenerateThumbnail(props: Props) {
canvas.height = player.videoHeight; canvas.height = player.videoHeight;
const context = canvas.getContext('2d'); const context = canvas.getContext('2d');
context.drawImage(player, 0, 0, canvas.width, canvas.height); context.drawImage(player, 0, 0, canvas.width, canvas.height);
const dataURL = canvas.toDataURL(); const dataURL = canvas.toDataURL('image/jpeg', quality);
const rawData = dataURL.replace(/data:image\/\w+;base64,/i, ''); const rawData = dataURL.replace(/data:image\/\w+;base64,/i, '');
canvas.remove(); canvas.remove();
return Buffer.from(rawData, 'base64'); return Buffer.from(rawData, 'base64');