UNPKG

@canvacord/beta

Version:

Simple & easy to use image manipulation module for beginners.

267 lines (266 loc) 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()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.Photoshop = void 0; const canvas_1 = require("@napi-rs/canvas"); const Util_1 = require("../Utils/Util"); const Sketch_1 = require("../include/Sketch"); const loadImage_1 = require("../Utils/loadImage"); /** * Basic photo editing */ class Photoshop { constructor() { throw new Error('Cannot instantiate static class'); } static blur(image, pixels) { return __awaiter(this, void 0, void 0, function* () { if (!image) throw new Error('Image was not provided!'); const img = yield Util_1.Util.loadImage(image); const canvas = canvas_1.createCanvas(img.width, img.height); const ctx = canvas.getContext('2d'); // experiment // https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/filter // currently not supported ctx.filter = `blur(${pixels !== null && pixels !== void 0 ? pixels : 0}px)`; ctx.drawImage(img, 0, 0, canvas.width, canvas.height); return yield canvas.png(); }); } static brighten(img, amount) { return __awaiter(this, void 0, void 0, function* () { amount !== null && amount !== void 0 ? amount : (amount = 50); const image = yield Util_1.Util.loadImage(img); const canvas = canvas_1.createCanvas(image.width, image.height); const ctx = canvas.getContext('2d'); ctx.drawImage(image, 0, 0); const imgData = ctx.getImageData(0, 0, canvas.width, canvas.height); for (let i = 0; i < imgData.data.length; i += 4) { imgData.data[i] += amount; imgData.data[i + 1] += amount; imgData.data[i + 2] += amount; } ctx.putImageData(imgData, 0, 0); return yield canvas.png(); }); } static darken(img, amount) { return __awaiter(this, void 0, void 0, function* () { return yield Photoshop.brighten(img, -amount); }); } static greyscale(img) { return __awaiter(this, void 0, void 0, function* () { const image = yield Util_1.Util.loadImage(img); const canvas = canvas_1.createCanvas(image.width, image.height); const ctx = canvas.getContext('2d'); ctx.drawImage(image, 0, 0); const imgData = ctx.getImageData(0, 0, canvas.width, canvas.height); for (let i = 0; i < imgData.data.length; i += 4) { const brightness = 0.34 * imgData.data[i] + 0.5 * imgData.data[i + 1] + 0.16 * imgData.data[i + 2]; imgData.data[i] = brightness; imgData.data[i + 1] = brightness; imgData.data[i + 2] = brightness; } ctx.putImageData(imgData, 0, 0); return yield canvas.png(); }); } static grayscale(img) { return __awaiter(this, void 0, void 0, function* () { return yield Photoshop.greyscale(img); }); } static invert(img) { return __awaiter(this, void 0, void 0, function* () { const image = yield Util_1.Util.loadImage(img); const canvas = canvas_1.createCanvas(image.width, image.height); const ctx = canvas.getContext('2d'); ctx.drawImage(image, 0, 0); const imgData = ctx.getImageData(0, 0, canvas.width, canvas.height); for (let i = 0; i < imgData.data.length; i += 4) { imgData.data[i] = 255 - imgData.data[i]; imgData.data[i + 1] = 255 - imgData.data[i + 1]; imgData.data[i + 2] = 255 - imgData.data[i + 2]; imgData.data[i + 3] = 255; } ctx.putImageData(imgData, 0, 0); return yield canvas.png(); }); } static sepia(img) { return __awaiter(this, void 0, void 0, function* () { const image = yield Util_1.Util.loadImage(img); const canvas = canvas_1.createCanvas(image.width, image.height); const ctx = canvas.getContext('2d'); ctx.drawImage(image, 0, 0); const imgData = ctx.getImageData(0, 0, canvas.width, canvas.height); for (let i = 0; i < imgData.data.length; i += 4) { imgData.data[i] = imgData.data[i] * 0.393 + imgData.data[i + 1] * 0.769 + imgData.data[i + 2] * 0.189; imgData.data[i + 1] = imgData.data[i] * 0.349 + imgData.data[i + 1] * 0.686 + imgData.data[i + 2] * 0.168; imgData.data[i + 2] = imgData.data[i] * 0.272 + imgData.data[i + 1] * 0.534 + imgData.data[i + 2] * 0.131; } ctx.putImageData(imgData, 0, 0); return yield canvas.png(); }); } static threshold(img, amount) { return __awaiter(this, void 0, void 0, function* () { const image = yield Util_1.Util.loadImage(img); const canvas = canvas_1.createCanvas(image.width, image.height); const ctx = canvas.getContext('2d'); ctx.drawImage(image, 0, 0); const imgData = ctx.getImageData(0, 0, canvas.width, canvas.height); for (let i = 0; i < imgData.data.length; i += 4) { const r = imgData.data[i]; const g = imgData.data[i + 1]; const b = imgData.data[i + 2]; const v = 0.2126 * r + 0.7152 * g + 0.0722 * b >= amount ? 255 : 0; imgData.data[i] = imgData.data[i + 1] = imgData.data[i + 2] = v; } ctx.putImageData(imgData, 0, 0); return yield canvas.png(); }); } static circle(image) { return __awaiter(this, void 0, void 0, function* () { if (!image) throw new Error('Image was not provided!'); const img = yield Util_1.Util.loadImage(image); const canvas = canvas_1.createCanvas(img.width, img.height); const ctx = canvas.getContext('2d'); ctx.drawImage(img, 0, 0); ctx.globalCompositeOperation = 'destination-in'; ctx.beginPath(); ctx.arc(canvas.width / 2, canvas.height / 2, canvas.height / 2, 0, Math.PI * 2); ctx.closePath(); ctx.fill(); return yield canvas.png(); }); } static convolute(ctx, canvas, matrix, opaque) { return __awaiter(this, void 0, void 0, function* () { const side = Math.round(Math.sqrt(matrix.length)); const halfSide = Math.floor(side / 2); const pixels = ctx.getImageData(0, 0, canvas.width, canvas.height); const src = pixels.data; const sw = pixels.width; const sh = pixels.height; const w = sw; const h = sh; const output = ctx.getImageData(0, 0, canvas.width, canvas.height); const dst = output.data; const alphaFac = opaque ? 1 : 0; for (let y = 0; y < h; y++) { for (let x = 0; x < w; x++) { const sy = y; const sx = x; const dstOff = (y * w + x) * 4; let r = 0; let g = 0; let b = 0; let a = 0; for (let cy = 0; cy < side; cy++) { for (let cx = 0; cx < side; cx++) { const scy = sy + cy - halfSide; const scx = sx + cx - halfSide; if (scy >= 0 && scy < sh && scx >= 0 && scx < sw) { const srcOff = (scy * sw + scx) * 4; const wt = matrix[cy * side + cx]; r += src[srcOff] * wt; g += src[srcOff + 1] * wt; b += src[srcOff + 2] * wt; a += src[srcOff + 3] * wt; } } } dst[dstOff] = r; dst[dstOff + 1] = g; dst[dstOff + 2] = b; dst[dstOff + 3] = a + alphaFac * (255 - a); } } ctx.putImageData(output, 0, 0); return ctx; }); } static colorfy(image, color) { return __awaiter(this, void 0, void 0, function* () { if (!image) throw new Error('Image was not provided!'); const img = yield Util_1.Util.loadImage(image); const canvas = canvas_1.createCanvas(img.width, img.height); const ctx = canvas.getContext('2d'); ctx.drawImage(img, 0, 0, canvas.width, canvas.height); if (color) { ctx.globalCompositeOperation = 'color'; ctx.fillStyle = color; ctx.fillRect(0, 0, canvas.width, canvas.height); } return yield canvas.png(); }); } static colourfy(image, colour) { return __awaiter(this, void 0, void 0, function* () { return yield this.colorfy(image, colour); }); } static color(color, width, height) { return __awaiter(this, void 0, void 0, function* () { const canvas = canvas_1.createCanvas(width !== null && width !== void 0 ? width : 1024, height !== null && height !== void 0 ? height : 1024); const ctx = canvas.getContext('2d'); ctx.beginPath(); ctx.fillStyle = color !== null && color !== void 0 ? color : '#FFFFFF'; ctx.fillRect(0, 0, canvas.width, canvas.height); return yield canvas.png(); }); } static colour(colour, width, height) { return __awaiter(this, void 0, void 0, function* () { return this.color(colour, width, height); }); } static sketch(image, options = {}) { return __awaiter(this, void 0, void 0, function* () { return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () { if (!image) return reject(new Error("Source image was not provided")); const img = yield loadImage_1.loadImage(image); const canvas = canvas_1.createCanvas(img.width, img.height); const ctx = canvas.getContext("2d"); ctx.drawImage(img, 0, 0, canvas.width, canvas.height); Object.assign({}, { levelSteps: 6, lineAlpha: 0.1, lineThickness: 2, lineDensity: 0.5, lightness: 4, edgeBlurAmount: 2, edgeAmount: 0.5 }, options); const greyscale = Boolean(options.greyscale); delete options['greyscale']; Object.keys(options).filter((x) => x !== 'greyscale').forEach((fn) => { if (!Util_1.Util.is(options[fn], 'number') || options[fn] === Infinity) return reject(new TypeError(`options.${fn} must be a finite number, received ${fn}!`)); }); const sketcher = new Sketch_1.Sketcher(canvas.width, canvas.height); for (const prop of Object.keys(options)) { sketcher[prop] = options[prop]; } sketcher.transformCanvas(canvas, greyscale) .whenReady(() => __awaiter(this, void 0, void 0, function* () { return resolve(yield canvas.png()); })); })); }); } } exports.Photoshop = Photoshop;