mirror of
https://code.equilibrium.co.ao/ITO/doneit-web.git
synced 2026-04-19 04:57:52 +00:00
73 lines
2.5 KiB
TypeScript
73 lines
2.5 KiB
TypeScript
import { err, ok, Result } from "neverthrow";
|
|
|
|
/**
|
|
* Compresses an image represented as a Base64 string.
|
|
*
|
|
* This function resizes the image to fit within the specified maximum width and height while maintaining the aspect ratio.
|
|
* The image is then compressed to a JPEG format with the given quality level.
|
|
*
|
|
* @param base64String - The Base64 string of the image to be compressed.
|
|
* @param maxWidth - The maximum width of the compressed image. The aspect ratio is preserved.
|
|
* @param maxHeight - The maximum height of the compressed image. The aspect ratio is preserved.
|
|
* @param quality - The quality of the compressed image, ranging from 0 to 1, where 1 is the best quality.
|
|
*
|
|
* @returns A Promise that resolves to a `Result` containing either:
|
|
* - `ok` with the compressed image as a Base64 string, or
|
|
* - `err` with an error if the image fails to load or compress.
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* compressImageBase64('data:image/png;base64,...', 800, 600, 0.8)
|
|
* .then(result => {
|
|
* if (result.isOk()) {
|
|
* console.log('Compressed image:', result.value);
|
|
* } else {
|
|
* console.error('Error compressing image:', result.error);
|
|
* }
|
|
* });
|
|
* ```
|
|
*/
|
|
export function compressImageBase64(base64String: string, maxWidth: number, maxHeight: number, quality: number): Promise<Result<string, any>> {
|
|
return new Promise((resolve, reject) => {
|
|
const image = new Image();
|
|
image.src = base64String;
|
|
|
|
image.onload = async () => {
|
|
const canvas = document.createElement('canvas');
|
|
let newWidth = image.width;
|
|
let newHeight = image.height;
|
|
|
|
if (newWidth > maxWidth) {
|
|
newHeight *= maxWidth / newWidth;
|
|
newWidth = maxWidth;
|
|
}
|
|
|
|
if (newHeight > maxHeight) {
|
|
newWidth *= maxHeight / newHeight;
|
|
newHeight = maxHeight;
|
|
}
|
|
|
|
canvas.width = newWidth;
|
|
canvas.height = newHeight;
|
|
|
|
const context = canvas.getContext('2d');
|
|
context?.drawImage(image, 0, 0, newWidth, newHeight);
|
|
|
|
const compressedBase64 = canvas.toDataURL('image/jpeg', quality);
|
|
|
|
// Calculate the compression percentage
|
|
const originalSize = base64String.length;
|
|
const compressedSize = compressedBase64.length;
|
|
const compressionPercentage = ((originalSize - compressedSize) / originalSize) * 100;
|
|
|
|
console.log(`Compression achieved: ${compressionPercentage.toFixed(2)}%`);
|
|
|
|
resolve(ok(compressedBase64));
|
|
};
|
|
|
|
image.onerror = (error) => {
|
|
resolve(err(error));
|
|
};
|
|
});
|
|
}
|