pica-resize-image
Version:
A resize image plugin for Pica
230 lines (228 loc) • 7.81 kB
JavaScript
var __create = Object.create;
var __getProtoOf = Object.getPrototypeOf;
var __defProp = Object.defineProperty;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __toESM = (mod, isNodeMode, target) => {
target = mod != null ? __create(__getProtoOf(mod)) : {};
const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
for (let key of __getOwnPropNames(mod))
if (!__hasOwnProp.call(to, key))
__defProp(to, key, {
get: () => mod[key],
enumerable: true
});
return to;
};
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
}) : x)(function(x) {
if (typeof require !== "undefined")
return require.apply(this, arguments);
throw Error('Dynamic require of "' + x + '" is not supported');
});
// src/index.ts
import Pica from "pica";
var heic2any = null;
if (typeof window !== "undefined") {
try {
heic2any = __require("heic2any");
if (heic2any && heic2any.default) {
heic2any = heic2any.default;
}
} catch (e) {
console.log("heic2any not available (will load dynamically if needed)");
}
}
var OUTPUT_TYPE = {
file: "file",
blob: "blob",
base64: "base64"
};
var MIME_TYPE = {
png: {
mimeType: "image/png",
extension: "png"
},
jpeg: {
mimeType: "image/jpeg",
extension: "jpeg"
},
webp: {
mimeType: "image/webp",
extension: "webp"
}
};
var isHEIC = (file) => {
const heicTypes = [
"image/heic",
"image/heif",
"image/heic-sequence",
"image/heif-sequence"
];
if (heicTypes.includes(file.type.toLowerCase())) {
return true;
}
const extension = file.name.split(".").pop()?.toLowerCase();
return extension === "heic" || extension === "heif";
};
var getHeic2any = async () => {
if (heic2any) {
console.log("heic2any available from top-level import");
return heic2any;
}
try {
console.log("Trying dynamic import of heic2any...");
const module = await import("heic2any");
const h2a = module.default || module;
console.log("heic2any loaded via dynamic import");
return h2a;
} catch (error) {
console.error("Failed to load heic2any:", error);
throw new Error("heic2any library not available. Please ensure it's installed: npm install heic2any");
}
};
var convertHEICToBlob = async (file) => {
try {
console.log("Converting HEIC to JPEG...");
const h2a = await getHeic2any();
const convertedBlob = await h2a({
blob: file,
toType: "image/jpeg",
quality: 0.9
});
console.log("HEIC conversion completed");
if (Array.isArray(convertedBlob)) {
return convertedBlob[0];
}
return convertedBlob;
} catch (error) {
console.error("HEIC conversion error:", error);
throw new Error(`Failed to convert HEIC image: ${error}`);
}
};
var coverImage = (image, options) => {
const targetRatio = options.width / options.height;
const imageRatio = image.width / image.height;
let cropWidth, cropHeight, cropX, cropY;
if (imageRatio > targetRatio) {
cropHeight = image.height;
cropWidth = image.height * targetRatio;
cropX = (image.width - cropWidth) / 2;
cropY = 0;
} else {
cropWidth = image.width;
cropHeight = image.width / targetRatio;
cropX = 0;
cropY = (image.height - cropHeight) / 2;
}
const tempCanvas = document.createElement("canvas");
const tempCtx = tempCanvas.getContext("2d");
tempCanvas.width = cropWidth;
tempCanvas.height = cropHeight;
tempCtx.drawImage(image, cropX, cropY, cropWidth, cropHeight, 0, 0, cropWidth, cropHeight);
const croppedImage = new Image;
croppedImage.src = tempCanvas.toDataURL();
return new Promise((resolve, reject) => {
croppedImage.onload = () => resolve(croppedImage);
croppedImage.onerror = (error) => reject(error);
});
};
var readFileBeforeResize = async (file, options) => {
console.log("readFileBeforeResize started:", file.name);
let fileToProcess = file;
if (isHEIC(file)) {
console.log("HEIC file detected, converting...");
const convertedBlob = await convertHEICToBlob(file);
fileToProcess = new File([convertedBlob], file.name.replace(/\.(heic|heif)$/i, ".jpg"), { type: "image/jpeg" });
console.log("HEIC converted to:", fileToProcess.name);
}
console.log("Creating image element...");
const canvas = document.createElement("canvas");
const image = new Image;
const objectUrl = URL.createObjectURL(fileToProcess);
image.src = objectUrl;
return new Promise((resolve, reject) => {
image.onload = async () => {
console.log("Image loaded successfully");
URL.revokeObjectURL(objectUrl);
if (!options) {
const percent = 100 / image.height;
canvas.width = percent * image.width;
canvas.height = 100;
return resolve({ from: image, to: canvas });
} else if (options.width && options.height && options.cover) {
const croppedImage = await coverImage(image, options);
canvas.width = options.width;
canvas.height = options.height;
return resolve({ from: croppedImage, to: canvas });
} else if (options.width && options.height) {
canvas.width = options.width;
canvas.height = options.height;
return resolve({ from: image, to: canvas });
} else if (options.width) {
const percent = options.width / image.width;
canvas.width = options.width;
canvas.height = percent * image.height;
return resolve({ from: image, to: canvas });
} else if (options.height) {
const percent = options.height / image.height;
canvas.width = percent * image.width;
canvas.height = options.height;
return resolve({ from: image, to: canvas });
}
};
image.onerror = (error) => {
URL.revokeObjectURL(objectUrl);
reject(error);
};
});
};
var blobToFile = (blob, mimeType) => {
const prefix = new Date().getTime();
const suffix = Math.random().toString(36).slice(2);
return new File([blob], `image-${prefix}-${suffix}.${mimeType.extension}`, {
type: mimeType.mimeType
});
};
var blobToBase64 = (blob) => {
return new Promise((resolve, reject) => {
const reader = new FileReader;
reader.onload = () => resolve(reader.result);
reader.onerror = reject;
reader.readAsDataURL(blob);
});
};
var resize = ({ from, to, mimeType, quality, output }) => {
const pica = Pica();
return pica.resize(from, to).then((result) => pica.toBlob(result, mimeType.mimeType, quality)).then((resizedBlob) => {
switch (output) {
case OUTPUT_TYPE.file:
return blobToFile(resizedBlob, mimeType);
case OUTPUT_TYPE.base64:
return blobToBase64(resizedBlob);
case OUTPUT_TYPE.blob:
return resizedBlob;
}
});
};
var resizeImage = async (image, options) => {
const { from, to } = await readFileBeforeResize(image, options);
const mimeType = options?.mimeType || MIME_TYPE.webp;
const quality = options?.quality || 1;
const output = options?.output || "file";
return resize({ from, to, mimeType, quality, output });
};
var resizeImages = async (images, options) => {
const mimeType = options?.mimeType || MIME_TYPE.webp;
const quality = options?.quality || 1;
const output = options?.output || "file";
const readImagesBeforeResize = await Promise.all(images.map((image) => readFileBeforeResize(image, options)));
return Promise.all(readImagesBeforeResize.map(({ from, to }) => resize({ from, to, mimeType, quality, output })));
};
export {
resizeImages,
resizeImage,
OUTPUT_TYPE,
MIME_TYPE
};