one
Version:
One is a React framework for web, iOS, and Android apps.
89 lines (88 loc) • 4.48 kB
JavaScript
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all) __defProp(target, name, {
get: all[name],
enumerable: true
});
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
get: () => from[key],
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
});
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var image_manipulator_exports = {};
__export(image_manipulator_exports, { ImageManipulator: () => ImageManipulator });
module.exports = __toCommonJS(image_manipulator_exports);
var import_nativeError = require("../nativeError.cjs");
function pixels(value, zero = false) {
if (!Number.isInteger(value) || value < (zero ? 0 : 1) || value > 1e5) throw new Error("ImageManipulator.transform: expected a whole pixel count");
return value;
}
function size(width, height) {
if (width > 1e4 || height > 1e4 || width * height > 25e6) throw new Error("ImageManipulator.transform: output is limited to 25 megapixels and 10,000 pixels per side");
}
async function transform(uri, options = {}) {
if (typeof window === "undefined") throw (0, import_nativeError.missingNativeBuild)("ImageManipulator.transform");
const { crop, resize, rotate = 0, flip, format = "jpeg", quality } = options;
if (![
"jpeg",
"png",
"webp"
].includes(format) || ![
0,
90,
180,
270
].includes(rotate)) throw new Error("ImageManipulator.transform: invalid format or rotation");
if (flip != null && flip !== "horizontal" && flip !== "vertical") throw new Error("ImageManipulator.transform: flip must be 'horizontal' or 'vertical'");
if (format === "png" && quality != null || quality != null && (!Number.isFinite(quality) || quality < 0 || quality > 1)) throw new Error("ImageManipulator.transform: quality applies only to JPEG or WebP and must be between 0 and 1");
const image = new window.Image();
image.crossOrigin = "anonymous";
image.src = uri;
await image.decode();
const x = pixels(crop?.x ?? 0, true), y = pixels(crop?.y ?? 0, true);
const cw = pixels(crop?.width ?? image.naturalWidth), ch = pixels(crop?.height ?? image.naturalHeight);
if (x + cw > image.naturalWidth || y + ch > image.naturalHeight) throw new Error("ImageManipulator.transform: crop must fit inside the source image");
if (resize && resize.width == null && resize.height == null) throw new Error("ImageManipulator.transform: resize needs a width or height");
let width = resize?.width == null ? cw : pixels(resize.width);
let height = resize?.height == null ? ch : pixels(resize.height);
if (resize?.width == null && resize?.height != null) width = Math.max(1, Math.round(cw * height / ch));
if (resize?.height == null && resize?.width != null) height = Math.max(1, Math.round(ch * width / cw));
size(width, height);
const canvas = document.createElement("canvas");
canvas.width = rotate === 90 || rotate === 270 ? height : width;
canvas.height = rotate === 90 || rotate === 270 ? width : height;
const context = canvas.getContext("2d");
if (!context) throw new Error("ImageManipulator.transform: canvas is unavailable");
context.translate(canvas.width / 2, canvas.height / 2);
if (flip === "horizontal") context.scale(-1, 1);
else if (flip === "vertical") context.scale(1, -1);
context.rotate(rotate * Math.PI / 180);
let source = image;
if (crop) {
const cropped = document.createElement("canvas");
cropped.width = cw;
cropped.height = ch;
const cropContext = cropped.getContext("2d");
if (!cropContext) throw new Error("ImageManipulator.transform: canvas is unavailable");
cropContext.drawImage(image, x, y, cw, ch, 0, 0, cw, ch);
source = cropped;
}
context.drawImage(source, -width / 2, -height / 2, width, height);
const blob = await new Promise((resolve, reject) => canvas.toBlob((value) => value ? resolve(value) : reject(new Error("ImageManipulator.transform: encoding failed")), `image/${format}`, quality ?? .9));
return {
uri: URL.createObjectURL(blob),
width: canvas.width,
height: canvas.height,
size: blob.size
};
}
const ImageManipulator = Object.freeze({ transform });