frontPanel/src/ui_kit/Modal/utils/imageManipulation.ts

101 lines
2.7 KiB
TypeScript
Raw Normal View History

2023-12-16 17:04:05 +00:00
import { PixelCrop } from "react-image-crop";
export function getRotatedImageBlob(image: HTMLImageElement) {
2023-12-31 02:53:25 +00:00
return new Promise<Blob>((resolve, reject) => {
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
if (!ctx) return reject(new Error("No 2d context"));
2023-12-16 17:04:05 +00:00
2023-12-31 02:53:25 +00:00
canvas.width = image.naturalHeight;
canvas.height = image.naturalWidth;
2023-12-16 17:04:05 +00:00
2023-12-31 02:53:25 +00:00
ctx.translate(canvas.width / 2, canvas.height / 2);
ctx.rotate(Math.PI / 2);
ctx.drawImage(image, -canvas.height / 2, -canvas.width / 2);
2023-12-16 17:04:05 +00:00
2023-12-31 02:53:25 +00:00
canvas.toBlob((blob) => {
if (!blob) return reject(new Error("Failed to create blob"));
2023-12-16 17:04:05 +00:00
2023-12-31 02:53:25 +00:00
resolve(blob);
2023-12-16 17:04:05 +00:00
});
2023-12-31 02:53:25 +00:00
});
2023-12-16 17:04:05 +00:00
}
export function getCroppedImageBlob(image: HTMLImageElement, crop: PixelCrop) {
2023-12-31 02:53:25 +00:00
return new Promise<Blob>((resolve, reject) => {
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
if (!ctx) return reject(new Error("No 2d context"));
const scale = 1;
const scaleX = image.naturalWidth / image.width;
const scaleY = image.naturalHeight / image.height;
const pixelRatio = window.devicePixelRatio;
canvas.width = Math.floor(crop.width * scaleX * pixelRatio);
canvas.height = Math.floor(crop.height * scaleY * pixelRatio);
ctx.scale(pixelRatio, pixelRatio);
ctx.imageSmoothingQuality = "high";
const cropX = crop.x * scaleX;
const cropY = crop.y * scaleY;
const centerX = image.naturalWidth / 2;
const centerY = image.naturalHeight / 2;
ctx.translate(-cropX, -cropY);
ctx.translate(centerX, centerY);
ctx.scale(scale, scale);
ctx.translate(-centerX, -centerY);
ctx.drawImage(
image,
0,
0,
image.naturalWidth,
image.naturalHeight,
0,
0,
image.naturalWidth,
image.naturalHeight,
);
canvas.toBlob((blob) => {
if (!blob) return reject(new Error("Failed to create blob"));
resolve(blob);
2023-12-16 17:04:05 +00:00
});
2023-12-31 02:53:25 +00:00
});
2023-12-16 17:04:05 +00:00
}
2023-12-31 02:53:25 +00:00
export function getDarkenedAndResizedImageBlob(
image: HTMLImageElement,
scale: number,
darken: number,
) {
return new Promise<Blob>((resolve, reject) => {
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
if (!ctx) return reject(new Error("No 2d context"));
2023-12-16 17:04:05 +00:00
2023-12-31 02:53:25 +00:00
const width = Math.floor(image.naturalWidth * scale);
const height = Math.floor(image.naturalHeight * scale);
2023-12-16 17:04:05 +00:00
2023-12-31 02:53:25 +00:00
canvas.width = width;
canvas.height = height;
2023-12-16 17:04:05 +00:00
2023-12-31 02:53:25 +00:00
ctx.drawImage(image, 0, 0, width, height);
2023-12-16 17:04:05 +00:00
2023-12-31 02:53:25 +00:00
if (darken > 0) {
ctx.fillStyle = `rgba(0, 0, 0, ${darken})`;
ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height);
}
2023-12-16 17:04:05 +00:00
2023-12-31 02:53:25 +00:00
canvas.toBlob((blob) => {
if (!blob) return reject(new Error("Failed to create blob"));
2023-12-16 17:04:05 +00:00
2023-12-31 02:53:25 +00:00
resolve(blob);
2023-12-16 17:04:05 +00:00
});
2023-12-31 02:53:25 +00:00
});
}