2024-07-16 20:28:05 +02:00
|
|
|
import shim from '@joplin/lib/shim';
|
|
|
|
import Logger from '@joplin/utils/Logger';
|
|
|
|
import ImageResizer from '@bam.tech/react-native-image-resizer';
|
2024-08-02 15:51:49 +02:00
|
|
|
import fileToImage from './fileToImage.web';
|
|
|
|
import FsDriverWeb from '../fs-driver/fs-driver-rn.web';
|
2024-07-16 20:28:05 +02:00
|
|
|
|
|
|
|
const logger = Logger.create('resizeImage');
|
|
|
|
|
|
|
|
type OutputFormat = 'PNG' | 'JPEG';
|
|
|
|
|
|
|
|
interface Options {
|
|
|
|
inputPath: string;
|
|
|
|
outputPath: string;
|
|
|
|
maxWidth: number;
|
|
|
|
maxHeight: number;
|
|
|
|
format: OutputFormat;
|
|
|
|
quality: number;
|
|
|
|
}
|
|
|
|
|
|
|
|
const resizeImage = async (options: Options) => {
|
2024-08-02 15:51:49 +02:00
|
|
|
if (shim.mobilePlatform() === 'web') {
|
|
|
|
const image = await fileToImage(options.inputPath);
|
|
|
|
try {
|
|
|
|
const canvas = document.createElement('canvas');
|
|
|
|
|
|
|
|
// Choose a scale factor such that the resized image fits within a
|
|
|
|
// maxWidth x maxHeight box.
|
|
|
|
const scale = Math.min(
|
|
|
|
options.maxWidth / image.image.width,
|
|
|
|
options.maxHeight / image.image.height,
|
|
|
|
);
|
|
|
|
canvas.width = image.image.width * scale;
|
|
|
|
canvas.height = image.image.height * scale;
|
|
|
|
|
|
|
|
const ctx = canvas.getContext('2d');
|
|
|
|
ctx.drawImage(image.image, 0, 0, canvas.width, canvas.height);
|
|
|
|
|
|
|
|
const blob = await new Promise<Blob>((resolve, reject) => {
|
|
|
|
try {
|
|
|
|
canvas.toBlob(
|
|
|
|
(blob) => resolve(blob),
|
|
|
|
`image/${options.format.toLowerCase()}`,
|
|
|
|
options.quality,
|
|
|
|
);
|
|
|
|
} catch (error) {
|
|
|
|
reject(error);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
await (shim.fsDriver() as FsDriverWeb).writeFile(
|
|
|
|
options.outputPath, await blob.arrayBuffer(), 'Buffer',
|
|
|
|
);
|
|
|
|
} finally {
|
|
|
|
image.free();
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
const resizedImage = await ImageResizer.createResizedImage(
|
|
|
|
options.inputPath,
|
|
|
|
options.maxWidth,
|
|
|
|
options.maxHeight,
|
|
|
|
options.format,
|
|
|
|
options.quality, // quality
|
|
|
|
undefined, // rotation
|
|
|
|
undefined, // outputPath
|
|
|
|
true, // keep metadata
|
|
|
|
);
|
|
|
|
|
|
|
|
const resizedImagePath = resizedImage.uri;
|
|
|
|
logger.info('Resized image ', resizedImagePath);
|
|
|
|
logger.info(`Moving ${resizedImagePath} => ${options.outputPath}`);
|
|
|
|
|
|
|
|
await shim.fsDriver().copy(resizedImagePath, options.outputPath);
|
|
|
|
|
|
|
|
try {
|
|
|
|
await shim.fsDriver().unlink(resizedImagePath);
|
|
|
|
} catch (error) {
|
|
|
|
logger.warn('Error when unlinking cached file: ', error);
|
|
|
|
}
|
2024-07-16 20:28:05 +02:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
export default resizeImage;
|