Web: Shared: Image processing is moved to a general function.
This commit is contained in:
parent
4784395b02
commit
80b943c0e7
@ -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);
|
||||||
|
@ -75,4 +75,4 @@ const ImageEditor = ({
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export { ImageEditor, AvatarPreview };
|
export { ImageEditor, AvatarPreview, Dropzone };
|
||||||
|
@ -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,
|
||||||
|
);
|
||||||
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user