Web: Shared: Image processing is moved to a general function.

This commit is contained in:
Tatiana Lopaeva 2024-05-13 20:41:51 +03:00
parent 4784395b02
commit 80b943c0e7
3 changed files with 68 additions and 65 deletions

View File

@ -25,15 +25,11 @@
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode // International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
import React, { useState, useRef, useEffect } from "react"; import React, { useState, useRef, useEffect } from "react";
import resizeImage from "resize-image"; import { imageProcessing } from "@docspace/shared/utils/common";
import DropzoneComponent from "../../dropzone"; import DropzoneComponent from "../../dropzone";
import { toastr } from "../../toast"; import { toastr } from "../../toast";
const ONE_MEGABYTE = 1024 * 1024;
const COMPRESSION_RATIO = 2;
const NO_COMPRESSION_RATIO = 1;
const Dropzone = ({ const Dropzone = ({
t, t,
setUploadedFile, setUploadedFile,
@ -55,70 +51,12 @@ const Dropzone = ({
}; };
}, []); }, []);
async function resizeRecursiveAsync(
img: { width: number; height: number },
canvas: HTMLCanvasElement,
compressionRatio = COMPRESSION_RATIO,
depth = 0,
): Promise<unknown> {
const data = resizeImage.resize(
// @ts-expect-error canvas
canvas,
img.width / compressionRatio,
img.height / compressionRatio,
resizeImage.JPEG,
);
const file = await fetch(data)
.then((res) => res.blob())
.then((blob) => {
const f = new File([blob], "File name", {
type: "image/jpg",
});
return f;
});
// const stepMessage = `Step ${depth + 1}`;
// const sizeMessage = `size = ${file.size} bytes`;
// const compressionRatioMessage = `compressionRatio = ${compressionRatio}`;
// console.log(`${stepMessage} ${sizeMessage} ${compressionRatioMessage}`);
if (file.size < ONE_MEGABYTE) {
return file;
}
if (depth > 5) {
// console.log("start");
throw new Error("recursion depth exceeded");
}
return new Promise((resolve) => {
// eslint-disable-next-line no-promise-executor-return
return resolve(file);
}).then(() =>
resizeRecursiveAsync(img, canvas, compressionRatio + 1, depth + 1),
);
}
const onDrop = async ([file]: File[]) => { const onDrop = async ([file]: File[]) => {
timer.current = setTimeout(() => { timer.current = setTimeout(() => {
setLoadingFile(true); setLoadingFile(true);
}, 50); }, 50);
try { try {
const imageBitMap = await createImageBitmap(file); imageProcessing(file)
const width = imageBitMap.width;
const height = imageBitMap.height;
// @ts-expect-error imageBitMap
const canvas = resizeImage.resize2Canvas(imageBitMap, width, height);
resizeRecursiveAsync(
{ width, height },
canvas,
file.size > ONE_MEGABYTE ? COMPRESSION_RATIO : NO_COMPRESSION_RATIO,
)
.then((f) => { .then((f) => {
if (mount.current) { if (mount.current) {
if (f instanceof File) setUploadedFile(f); if (f instanceof File) setUploadedFile(f);

View File

@ -75,4 +75,4 @@ const ImageEditor = ({
); );
}; };
export { ImageEditor, AvatarPreview }; export { ImageEditor, AvatarPreview, Dropzone };

View File

@ -32,6 +32,7 @@ import find from "lodash/find";
import moment from "moment-timezone"; import moment from "moment-timezone";
import { isMobile } from "react-device-detect"; import { isMobile } from "react-device-detect";
import sjcl from "sjcl"; import sjcl from "sjcl";
import resizeImage from "resize-image";
import LoginPageSvgUrl from "PUBLIC_DIR/images/logo/loginpage.svg?url"; import LoginPageSvgUrl from "PUBLIC_DIR/images/logo/loginpage.svg?url";
import DarkLoginPageSvgUrl from "PUBLIC_DIR/images/logo/dark_loginpage.svg?url"; import DarkLoginPageSvgUrl from "PUBLIC_DIR/images/logo/dark_loginpage.svg?url";
@ -1068,3 +1069,67 @@ export function getLogoUrl(
) { ) {
return `/logo.ashx?logotype=${logoType}&dark=${dark}&default=${def}`; return `/logo.ashx?logotype=${logoType}&dark=${dark}&default=${def}`;
} }
export const imageProcessing = async (file: File) => {
const ONE_MEGABYTE = 1024 * 1024;
const COMPRESSION_RATIO = 2;
const NO_COMPRESSION_RATIO = 1;
const imageBitMap = await createImageBitmap(file);
const width = imageBitMap.width;
const height = imageBitMap.height;
// @ts-expect-error imageBitMap
const canvas = resizeImage.resize2Canvas(imageBitMap, width, height);
async function resizeRecursiveAsync(
img: { width: number; height: number },
compressionRatio = COMPRESSION_RATIO,
depth = 0,
): Promise<unknown> {
const data = resizeImage.resize(
// @ts-expect-error canvas
canvas,
img.width / compressionRatio,
img.height / compressionRatio,
resizeImage.JPEG,
);
const newFile = await fetch(data)
.then((res) => res.blob())
.then((blob) => {
const f = new File([blob], "File name", {
type: "image/jpg",
});
return f;
});
console.log("file", newFile);
// const stepMessage = `Step ${depth + 1}`;
// const sizeMessage = `size = ${file.size} bytes`;
// const compressionRatioMessage = `compressionRatio = ${compressionRatio}`;
// console.log(`${stepMessage} ${sizeMessage} ${compressionRatioMessage}`);
if (newFile.size < ONE_MEGABYTE) {
return newFile;
}
if (depth > 5) {
// console.log("start");
throw new Error("recursion depth exceeded");
}
return new Promise((resolve) => {
// eslint-disable-next-line no-promise-executor-return
return resolve(newFile);
}).then(() => resizeRecursiveAsync(img, compressionRatio + 1, depth + 1));
}
return resizeRecursiveAsync(
{ width, height },
file.size > ONE_MEGABYTE ? COMPRESSION_RATIO : NO_COMPRESSION_RATIO,
);
};