| interface optionType { | ||
| imagePath: string; | ||
| x?: number | any; | ||
| y?: number | any; | ||
| width?: number | any; | ||
| height?: number | any; | ||
| borderRadius?: number | any; | ||
| circle?: boolean; | ||
| cropCenter?: boolean; | ||
| } | ||
| declare const cropImage: (option: optionType) => Promise<Buffer>; | ||
| export { cropImage }; |
| interface optionType { | ||
| imagePath: string; | ||
| x?: number | any; | ||
| y?: number | any; | ||
| width?: number | any; | ||
| height?: number | any; | ||
| borderRadius?: number | any; | ||
| circle?: boolean; | ||
| cropCenter?: boolean; | ||
| } | ||
| declare const cropImage: (option: optionType) => Promise<Buffer>; | ||
| export { cropImage }; |
| "use strict"; | ||
| 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 __async = (__this, __arguments, generator) => { | ||
| return new Promise((resolve, reject) => { | ||
| var fulfilled = (value) => { | ||
| try { | ||
| step(generator.next(value)); | ||
| } catch (e) { | ||
| reject(e); | ||
| } | ||
| }; | ||
| var rejected = (value) => { | ||
| try { | ||
| step(generator.throw(value)); | ||
| } catch (e) { | ||
| reject(e); | ||
| } | ||
| }; | ||
| var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected); | ||
| step((generator = generator.apply(__this, __arguments)).next()); | ||
| }); | ||
| }; | ||
| // src/index.ts | ||
| var src_exports = {}; | ||
| __export(src_exports, { | ||
| cropImage: () => cropImage | ||
| }); | ||
| module.exports = __toCommonJS(src_exports); | ||
| var import_canvas = require("@napi-rs/canvas"); | ||
| var cropImage = (option) => __async(void 0, null, function* () { | ||
| try { | ||
| const image = yield (0, import_canvas.loadImage)(option.imagePath); | ||
| if (!option.width) | ||
| option.width = image.width; | ||
| if (!option.height) | ||
| option.height = image.height; | ||
| const scaleWidth = option.width / image.width; | ||
| const scaleHeight = option.height / image.height; | ||
| const scaleFactor = Math.max(scaleWidth, scaleHeight); | ||
| const scaledWidth = image.width * scaleFactor; | ||
| const scaledHeight = image.height * scaleFactor; | ||
| if (option.cropCenter) { | ||
| option.x = (option.width - scaledWidth) / 2; | ||
| option.y = (option.height - scaledHeight) / 2; | ||
| } else { | ||
| option.x -= (option.width - image.width * scaleFactor) / 2; | ||
| option.y -= (option.height - image.height * scaleFactor) / 2; | ||
| } | ||
| const canvas = (0, import_canvas.createCanvas)(option.width, option.height); | ||
| const ctx = canvas.getContext("2d"); | ||
| if (option.circle) { | ||
| ctx.beginPath(); | ||
| ctx.arc(option.width / 2, option.height / 2, Math.min(option.width, option.height) / 2, 0, Math.PI * 2); | ||
| ctx.closePath(); | ||
| ctx.clip(); | ||
| } else if (option.borderRadius > 0) { | ||
| ctx.beginPath(); | ||
| ctx.moveTo(option.borderRadius, 0); | ||
| ctx.lineTo(option.width - option.borderRadius, 0); | ||
| ctx.quadraticCurveTo(option.width, 0, option.width, option.borderRadius); | ||
| ctx.lineTo(option.width, option.height - option.borderRadius); | ||
| ctx.quadraticCurveTo(option.width, option.height, option.width - option.borderRadius, option.height); | ||
| ctx.lineTo(option.borderRadius, option.height); | ||
| ctx.quadraticCurveTo(0, option.height, 0, option.height - option.borderRadius); | ||
| ctx.lineTo(0, option.borderRadius); | ||
| ctx.quadraticCurveTo(0, 0, option.borderRadius, 0); | ||
| ctx.closePath(); | ||
| ctx.clip(); | ||
| } | ||
| ctx.drawImage(image, option.x, option.y, scaledWidth, scaledHeight); | ||
| return canvas.toBuffer("image/png"); | ||
| } catch (e) { | ||
| throw new Error(e.message); | ||
| } | ||
| }); | ||
| // Annotate the CommonJS export names for ESM import in node: | ||
| 0 && (module.exports = { | ||
| cropImage | ||
| }); |
| var __async = (__this, __arguments, generator) => { | ||
| return new Promise((resolve, reject) => { | ||
| var fulfilled = (value) => { | ||
| try { | ||
| step(generator.next(value)); | ||
| } catch (e) { | ||
| reject(e); | ||
| } | ||
| }; | ||
| var rejected = (value) => { | ||
| try { | ||
| step(generator.throw(value)); | ||
| } catch (e) { | ||
| reject(e); | ||
| } | ||
| }; | ||
| var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected); | ||
| step((generator = generator.apply(__this, __arguments)).next()); | ||
| }); | ||
| }; | ||
| // src/index.ts | ||
| import { createCanvas, loadImage } from "@napi-rs/canvas"; | ||
| var cropImage = (option) => __async(void 0, null, function* () { | ||
| try { | ||
| const image = yield loadImage(option.imagePath); | ||
| if (!option.width) | ||
| option.width = image.width; | ||
| if (!option.height) | ||
| option.height = image.height; | ||
| const scaleWidth = option.width / image.width; | ||
| const scaleHeight = option.height / image.height; | ||
| const scaleFactor = Math.max(scaleWidth, scaleHeight); | ||
| const scaledWidth = image.width * scaleFactor; | ||
| const scaledHeight = image.height * scaleFactor; | ||
| if (option.cropCenter) { | ||
| option.x = (option.width - scaledWidth) / 2; | ||
| option.y = (option.height - scaledHeight) / 2; | ||
| } else { | ||
| option.x -= (option.width - image.width * scaleFactor) / 2; | ||
| option.y -= (option.height - image.height * scaleFactor) / 2; | ||
| } | ||
| const canvas = createCanvas(option.width, option.height); | ||
| const ctx = canvas.getContext("2d"); | ||
| if (option.circle) { | ||
| ctx.beginPath(); | ||
| ctx.arc(option.width / 2, option.height / 2, Math.min(option.width, option.height) / 2, 0, Math.PI * 2); | ||
| ctx.closePath(); | ||
| ctx.clip(); | ||
| } else if (option.borderRadius > 0) { | ||
| ctx.beginPath(); | ||
| ctx.moveTo(option.borderRadius, 0); | ||
| ctx.lineTo(option.width - option.borderRadius, 0); | ||
| ctx.quadraticCurveTo(option.width, 0, option.width, option.borderRadius); | ||
| ctx.lineTo(option.width, option.height - option.borderRadius); | ||
| ctx.quadraticCurveTo(option.width, option.height, option.width - option.borderRadius, option.height); | ||
| ctx.lineTo(option.borderRadius, option.height); | ||
| ctx.quadraticCurveTo(0, option.height, 0, option.height - option.borderRadius); | ||
| ctx.lineTo(0, option.borderRadius); | ||
| ctx.quadraticCurveTo(0, 0, option.borderRadius, 0); | ||
| ctx.closePath(); | ||
| ctx.clip(); | ||
| } | ||
| ctx.drawImage(image, option.x, option.y, scaledWidth, scaledHeight); | ||
| return canvas.toBuffer("image/png"); | ||
| } catch (e) { | ||
| throw new Error(e.message); | ||
| } | ||
| }); | ||
| export { | ||
| cropImage | ||
| }; |
+24
-11
| { | ||
| "name": "cropify", | ||
| "types": "./index.d.ts", | ||
| "version": "1.0.9-beta.0", | ||
| "description": "Crop and round image corners seamlessly.", | ||
| "version": "1.0.8", | ||
| "main": "index.js", | ||
| "main": "./dist/index.js", | ||
| "module": "./dist/index.mjs", | ||
| "types": "./dist/index.d.ts", | ||
| "exports": { | ||
| ".": { | ||
| "require": "./dist/index.js", | ||
| "import": "./dist/index.mjs", | ||
| "types": "./dist/index.d.ts" | ||
| } | ||
| }, | ||
| "files": [ | ||
| "index.js", | ||
| "index.d.ts" | ||
| "dist" | ||
| ], | ||
| "scripts": { | ||
| "test": "echo \"Error: no test specified\" && exit 1" | ||
| "build": "tsup", | ||
| "deploy": "npm publish", | ||
| "deploy:beta": "npm publish --tag beta", | ||
| "test:m": "cd tests && node index.mjs", | ||
| "test:c": "cd tests && node index.js" | ||
| }, | ||
@@ -21,9 +32,8 @@ "keywords": [ | ||
| ], | ||
| "author": "FlameFace", | ||
| "author": "flameface", | ||
| "license": "MIT", | ||
| "dependencies": { | ||
| "canvas": "^2.11.2" | ||
| }, | ||
| "devDependencies": { | ||
| "@types/node": "^20.11.19" | ||
| "@types/node": "^20.11.28", | ||
| "tsup": "^8.0.2", | ||
| "typescript": "^5.4.2" | ||
| }, | ||
@@ -36,3 +46,6 @@ "repository": { | ||
| "url": "https://github.com/unburn/cropify/issues" | ||
| }, | ||
| "dependencies": { | ||
| "@napi-rs/canvas": "^0.1.51" | ||
| } | ||
| } |
-12
| interface cropOption { | ||
| imagePath: string, | ||
| x?: number, | ||
| y?: number, | ||
| width?: number, | ||
| height?: number, | ||
| borderRadius?: number, | ||
| circle?: boolean, | ||
| cropCenter?: boolean | ||
| } | ||
| export declare function cropImage(options: cropOption): Promise<Buffer>; |
-70
| const { createCanvas, loadImage } = require('canvas'); | ||
| async function cropImage({ | ||
| imagePath, | ||
| x, | ||
| y, | ||
| width, | ||
| height, | ||
| borderRadius = 0, | ||
| circle = false, | ||
| cropCenter = false | ||
| }) { | ||
| try { | ||
| const image = await loadImage(imagePath); | ||
| if (!width) width = image.width; | ||
| if (!height) height = image.height; | ||
| // Calculate scale factors | ||
| const scaleWidth = width / image.width; | ||
| const scaleHeight = height / image.height; | ||
| const scaleFactor = Math.max(scaleWidth, scaleHeight); | ||
| // Scaled dimensions | ||
| const scaledWidth = image.width * scaleFactor; | ||
| const scaledHeight = image.height * scaleFactor; | ||
| // Adjust x and y before scaling | ||
| if (cropCenter) { | ||
| x = (width - scaledWidth) / 2; | ||
| y = (height - scaledHeight) / 2; | ||
| } else { | ||
| x -= (width - image.width * scaleFactor) / 2; | ||
| y -= (height - image.height * scaleFactor) / 2; | ||
| } | ||
| // Create canvas | ||
| const canvas = createCanvas(width, height); | ||
| const ctx = canvas.getContext('2d'); | ||
| if (circle) { // Crop image into a circle | ||
| ctx.beginPath(); | ||
| ctx.arc(width / 2, height / 2, Math.min(width, height) / 2, 0, Math.PI * 2); | ||
| ctx.closePath(); | ||
| ctx.clip(); | ||
| } else if (borderRadius > 0) { // Clip with border radius if provided | ||
| ctx.beginPath(); | ||
| ctx.moveTo(borderRadius, 0); | ||
| ctx.lineTo(width - borderRadius, 0); | ||
| ctx.quadraticCurveTo(width, 0, width, borderRadius); | ||
| ctx.lineTo(width, height - borderRadius); | ||
| ctx.quadraticCurveTo(width, height, width - borderRadius, height); | ||
| ctx.lineTo(borderRadius, height); | ||
| ctx.quadraticCurveTo(0, height, 0, height - borderRadius); | ||
| ctx.lineTo(0, borderRadius); | ||
| ctx.quadraticCurveTo(0, 0, borderRadius, 0); | ||
| ctx.closePath(); | ||
| ctx.clip(); | ||
| } | ||
| // Draw image | ||
| ctx.drawImage(image, x, y, scaledWidth, scaledHeight); | ||
| return canvas.toBuffer("image/png"); | ||
| } catch (e) { | ||
| throw new Error(e.message) | ||
| } | ||
| } | ||
| module.exports = { cropImage }; |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
No tests
QualityPackage does not have any tests. This is a strong signal of a poorly maintained or low quality package.
Found 1 instance in 1 package
10027
86.38%6
50%178
157.97%3
200%+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed