UNPKG

one

Version:

One is a React framework for web, iOS, and Android apps.

89 lines (88 loc) • 4.48 kB
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 });