UNPKG

magica

Version:

ImageMagick for browser and Node.js, easy setup, high level API and Command Line Interface, including WASM binary for an easy setup.

328 lines 12.8 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const assert_1 = require("assert"); const cross_fetch_1 = __importDefault(require("cross-fetch")); const fs_1 = require("fs"); const misc_utils_of_mine_generic_1 = require("misc-utils-of-mine-generic"); const html_1 = require("../image/html"); const imageCompare_1 = require("../image/imageCompare"); const imageInfo_1 = require("../image/imageInfo"); const imageUtil_1 = require("../image/imageUtil"); const magickLoaded_1 = require("../imageMagick/magickLoaded"); const run_1 = require("../main/run"); const options_1 = require("../options"); const base64_1 = require("../util/base64"); const fileUtil_1 = require("../util/fileUtil"); const protected_1 = require("./protected"); /** * Default File implementation with utilities for creating from file system or urls. * * Also instances have utilities to cache and get image information like size, mimeType, image comparison, * interacting with HTML DOM, etc. */ class File { constructor(name, content, isProtected = false, url, width, height) { this.name = name; this.content = content; this.url = url; this.width = width; this.height = height; if (isProtected) { protected_1.protectFile(name); } } /** * Same as [info] but returning only the first image's data. */ infoOne() { return __awaiter(this, void 0, void 0, function* () { var i = yield this.info(); if (!i || !i.length) { throw new Error('Expected image info extract to work'); } return i[0]; }); } /** * Get image information, like geometry, important numbers, mimeType, etc. * The first time it calls `identify` command, but then it will cache ths value. */ info() { return new Promise(resolve => { if (this._info) { resolve(this._info); } else { imageInfo_1.imageInfo(this).then(data => { this._info = (data || []).map(i => i.image); resolve(this._info); }); } }); } size() { return __awaiter(this, void 0, void 0, function* () { if (this.width && this.height) { return { width: this.width, height: this.height }; } var i = yield this.infoOne(); this.width = i.geometry ? i.geometry.width : this.width; this.height = i.geometry ? i.geometry.height : this.height; return { width: this.width || 0, height: this.height || 0 }; }); } widthXHeight() { return __awaiter(this, void 0, void 0, function* () { if (this.width && this.height) { return `${this.width}x${this.height}`; } var s = yield this.size(); return `${s.width}x${s.height}`; }); } mimeType() { return __awaiter(this, void 0, void 0, function* () { var i = yield this.infoOne(); return i.mimeType; }); } pixel(x, y) { return __awaiter(this, void 0, void 0, function* () { if (this._pixels) { return imageUtil_1.rgbaToString(this._pixels[imageUtil_1.coordsToIndex(this.width, x, y)]); } return yield imageUtil_1.imagePixelColor(this, x, y); }); } rgba(x, y) { return __awaiter(this, void 0, void 0, function* () { yield this.pixelCalculate(); return this._pixels[imageUtil_1.coordsToIndex(this.width, x, y)]; }); } /** * it will compute all pixel colors so following [pixel] and [rgba] calls will be fast */ pixelCalculate() { return __awaiter(this, void 0, void 0, function* () { this._pixels = yield imageUtil_1.getPixels(this); }); } /** * Creates a DataUrl like `data:image/png;name=f.png;base64,` using given base64 content, mimeType and fileName. */ asDataUrl(mime) { return __awaiter(this, void 0, void 0, function* () { return File.toDataUrl(this, mime); }); } /** * Returns base64 representation of this image in an encoded format like PNG */ asBase64(file) { return File.toBase64(file); } /** * Returns base64 representation of this image in an encoded format like PNG */ equals(file) { return __awaiter(this, void 0, void 0, function* () { return yield imageCompare_1.imageCompare(this, file); }); } /** * Returns base64 representation of this image in an encoded format like PNG */ asArrayBuffer() { return __awaiter(this, void 0, void 0, function* () { return this.content.buffer; }); } asHTMLImageData() { return __awaiter(this, void 0, void 0, function* () { var d = yield this.asRGBAImageData(); return new ImageData(d.data, d.width, d.height); }); } asRGBAImageData() { return __awaiter(this, void 0, void 0, function* () { var size = yield this.size(); var { outputFiles } = this.name.endsWith('.rgba') && this.width && this.height ? { outputFiles: [this] } : yield run_1.run({ script: `convert ${yield this.sizeDepthArgs()} '${this.name}[0]' ${yield this.sizeDepthArgs(false)} output.rgba`, inputFiles: [this] }); return { data: new Uint8ClampedArray(outputFiles[0].content.buffer), width: size.width, height: size.height }; }); } sizeDepthArgs(onlyIfRGBA = true) { return __awaiter(this, void 0, void 0, function* () { return File.getSizeDepthArgs(this, onlyIfRGBA); }); } static getSizeDepthArgs(f, onlyIfRGBA = true) { return __awaiter(this, void 0, void 0, function* () { return (!onlyIfRGBA || f.name.endsWith('.rgba')) ? `-size ${yield f.widthXHeight()} -depth 8` : ''; }); } /** * Creates a DataUrl like `data:image/png;name=f.png;base64,` using given base64 content, mimeType and fileName. */ static toDataUrl(file, mime) { return __awaiter(this, void 0, void 0, function* () { return yield html_1.toDataUrl(file, mime); }); } /** * Creates a File from given url. In Node.js urls must be absolute!. */ static fromUrl(url, o = {}) { return __awaiter(this, void 0, void 0, function* () { try { const response = yield cross_fetch_1.default(url, o); return new File(o.name || misc_utils_of_mine_generic_1.getFileNameFromUrl(url), new Uint8ClampedArray(yield response.arrayBuffer()), o.protected, url); } catch (error) { console.error(error); return undefined; } }); } /** * Creates a File from given ArrayBuffer. */ static fromArrayBuffer(b, o = {}) { return __awaiter(this, void 0, void 0, function* () { const f = new File(o.name || 'unknown', new Uint8ClampedArray(b), o.protected); if (!o.name) { const info = yield f.infoOne(); return new File(info.format ? 'unammed.' + info.format.toLowerCase() : 'unknown', f.content, o.protected); } return f; }); } /** * Creates a File from given file system path. Only Node.js. */ static fromFile(f, o = {}) { if (!misc_utils_of_mine_generic_1.isNode()) { throw new Error('File.readFile() called in the browser.'); } try { return new File(o.name || misc_utils_of_mine_generic_1.basename(f), new Uint8ClampedArray(fs_1.readFileSync(f)), o.protected); } catch (error) { console.error(error); return undefined; } } /** * Returns the file content as plain string. This is useful to read the content of a .json or .txt file * but not for images or other binary file content. */ static asString(f) { return String.fromCharCode.apply(null, f.content); } /** * Returns base64 representation of this image in an encoded format like PNG */ static toBase64(file) { return base64_1.arrayBufferToBase64(file.content.buffer); } /** * Loads file from given base64 string. */ static fromBase64(base64, name) { return new File(name, Buffer.from(Base64.decode(base64), 'base64')); } /** * Loads file from given data url string. */ static fromDataUrl(dataUrl, name) { return File.fromBase64(base64_1.urlToBase64(dataUrl), name); } /** * Loads files from files in html input element of type "file". */ static fromHtmlFileInputElement(el) { return Promise.all(Array.from(el.files).map(file => new Promise((resolve, reject) => { var reader = new FileReader(); reader.addEventListener('loadend', e => resolve(new File(file.name, new Uint8ClampedArray(reader.result)))); reader.readAsArrayBuffer(file); }))); } /** * Shortcut for [resolve] that returns the first result. */ static resolveOne(files, options = { protected: false }) { return __awaiter(this, void 0, void 0, function* () { var a = yield File.resolve(files, options); return a.length > 0 ? a[0] : undefined; }); } /** * Given paths, urls or files it will try to load them all and return a list of File for those succeed. */ static resolve(files, options = { protected: false }) { return __awaiter(this, void 0, void 0, function* () { var fs = (misc_utils_of_mine_generic_1.asArray(files || [])).filter(misc_utils_of_mine_generic_1.notUndefined); var result = yield misc_utils_of_mine_generic_1.serial(fs.map(f => () => __awaiter(this, void 0, void 0, function* () { if (typeof f === 'string') { if (misc_utils_of_mine_generic_1.isNode() && fs_1.existsSync(f)) { return yield File.fromFile(f, options); } else { return yield File.fromUrl(f, options); } } else { assert_1.ok(ArrayBuffer.isView(f.content)); return f; } }))); return result.filter(misc_utils_of_mine_generic_1.notUndefined).map(File.asFile); }); } static isFile(f) { return !!f && !!f.name && !!f.content && typeof f.constructor !== 'undefined' && !!f.size && !!f.infoOne; } static asFile(f) { return File.isFile(f) ? f : typeof f === 'string' ? fileUtil_1.readFile(f, magickLoaded_1.getFS()) : new File(f.name, f.content); } static asPath(f) { return typeof f === 'string' ? f : f.name; } static fromRGBAImageData(d, name = 'img.rgba') { return new File(name, d.data, undefined, undefined, d.width, d.height); } static fromHTMLImageData(d, name = 'img.rgba') { return File.fromRGBAImageData(d, name); } static fileExists(f) { return __awaiter(this, void 0, void 0, function* () { const { FS } = yield magickLoaded_1.magickLoaded; FS.chdir(options_1.getOption('emscriptenNodeFsRoot')); return fileUtil_1.isDir(File.asPath(f), FS) || fileUtil_1.isFile(File.asPath(f), FS); }); } } exports.File = File; File.equals = (a, b) => File.asPath(a) !== File.asPath(b); //# sourceMappingURL=file.js.map