Initial commit

This commit is contained in:
robert committed 2025-05-30 18:13:30 +08:00
commit e49726988c
5445 files changed
+1089914

No files matched your search

+8
View File
@@ -0,0 +1,8 @@
{
"extends": "../tsconfig.json",
"compilerOptions": {
"rootDir": "../src",
"module": "nodenext",
"moduleResolution": "nodenext"
}
}
+17
View File
@@ -0,0 +1,17 @@
{
"extends": "./build.json",
"include": [
"../src/**/*.ts",
"../src/**/*.cts",
"../src/**/*.tsx",
"../src/**/*.json"
],
"exclude": [
"../**/*.test.ts",
"../src/**/*.mts",
"../src/package.json"
],
"compilerOptions": {
"outDir": "../.tshy-build/commonjs"
}
}
+16
View File
@@ -0,0 +1,16 @@
{
"extends": "./build.json",
"include": [
"../src/**/*.ts",
"../src/**/*.mts",
"../src/**/*.tsx",
"../src/**/*.json"
],
"exclude": [
"../**/*.test.ts",
"../src/package.json"
],
"compilerOptions": {
"outDir": "../.tshy-build/esm"
}
}
+5
View File
@@ -0,0 +1,5 @@

> @jimp/plugin-blit@1.5.0 build /Users/andrewlisowski/Documents/jimp/plugins/plugin-blit
> tshy
+5
View File
@@ -0,0 +1,5 @@

> @jimp/plugin-blit@1.1.2 lint /Users/andrewlisowski/Documents/jimp/plugins/plugin-blit
> eslint .
+31
View File
@@ -0,0 +1,31 @@
> @jimp/plugin-blit@1.1.1 test:browser /Users/andrewlisowski/Documents/jimp/plugins/plugin-blit
> vitest --config vitest.config.browser.mjs "--watch=false" "--u"
 RUN  v1.4.0 /Users/andrewlisowski/Documents/jimp/plugins/plugin-blit
 Browser runner started at http://localhost:5176/
[?25l ✓ src/index.test.ts (6)
✓ Blit over image (6)
✓ blit on top, with no crop
✓ blit on middle, with no crop
✓ blit on middle, with x,y crop
✓ blit on middle, with x,y,w,h crop
✓ blit partially out, on top-left
✓ blit partially out, on bottom-right
 ✓ src/index.test.ts (6)
✓ Blit over image (6)
✓ blit on top, with no crop
✓ blit on middle, with no crop
✓ blit on middle, with x,y crop
✓ blit on middle, with x,y,w,h crop
✓ blit partially out, on top-left
✓ blit partially out, on bottom-right
 Test Files  1 passed (1)
 Tests  6 passed (6)
 Start at  00:42:10
 Duration  6.50s (transform 0ms, setup 0ms, collect 308ms, tests 4ms, environment 0ms, prepare 0ms)
[?25h[?25h
File diff suppressed because it is too large. Load diff
+64
View File
@@ -0,0 +1,64 @@
# v1.4.0 (Sat Sep 07 2024)
#### 📝 Documentation
- Misc doc updates [#1334](https://github.com/jimp-dev/jimp/pull/1334) ([@hipstersmoothie](https://github.com/hipstersmoothie))
#### Authors: 1
- Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
---
# v1.1.3 (Mon Sep 02 2024)
#### 🐛 Bug Fix
- Update deps [#1319](https://github.com/jimp-dev/jimp/pull/1319) ([@hipstersmoothie](https://github.com/hipstersmoothie))
#### Authors: 1
- Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
---
# v1.1.0 (Sun Sep 01 2024)
#### ⚠️ Pushed to `main`
- upgrade tshy ([@hipstersmoothie](https://github.com/hipstersmoothie))
- update more docs ([@hipstersmoothie](https://github.com/hipstersmoothie))
#### Authors: 1
- Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
---
# v1.0.3 (Sat Aug 31 2024)
#### 🐛 Bug Fix
- Fix build [#1303](https://github.com/jimp-dev/jimp/pull/1303) ([@hipstersmoothie](https://github.com/hipstersmoothie))
#### ⚠️ Pushed to `main`
- add clean script ([@hipstersmoothie](https://github.com/hipstersmoothie))
#### Authors: 1
- Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
---
# v1.0.2 (Sat Aug 31 2024)
#### ⚠️ Pushed to `main`
- set side effects ([@hipstersmoothie](https://github.com/hipstersmoothie))
- fix versions ([@hipstersmoothie](https://github.com/hipstersmoothie))
- add publish config ([@hipstersmoothie](https://github.com/hipstersmoothie))
#### Authors: 1
- Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2018 Oliver Moran
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+10
View File
@@ -0,0 +1,10 @@
<div align="center">
<img width="200" height="200"
src="https://s3.amazonaws.com/pix.iemoji.com/images/emoji/apple/ios-11/256/crayon.png">
<h1>@jimp/plugin-blit</h1>
<p>Blit an image.</p>
</div>
> Blit - a data operation commonly used in computer graphics in which several bitmaps are combined into one using a boolean function.
[Read the docs](http://jimp-dev.github.io/jimp/api/jimp/classes/jimp#blit)
+118
View File
@@ -0,0 +1,118 @@
import { JimpClass } from "@jimp/types";
import { z } from "zod";
declare const BlitOptionsSchema: z.ZodUnion<[z.ZodObject<{
bitmap: z.ZodObject<{
data: z.ZodUnion<[z.ZodType<Buffer, z.ZodTypeDef, Buffer>, z.ZodType<Uint8Array, z.ZodTypeDef, Uint8Array>]>;
width: z.ZodNumber;
height: z.ZodNumber;
}, "strip", z.ZodTypeAny, {
data: Buffer | Uint8Array;
width: number;
height: number;
}, {
data: Buffer | Uint8Array;
width: number;
height: number;
}>;
}, "strip", z.ZodTypeAny, {
bitmap: {
data: Buffer | Uint8Array;
width: number;
height: number;
};
}, {
bitmap: {
data: Buffer | Uint8Array;
width: number;
height: number;
};
}>, z.ZodObject<{
src: z.ZodObject<{
bitmap: z.ZodObject<{
data: z.ZodUnion<[z.ZodType<Buffer, z.ZodTypeDef, Buffer>, z.ZodType<Uint8Array, z.ZodTypeDef, Uint8Array>]>;
width: z.ZodNumber;
height: z.ZodNumber;
}, "strip", z.ZodTypeAny, {
data: Buffer | Uint8Array;
width: number;
height: number;
}, {
data: Buffer | Uint8Array;
width: number;
height: number;
}>;
}, "strip", z.ZodTypeAny, {
bitmap: {
data: Buffer | Uint8Array;
width: number;
height: number;
};
}, {
bitmap: {
data: Buffer | Uint8Array;
width: number;
height: number;
};
}>;
/** the x position to blit the image */
x: z.ZodOptional<z.ZodNumber>;
/** the y position to blit the image */
y: z.ZodOptional<z.ZodNumber>;
/** the x position from which to crop the source image */
srcX: z.ZodOptional<z.ZodNumber>;
/** the y position from which to crop the source image */
srcY: z.ZodOptional<z.ZodNumber>;
/** the width to which to crop the source image */
srcW: z.ZodOptional<z.ZodNumber>;
/** the height to which to crop the source image */
srcH: z.ZodOptional<z.ZodNumber>;
}, "strip", z.ZodTypeAny, {
src: {
bitmap: {
data: Buffer | Uint8Array;
width: number;
height: number;
};
};
x?: number | undefined;
y?: number | undefined;
srcX?: number | undefined;
srcY?: number | undefined;
srcW?: number | undefined;
srcH?: number | undefined;
}, {
src: {
bitmap: {
data: Buffer | Uint8Array;
width: number;
height: number;
};
};
x?: number | undefined;
y?: number | undefined;
srcX?: number | undefined;
srcY?: number | undefined;
srcW?: number | undefined;
srcH?: number | undefined;
}>]>;
export type BlitOptions = z.infer<typeof BlitOptionsSchema>;
export declare const methods: {
/**
* Short for "bit-block transfer".
* It involves the transfer of a block of pixel data from one area of a computer's memory to another area, typically for the purpose of rendering images on the screen or manipulating them in various ways.
* It's a fundamental operation in computer graphics utilized in various applications, from operating systems to video games.
*
* @example
* ```ts
* import { Jimp } from "jimp";
*
* const image = await Jimp.read("test/image.png");
* const parrot = await Jimp.read("test/party-parrot.png");
*
* image.blit({ src: parrot, x: 10, y: 10 });
* ```
*/
blit<I extends JimpClass>(image: I, options: BlitOptions): I;
};
export {};
//# sourceMappingURL=index.d.ts.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAmB,MAAM,aAAa,CAAC;AAEzD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAoBxB,QAAA,MAAM,iBAAiB;;oCAEV,MAAM,gBAAe,MAAO;;;;cAK0B,MAAO;;;;cAAoF,MAAO;;;;;;cAClF,MAAO;;;;;;cAKvF,MACF;;;;;;;wCAZY,MAAM,gBAAe,MAAO;;;;kBAK0B,MAAO;;;;kBAAoF,MAAO;;;;;;kBAClF,MAAO;;;;;;kBAKvF,MACF;;;;;IA9BC,uCAAuC;;IAEvC,uCAAuC;;IAEvC,yDAAyD;;IAEzD,yDAAyD;;IAEzD,kDAAkD;;IAElD,mDAAmD;;;;;kBAc8B,MAAO;;;;;;;;;;;;;;kBAKvF,MACF;;;;;;;;;;;IAd6E,CAAC;AAE/E,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAE5D,eAAO,MAAM,OAAO;IAClB;;;;;;;;;;;;;;OAcG;SACE,CAAC,SAAS,SAAS,SAAS,CAAC,WAAW,WAAW;CAuEzD,CAAC"}
+92
View File
@@ -0,0 +1,92 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.methods = void 0;
const types_1 = require("@jimp/types");
const utils_1 = require("@jimp/utils");
const zod_1 = require("zod");
const BlitOptionsSchemaComplex = zod_1.z.object({
src: types_1.JimpClassSchema,
/** the x position to blit the image */
x: zod_1.z.number().optional(),
/** the y position to blit the image */
y: zod_1.z.number().optional(),
/** the x position from which to crop the source image */
srcX: zod_1.z.number().optional(),
/** the y position from which to crop the source image */
srcY: zod_1.z.number().optional(),
/** the width to which to crop the source image */
srcW: zod_1.z.number().optional(),
/** the height to which to crop the source image */
srcH: zod_1.z.number().optional(),
});
const BlitOptionsSchema = zod_1.z.union([types_1.JimpClassSchema, BlitOptionsSchemaComplex]);
exports.methods = {
/**
* Short for "bit-block transfer".
* It involves the transfer of a block of pixel data from one area of a computer's memory to another area, typically for the purpose of rendering images on the screen or manipulating them in various ways.
* It's a fundamental operation in computer graphics utilized in various applications, from operating systems to video games.
*
* @example
* ```ts
* import { Jimp } from "jimp";
*
* const image = await Jimp.read("test/image.png");
* const parrot = await Jimp.read("test/party-parrot.png");
*
* image.blit({ src: parrot, x: 10, y: 10 });
* ```
*/
blit(image, options) {
const parsed = BlitOptionsSchema.parse(options);
let {
// eslint-disable-next-line prefer-const
src, x = 0, y = 0, srcX = 0, srcY = 0, srcW = src.bitmap.width, srcH = src.bitmap.height, } = "bitmap" in parsed ? { src: parsed } : parsed;
if (!("bitmap" in src)) {
throw new Error("The source must be a Jimp image");
}
if (typeof x !== "number" || typeof y !== "number") {
throw new Error("x and y must be numbers");
}
// round input
x = Math.round(x);
y = Math.round(y);
// round input
srcX = Math.round(srcX);
srcY = Math.round(srcY);
srcW = Math.round(srcW);
srcH = Math.round(srcH);
const maxWidth = image.bitmap.width;
const maxHeight = image.bitmap.height;
(0, utils_1.scan)(src, srcX, srcY, srcW, srcH, function (sx, sy, idx) {
const xOffset = x + sx - srcX;
const yOffset = y + sy - srcY;
if (xOffset >= 0 &&
yOffset >= 0 &&
maxWidth - xOffset > 0 &&
maxHeight - yOffset > 0) {
const dstIdx = image.getPixelIndex(xOffset, yOffset);
const srcColor = {
r: src.bitmap.data[idx] || 0,
g: src.bitmap.data[idx + 1] || 0,
b: src.bitmap.data[idx + 2] || 0,
a: src.bitmap.data[idx + 3] || 0,
};
const dst = {
r: image.bitmap.data[dstIdx] || 0,
g: image.bitmap.data[dstIdx + 1] || 0,
b: image.bitmap.data[dstIdx + 2] || 0,
a: image.bitmap.data[dstIdx + 3] || 0,
};
image.bitmap.data[dstIdx] =
((srcColor.a * (srcColor.r - dst.r) - dst.r + 255) >> 8) + dst.r;
image.bitmap.data[dstIdx + 1] =
((srcColor.a * (srcColor.g - dst.g) - dst.g + 255) >> 8) + dst.g;
image.bitmap.data[dstIdx + 2] =
((srcColor.a * (srcColor.b - dst.b) - dst.b + 255) >> 8) + dst.b;
image.bitmap.data[dstIdx + 3] = (0, utils_1.limit255)(dst.a + srcColor.a);
}
});
return image;
},
};
//# sourceMappingURL=index.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
+3
View File
@@ -0,0 +1,3 @@
{
"type": "commonjs"
}
+118
View File
@@ -0,0 +1,118 @@
import { JimpClass } from "@jimp/types";
import { z } from "zod";
declare const BlitOptionsSchema: z.ZodUnion<[z.ZodObject<{
bitmap: z.ZodObject<{
data: z.ZodUnion<[z.ZodType<Buffer, z.ZodTypeDef, Buffer>, z.ZodType<Uint8Array, z.ZodTypeDef, Uint8Array>]>;
width: z.ZodNumber;
height: z.ZodNumber;
}, "strip", z.ZodTypeAny, {
data: Buffer | Uint8Array;
width: number;
height: number;
}, {
data: Buffer | Uint8Array;
width: number;
height: number;
}>;
}, "strip", z.ZodTypeAny, {
bitmap: {
data: Buffer | Uint8Array;
width: number;
height: number;
};
}, {
bitmap: {
data: Buffer | Uint8Array;
width: number;
height: number;
};
}>, z.ZodObject<{
src: z.ZodObject<{
bitmap: z.ZodObject<{
data: z.ZodUnion<[z.ZodType<Buffer, z.ZodTypeDef, Buffer>, z.ZodType<Uint8Array, z.ZodTypeDef, Uint8Array>]>;
width: z.ZodNumber;
height: z.ZodNumber;
}, "strip", z.ZodTypeAny, {
data: Buffer | Uint8Array;
width: number;
height: number;
}, {
data: Buffer | Uint8Array;
width: number;
height: number;
}>;
}, "strip", z.ZodTypeAny, {
bitmap: {
data: Buffer | Uint8Array;
width: number;
height: number;
};
}, {
bitmap: {
data: Buffer | Uint8Array;
width: number;
height: number;
};
}>;
/** the x position to blit the image */
x: z.ZodOptional<z.ZodNumber>;
/** the y position to blit the image */
y: z.ZodOptional<z.ZodNumber>;
/** the x position from which to crop the source image */
srcX: z.ZodOptional<z.ZodNumber>;
/** the y position from which to crop the source image */
srcY: z.ZodOptional<z.ZodNumber>;
/** the width to which to crop the source image */
srcW: z.ZodOptional<z.ZodNumber>;
/** the height to which to crop the source image */
srcH: z.ZodOptional<z.ZodNumber>;
}, "strip", z.ZodTypeAny, {
src: {
bitmap: {
data: Buffer | Uint8Array;
width: number;
height: number;
};
};
x?: number | undefined;
y?: number | undefined;
srcX?: number | undefined;
srcY?: number | undefined;
srcW?: number | undefined;
srcH?: number | undefined;
}, {
src: {
bitmap: {
data: Buffer | Uint8Array;
width: number;
height: number;
};
};
x?: number | undefined;
y?: number | undefined;
srcX?: number | undefined;
srcY?: number | undefined;
srcW?: number | undefined;
srcH?: number | undefined;
}>]>;
export type BlitOptions = z.infer<typeof BlitOptionsSchema>;
export declare const methods: {
/**
* Short for "bit-block transfer".
* It involves the transfer of a block of pixel data from one area of a computer's memory to another area, typically for the purpose of rendering images on the screen or manipulating them in various ways.
* It's a fundamental operation in computer graphics utilized in various applications, from operating systems to video games.
*
* @example
* ```ts
* import { Jimp } from "jimp";
*
* const image = await Jimp.read("test/image.png");
* const parrot = await Jimp.read("test/party-parrot.png");
*
* image.blit({ src: parrot, x: 10, y: 10 });
* ```
*/
blit<I extends JimpClass>(image: I, options: BlitOptions): I;
};
export {};
//# sourceMappingURL=index.d.ts.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAmB,MAAM,aAAa,CAAC;AAEzD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAoBxB,QAAA,MAAM,iBAAiB;;oCAEV,MAAM,gBAAe,MAAO;;;;cAK0B,MAAO;;;;cAAoF,MAAO;;;;;;cAClF,MAAO;;;;;;cAKvF,MACF;;;;;;;wCAZY,MAAM,gBAAe,MAAO;;;;kBAK0B,MAAO;;;;kBAAoF,MAAO;;;;;;kBAClF,MAAO;;;;;;kBAKvF,MACF;;;;;IA9BC,uCAAuC;;IAEvC,uCAAuC;;IAEvC,yDAAyD;;IAEzD,yDAAyD;;IAEzD,kDAAkD;;IAElD,mDAAmD;;;;;kBAc8B,MAAO;;;;;;;;;;;;;;kBAKvF,MACF;;;;;;;;;;;IAd6E,CAAC;AAE/E,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAE5D,eAAO,MAAM,OAAO;IAClB;;;;;;;;;;;;;;OAcG;SACE,CAAC,SAAS,SAAS,SAAS,CAAC,WAAW,WAAW;CAuEzD,CAAC"}
+89
View File
@@ -0,0 +1,89 @@
import { JimpClassSchema } from "@jimp/types";
import { limit255, scan } from "@jimp/utils";
import { z } from "zod";
const BlitOptionsSchemaComplex = z.object({
src: JimpClassSchema,
/** the x position to blit the image */
x: z.number().optional(),
/** the y position to blit the image */
y: z.number().optional(),
/** the x position from which to crop the source image */
srcX: z.number().optional(),
/** the y position from which to crop the source image */
srcY: z.number().optional(),
/** the width to which to crop the source image */
srcW: z.number().optional(),
/** the height to which to crop the source image */
srcH: z.number().optional(),
});
const BlitOptionsSchema = z.union([JimpClassSchema, BlitOptionsSchemaComplex]);
export const methods = {
/**
* Short for "bit-block transfer".
* It involves the transfer of a block of pixel data from one area of a computer's memory to another area, typically for the purpose of rendering images on the screen or manipulating them in various ways.
* It's a fundamental operation in computer graphics utilized in various applications, from operating systems to video games.
*
* @example
* ```ts
* import { Jimp } from "jimp";
*
* const image = await Jimp.read("test/image.png");
* const parrot = await Jimp.read("test/party-parrot.png");
*
* image.blit({ src: parrot, x: 10, y: 10 });
* ```
*/
blit(image, options) {
const parsed = BlitOptionsSchema.parse(options);
let {
// eslint-disable-next-line prefer-const
src, x = 0, y = 0, srcX = 0, srcY = 0, srcW = src.bitmap.width, srcH = src.bitmap.height, } = "bitmap" in parsed ? { src: parsed } : parsed;
if (!("bitmap" in src)) {
throw new Error("The source must be a Jimp image");
}
if (typeof x !== "number" || typeof y !== "number") {
throw new Error("x and y must be numbers");
}
// round input
x = Math.round(x);
y = Math.round(y);
// round input
srcX = Math.round(srcX);
srcY = Math.round(srcY);
srcW = Math.round(srcW);
srcH = Math.round(srcH);
const maxWidth = image.bitmap.width;
const maxHeight = image.bitmap.height;
scan(src, srcX, srcY, srcW, srcH, function (sx, sy, idx) {
const xOffset = x + sx - srcX;
const yOffset = y + sy - srcY;
if (xOffset >= 0 &&
yOffset >= 0 &&
maxWidth - xOffset > 0 &&
maxHeight - yOffset > 0) {
const dstIdx = image.getPixelIndex(xOffset, yOffset);
const srcColor = {
r: src.bitmap.data[idx] || 0,
g: src.bitmap.data[idx + 1] || 0,
b: src.bitmap.data[idx + 2] || 0,
a: src.bitmap.data[idx + 3] || 0,
};
const dst = {
r: image.bitmap.data[dstIdx] || 0,
g: image.bitmap.data[dstIdx + 1] || 0,
b: image.bitmap.data[dstIdx + 2] || 0,
a: image.bitmap.data[dstIdx + 3] || 0,
};
image.bitmap.data[dstIdx] =
((srcColor.a * (srcColor.r - dst.r) - dst.r + 255) >> 8) + dst.r;
image.bitmap.data[dstIdx + 1] =
((srcColor.a * (srcColor.g - dst.g) - dst.g + 255) >> 8) + dst.g;
image.bitmap.data[dstIdx + 2] =
((srcColor.a * (srcColor.b - dst.b) - dst.b + 255) >> 8) + dst.b;
image.bitmap.data[dstIdx + 3] = limit255(dst.a + srcColor.a);
}
});
return image;
},
};
//# sourceMappingURL=index.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
+3
View File
@@ -0,0 +1,3 @@
{
"type": "module"
}
+2
View File
@@ -0,0 +1,2 @@
import shared from "@jimp/config-eslint/base.js";
export default [...shared];
+69
View File
@@ -0,0 +1,69 @@
{
"name": "@jimp/plugin-blit",
"version": "1.6.0",
"repository": "jimp-dev/jimp",
"engines": {
"node": ">=18"
},
"scripts": {
"lint": "eslint .",
"test": "vitest",
"test:browser": "vitest --config vitest.config.browser.mjs",
"build": "tshy",
"dev": "tshy --watch",
"clean": "rm -rf node_modules .tshy .tshy-build dist .turbo"
},
"author": "Andrew Lisowski <lisowski54@gmail.com>",
"license": "MIT",
"dependencies": {
"@jimp/types": "1.6.0",
"@jimp/utils": "1.6.0",
"zod": "^3.23.8"
},
"devDependencies": {
"@jimp/config-eslint": "1.6.0",
"@jimp/config-typescript": "1.6.0",
"@jimp/config-vitest": "1.6.0",
"@jimp/core": "1.6.0",
"@jimp/js-jpeg": "1.6.0",
"@jimp/js-png": "1.6.0",
"@jimp/test-utils": "1.6.0",
"@vitest/browser": "^2.0.5",
"eslint": "^9.9.1",
"tshy": "^3.0.2",
"typescript": "^5.5.4",
"vite-plugin-node-polyfills": "^0.22.0",
"vitest": "^2.0.5"
},
"tshy": {
"exclude": [
"**/*.test.ts"
],
"exports": {
"./package.json": "./package.json",
".": "./src/index.ts"
}
},
"exports": {
"./package.json": "./package.json",
".": {
"import": {
"types": "./dist/esm/index.d.ts",
"default": "./dist/esm/index.js"
},
"require": {
"types": "./dist/commonjs/index.d.ts",
"default": "./dist/commonjs/index.js"
}
}
},
"main": "./dist/commonjs/index.js",
"types": "./dist/commonjs/index.d.ts",
"type": "module",
"publishConfig": {
"access": "public"
},
"sideEffects": false,
"module": "./dist/esm/index.js",
"gitHead": "c88abe6046dccbdb6e4f5f00c3dd403c81d83515"
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 397 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

+145
View File
@@ -0,0 +1,145 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`Blit over image > blit on middle, with no crop 1`] = `
Visualization:
▴▴▴▴▸▸▸▸
▴□□□□□□▸
▴□▥▥▥▥□▸
▴□▥■■▥□▸
▾□▥■■▥□◆
▾□▥▥▥▥□◆
▾□□□□□□◆
▾▾▾▾◆◆◆◆
Data:
FF-00-00ᶠᶠ FF-00-00ᶠᶠ FF-00-00ᶠᶠ FF-00-00ᶠᶠ 00-FF-00ᶠᶠ 00-FF-00ᶠᶠ 00-FF-00ᶠᶠ 00-FF-00ᶠᶠ
FF-00-00ᶠᶠ FF-FF-FFᶠᶠ FF-FF-FFᶠᶠ FF-FF-FFᶠᶠ FF-FF-FFᶠᶠ FF-FF-FFᶠᶠ FF-FF-FFᶠᶠ 00-FF-00ᶠᶠ
FF-00-00ᶠᶠ FF-FF-FFᶠᶠ BF-BF-BFᶠᶠ BF-BF-BFᶠᶠ BF-BF-BFᶠᶠ BF-BF-BFᶠᶠ FF-FF-FFᶠᶠ 00-FF-00ᶠᶠ
FF-00-00ᶠᶠ FF-FF-FFᶠᶠ BF-BF-BFᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ BF-BF-BFᶠᶠ FF-FF-FFᶠᶠ 00-FF-00ᶠᶠ
00-00-FFᶠᶠ FF-FF-FFᶠᶠ BF-BF-BFᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ BF-BF-BFᶠᶠ FF-FF-FFᶠᶠ FF-FF-00ᶠᶠ
00-00-FFᶠᶠ FF-FF-FFᶠᶠ BF-BF-BFᶠᶠ BF-BF-BFᶠᶠ BF-BF-BFᶠᶠ BF-BF-BFᶠᶠ FF-FF-FFᶠᶠ FF-FF-00ᶠᶠ
00-00-FFᶠᶠ FF-FF-FFᶠᶠ FF-FF-FFᶠᶠ FF-FF-FFᶠᶠ FF-FF-FFᶠᶠ FF-FF-FFᶠᶠ FF-FF-FFᶠᶠ FF-FF-00ᶠᶠ
00-00-FFᶠᶠ 00-00-FFᶠᶠ 00-00-FFᶠᶠ 00-00-FFᶠᶠ FF-FF-00ᶠᶠ FF-FF-00ᶠᶠ FF-FF-00ᶠᶠ FF-FF-00ᶠᶠ
`;
exports[`Blit over image > blit on middle, with x,y crop 1`] = `
Visualization:
▴▴▴▴▸▸▸▸
▴▴▴▴▸▸▸▸
▴▴▥▥▥▥□▸
▴▴▥■■▥□▸
▾▾▥■■▥□◆
▾▾▥▥▥▥□◆
▾▾□□□□□◆
▾▾▾▾◆◆◆◆
Data:
FF-00-00ᶠᶠ FF-00-00ᶠᶠ FF-00-00ᶠᶠ FF-00-00ᶠᶠ 00-FF-00ᶠᶠ 00-FF-00ᶠᶠ 00-FF-00ᶠᶠ 00-FF-00ᶠᶠ
FF-00-00ᶠᶠ FF-00-00ᶠᶠ FF-00-00ᶠᶠ FF-00-00ᶠᶠ 00-FF-00ᶠᶠ 00-FF-00ᶠᶠ 00-FF-00ᶠᶠ 00-FF-00ᶠᶠ
FF-00-00ᶠᶠ FF-00-00ᶠᶠ BF-BF-BFᶠᶠ BF-BF-BFᶠᶠ BF-BF-BFᶠᶠ BF-BF-BFᶠᶠ FF-FF-FFᶠᶠ 00-FF-00ᶠᶠ
FF-00-00ᶠᶠ FF-00-00ᶠᶠ BF-BF-BFᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ BF-BF-BFᶠᶠ FF-FF-FFᶠᶠ 00-FF-00ᶠᶠ
00-00-FFᶠᶠ 00-00-FFᶠᶠ BF-BF-BFᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ BF-BF-BFᶠᶠ FF-FF-FFᶠᶠ FF-FF-00ᶠᶠ
00-00-FFᶠᶠ 00-00-FFᶠᶠ BF-BF-BFᶠᶠ BF-BF-BFᶠᶠ BF-BF-BFᶠᶠ BF-BF-BFᶠᶠ FF-FF-FFᶠᶠ FF-FF-00ᶠᶠ
00-00-FFᶠᶠ 00-00-FFᶠᶠ FF-FF-FFᶠᶠ FF-FF-FFᶠᶠ FF-FF-FFᶠᶠ FF-FF-FFᶠᶠ FF-FF-FFᶠᶠ FF-FF-00ᶠᶠ
00-00-FFᶠᶠ 00-00-FFᶠᶠ 00-00-FFᶠᶠ 00-00-FFᶠᶠ FF-FF-00ᶠᶠ FF-FF-00ᶠᶠ FF-FF-00ᶠᶠ FF-FF-00ᶠᶠ
`;
exports[`Blit over image > blit on middle, with x,y,w,h crop 1`] = `
Visualization:
▴▴▴▴▸▸▸▸
▴▴▴▴▸▸▸▸
▴▴▥▥▥▥▸▸
▴▴▥■■▥▸▸
▾▾▥■■▥◆◆
▾▾▥▥▥▥◆◆
▾▾▾▾◆◆◆◆
▾▾▾▾◆◆◆◆
Data:
FF-00-00ᶠᶠ FF-00-00ᶠᶠ FF-00-00ᶠᶠ FF-00-00ᶠᶠ 00-FF-00ᶠᶠ 00-FF-00ᶠᶠ 00-FF-00ᶠᶠ 00-FF-00ᶠᶠ
FF-00-00ᶠᶠ FF-00-00ᶠᶠ FF-00-00ᶠᶠ FF-00-00ᶠᶠ 00-FF-00ᶠᶠ 00-FF-00ᶠᶠ 00-FF-00ᶠᶠ 00-FF-00ᶠᶠ
FF-00-00ᶠᶠ FF-00-00ᶠᶠ BF-BF-BFᶠᶠ BF-BF-BFᶠᶠ BF-BF-BFᶠᶠ BF-BF-BFᶠᶠ 00-FF-00ᶠᶠ 00-FF-00ᶠᶠ
FF-00-00ᶠᶠ FF-00-00ᶠᶠ BF-BF-BFᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ BF-BF-BFᶠᶠ 00-FF-00ᶠᶠ 00-FF-00ᶠᶠ
00-00-FFᶠᶠ 00-00-FFᶠᶠ BF-BF-BFᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ BF-BF-BFᶠᶠ FF-FF-00ᶠᶠ FF-FF-00ᶠᶠ
00-00-FFᶠᶠ 00-00-FFᶠᶠ BF-BF-BFᶠᶠ BF-BF-BFᶠᶠ BF-BF-BFᶠᶠ BF-BF-BFᶠᶠ FF-FF-00ᶠᶠ FF-FF-00ᶠᶠ
00-00-FFᶠᶠ 00-00-FFᶠᶠ 00-00-FFᶠᶠ 00-00-FFᶠᶠ FF-FF-00ᶠᶠ FF-FF-00ᶠᶠ FF-FF-00ᶠᶠ FF-FF-00ᶠᶠ
00-00-FFᶠᶠ 00-00-FFᶠᶠ 00-00-FFᶠᶠ 00-00-FFᶠᶠ FF-FF-00ᶠᶠ FF-FF-00ᶠᶠ FF-FF-00ᶠᶠ FF-FF-00ᶠᶠ
`;
exports[`Blit over image > blit on top, with no crop 1`] = `
Visualization:
□□□□□□▸▸
□▥▥▥▥□▸▸
□▥■■▥□▸▸
□▥■■▥□▸▸
□▥▥▥▥□◆◆
□□□□□□◆◆
▾▾▾▾◆◆◆◆
▾▾▾▾◆◆◆◆
Data:
FF-FF-FFᶠᶠ FF-FF-FFᶠᶠ FF-FF-FFᶠᶠ FF-FF-FFᶠᶠ FF-FF-FFᶠᶠ FF-FF-FFᶠᶠ 00-FF-00ᶠᶠ 00-FF-00ᶠᶠ
FF-FF-FFᶠᶠ BF-BF-BFᶠᶠ BF-BF-BFᶠᶠ BF-BF-BFᶠᶠ BF-BF-BFᶠᶠ FF-FF-FFᶠᶠ 00-FF-00ᶠᶠ 00-FF-00ᶠᶠ
FF-FF-FFᶠᶠ BF-BF-BFᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ BF-BF-BFᶠᶠ FF-FF-FFᶠᶠ 00-FF-00ᶠᶠ 00-FF-00ᶠᶠ
FF-FF-FFᶠᶠ BF-BF-BFᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ BF-BF-BFᶠᶠ FF-FF-FFᶠᶠ 00-FF-00ᶠᶠ 00-FF-00ᶠᶠ
FF-FF-FFᶠᶠ BF-BF-BFᶠᶠ BF-BF-BFᶠᶠ BF-BF-BFᶠᶠ BF-BF-BFᶠᶠ FF-FF-FFᶠᶠ FF-FF-00ᶠᶠ FF-FF-00ᶠᶠ
FF-FF-FFᶠᶠ FF-FF-FFᶠᶠ FF-FF-FFᶠᶠ FF-FF-FFᶠᶠ FF-FF-FFᶠᶠ FF-FF-FFᶠᶠ FF-FF-00ᶠᶠ FF-FF-00ᶠᶠ
00-00-FFᶠᶠ 00-00-FFᶠᶠ 00-00-FFᶠᶠ 00-00-FFᶠᶠ FF-FF-00ᶠᶠ FF-FF-00ᶠᶠ FF-FF-00ᶠᶠ FF-FF-00ᶠᶠ
00-00-FFᶠᶠ 00-00-FFᶠᶠ 00-00-FFᶠᶠ 00-00-FFᶠᶠ FF-FF-00ᶠᶠ FF-FF-00ᶠᶠ FF-FF-00ᶠᶠ FF-FF-00ᶠᶠ
`;
exports[`Blit over image > blit partially out, on bottom-right 1`] = `
Visualization:
▴▴▴▴▸▸▸▸
▴▴▴▴▸▸▸▸
▴▴▴▴▸▸▸▸
▴▴▴□□□□□
▾▾▾□▥▥▥▥
▾▾▾□▥■■▥
▾▾▾□▥■■▥
▾▾▾□▥▥▥▥
Data:
FF-00-00ᶠᶠ FF-00-00ᶠᶠ FF-00-00ᶠᶠ FF-00-00ᶠᶠ 00-FF-00ᶠᶠ 00-FF-00ᶠᶠ 00-FF-00ᶠᶠ 00-FF-00ᶠᶠ
FF-00-00ᶠᶠ FF-00-00ᶠᶠ FF-00-00ᶠᶠ FF-00-00ᶠᶠ 00-FF-00ᶠᶠ 00-FF-00ᶠᶠ 00-FF-00ᶠᶠ 00-FF-00ᶠᶠ
FF-00-00ᶠᶠ FF-00-00ᶠᶠ FF-00-00ᶠᶠ FF-00-00ᶠᶠ 00-FF-00ᶠᶠ 00-FF-00ᶠᶠ 00-FF-00ᶠᶠ 00-FF-00ᶠᶠ
FF-00-00ᶠᶠ FF-00-00ᶠᶠ FF-00-00ᶠᶠ FF-FF-FFᶠᶠ FF-FF-FFᶠᶠ FF-FF-FFᶠᶠ FF-FF-FFᶠᶠ FF-FF-FFᶠᶠ
00-00-FFᶠᶠ 00-00-FFᶠᶠ 00-00-FFᶠᶠ FF-FF-FFᶠᶠ BF-BF-BFᶠᶠ BF-BF-BFᶠᶠ BF-BF-BFᶠᶠ BF-BF-BFᶠᶠ
00-00-FFᶠᶠ 00-00-FFᶠᶠ 00-00-FFᶠᶠ FF-FF-FFᶠᶠ BF-BF-BFᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ BF-BF-BFᶠᶠ
00-00-FFᶠᶠ 00-00-FFᶠᶠ 00-00-FFᶠᶠ FF-FF-FFᶠᶠ BF-BF-BFᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ BF-BF-BFᶠᶠ
00-00-FFᶠᶠ 00-00-FFᶠᶠ 00-00-FFᶠᶠ FF-FF-FFᶠᶠ BF-BF-BFᶠᶠ BF-BF-BFᶠᶠ BF-BF-BFᶠᶠ BF-BF-BFᶠᶠ
`;
exports[`Blit over image > blit partially out, on top-left 1`] = `
Visualization:
▥▥▥▥□▸▸▸
▥■■▥□▸▸▸
▥■■▥□▸▸▸
▥▥▥▥□▸▸▸
□□□□□◆◆◆
▾▾▾▾◆◆◆◆
▾▾▾▾◆◆◆◆
▾▾▾▾◆◆◆◆
Data:
BF-BF-BFᶠᶠ BF-BF-BFᶠᶠ BF-BF-BFᶠᶠ BF-BF-BFᶠᶠ FF-FF-FFᶠᶠ 00-FF-00ᶠᶠ 00-FF-00ᶠᶠ 00-FF-00ᶠᶠ
BF-BF-BFᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ BF-BF-BFᶠᶠ FF-FF-FFᶠᶠ 00-FF-00ᶠᶠ 00-FF-00ᶠᶠ 00-FF-00ᶠᶠ
BF-BF-BFᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ BF-BF-BFᶠᶠ FF-FF-FFᶠᶠ 00-FF-00ᶠᶠ 00-FF-00ᶠᶠ 00-FF-00ᶠᶠ
BF-BF-BFᶠᶠ BF-BF-BFᶠᶠ BF-BF-BFᶠᶠ BF-BF-BFᶠᶠ FF-FF-FFᶠᶠ 00-FF-00ᶠᶠ 00-FF-00ᶠᶠ 00-FF-00ᶠᶠ
FF-FF-FFᶠᶠ FF-FF-FFᶠᶠ FF-FF-FFᶠᶠ FF-FF-FFᶠᶠ FF-FF-FFᶠᶠ FF-FF-00ᶠᶠ FF-FF-00ᶠᶠ FF-FF-00ᶠᶠ
00-00-FFᶠᶠ 00-00-FFᶠᶠ 00-00-FFᶠᶠ 00-00-FFᶠᶠ FF-FF-00ᶠᶠ FF-FF-00ᶠᶠ FF-FF-00ᶠᶠ FF-FF-00ᶠᶠ
00-00-FFᶠᶠ 00-00-FFᶠᶠ 00-00-FFᶠᶠ 00-00-FFᶠᶠ FF-FF-00ᶠᶠ FF-FF-00ᶠᶠ FF-FF-00ᶠᶠ FF-FF-00ᶠᶠ
00-00-FFᶠᶠ 00-00-FFᶠᶠ 00-00-FFᶠᶠ 00-00-FFᶠᶠ FF-FF-00ᶠᶠ FF-FF-00ᶠᶠ FF-FF-00ᶠᶠ FF-FF-00ᶠᶠ
`;
Binary file not shown.

After

Width:  |  Height:  |  Size: 397 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

+86
View File
@@ -0,0 +1,86 @@
import { expect, test, describe } from "vitest";
import { createJimp } from "@jimp/core";
import jpeg from "@jimp/js-jpeg";
import png from "@jimp/js-png";
import "@jimp/test-utils/image-snapshot";
import { getTestImagePath } from "@jimp/test-utils";
import * as blit from "./index.js";
const Jimp = createJimp({ formats: [jpeg, png], plugins: [blit.methods] });
describe("Blit over image", function () {
test("blit alpha", async () => {
const dice = await Jimp.read(getTestImagePath("dice.png"));
const image = await Jimp.read(getTestImagePath("cops.jpg"));
const output = await image.blit({ src: dice }).getBuffer("image/png");
expect(output).toMatchImageSnapshot();
});
async function createCat(catNum: number, len: number) {
const imgHeight = 60;
const butt = await Jimp.read(__dirname + "/images/cat_butt.png");
const head = await Jimp.read(__dirname + "/images/cat_head.png");
const fuzz = await Jimp.read(__dirname + "/images/cat_fuzz.png");
let longCat = len;
longCat = longCat > 20 ? 20 : longCat;
longCat = longCat <= 1 ? 1 : longCat;
const cat =
Math.floor(catNum * (head.bitmap.height / imgHeight)) * imgHeight;
const newImage = new Jimp({
width:
butt.bitmap.width + head.bitmap.width + fuzz.bitmap.width * longCat,
height: imgHeight,
color: 0x00000000,
});
newImage.blit({
src: butt,
x: 0,
y: 0,
srcX: 0,
srcY: cat,
srcW: butt.bitmap.width,
srcH: imgHeight,
});
for (let i = 0; i < longCat; i++) {
newImage.blit({
src: fuzz,
x: butt.bitmap.width + fuzz.bitmap.width * i,
y: 0,
srcX: 0,
srcY: cat,
srcW: fuzz.bitmap.width,
srcH: imgHeight,
});
}
newImage.blit({
src: head,
x: butt.bitmap.width + fuzz.bitmap.width * longCat,
y: 0,
srcX: 0,
srcY: cat,
srcW: head.bitmap.width,
srcH: imgHeight,
});
return newImage;
}
test("uses src params correctly", async () => {
const small = await createCat(0.3, 1);
expect(await small.getBuffer("image/png")).toMatchImageSnapshot();
const medium = await createCat(0.6, 7);
expect(await medium.getBuffer("image/png")).toMatchImageSnapshot();
const large = await createCat(0.9, 20);
expect(await large.getBuffer("image/png")).toMatchImageSnapshot();
});
});
+72
View File
@@ -0,0 +1,72 @@
import { expect, test, describe } from "vitest";
import { createJimp } from "@jimp/core";
import jpeg from "@jimp/js-jpeg";
import png from "@jimp/js-png";
import { makeTestImage } from "@jimp/test-utils";
import * as blit from "./index.js";
const Jimp = createJimp({ formats: [jpeg, png], plugins: [blit.methods] });
describe("Blit over image", function () {
const targetImg = Jimp.fromBitmap(
makeTestImage(
"▴▴▴▴▸▸▸▸",
"▴▴▴▴▸▸▸▸",
"▴▴▴▴▸▸▸▸",
"▴▴▴▴▸▸▸▸",
"▾▾▾▾◆◆◆◆",
"▾▾▾▾◆◆◆◆",
"▾▾▾▾◆◆◆◆",
"▾▾▾▾◆◆◆◆",
),
);
// stores the Jimp instances of the JGD images above.
// prettier-ignore
const srcImg = Jimp.fromBitmap(makeTestImage(
"□□□□□□",
"□▥▥▥▥□",
"□▥■■▥□",
"□▥■■▥□",
"□▥▥▥▥□",
"□□□□□□"
));
test("blit on top, with no crop", () => {
expect(targetImg.clone().blit(srcImg)).toMatchSnapshot();
});
test("blit on middle, with no crop", () => {
expect(
targetImg.clone().blit({ src: srcImg, x: 1, y: 1 }),
).toMatchSnapshot();
});
test("blit on middle, with x,y crop", () => {
expect(
targetImg
.clone()
.blit({ src: srcImg, x: 2, y: 2, srcX: 1, srcY: 1, srcW: 5, srcH: 5 }),
).toMatchSnapshot();
});
test("blit on middle, with x,y,w,h crop", () => {
expect(
targetImg
.clone()
.blit({ src: srcImg, x: 2, y: 2, srcX: 1, srcY: 1, srcW: 4, srcH: 4 }),
).toMatchSnapshot();
});
test("blit partially out, on top-left", () => {
expect(
targetImg.clone().blit({ src: srcImg, x: -1, y: -1 }),
).toMatchSnapshot();
});
test("blit partially out, on bottom-right", () => {
expect(
targetImg.clone().blit({ src: srcImg, x: 3, y: 3 }),
).toMatchSnapshot();
});
});
+114
View File
@@ -0,0 +1,114 @@
import { JimpClass, JimpClassSchema } from "@jimp/types";
import { limit255, scan } from "@jimp/utils";
import { z } from "zod";
const BlitOptionsSchemaComplex = z.object({
src: JimpClassSchema,
/** the x position to blit the image */
x: z.number().optional(),
/** the y position to blit the image */
y: z.number().optional(),
/** the x position from which to crop the source image */
srcX: z.number().optional(),
/** the y position from which to crop the source image */
srcY: z.number().optional(),
/** the width to which to crop the source image */
srcW: z.number().optional(),
/** the height to which to crop the source image */
srcH: z.number().optional(),
});
type BlitOptionsComplex = z.infer<typeof BlitOptionsSchemaComplex>;
const BlitOptionsSchema = z.union([JimpClassSchema, BlitOptionsSchemaComplex]);
export type BlitOptions = z.infer<typeof BlitOptionsSchema>;
export const methods = {
/**
* Short for "bit-block transfer".
* It involves the transfer of a block of pixel data from one area of a computer's memory to another area, typically for the purpose of rendering images on the screen or manipulating them in various ways.
* It's a fundamental operation in computer graphics utilized in various applications, from operating systems to video games.
*
* @example
* ```ts
* import { Jimp } from "jimp";
*
* const image = await Jimp.read("test/image.png");
* const parrot = await Jimp.read("test/party-parrot.png");
*
* image.blit({ src: parrot, x: 10, y: 10 });
* ```
*/
blit<I extends JimpClass>(image: I, options: BlitOptions) {
const parsed = BlitOptionsSchema.parse(options);
let {
// eslint-disable-next-line prefer-const
src,
x = 0,
y = 0,
srcX = 0,
srcY = 0,
srcW = src.bitmap.width,
srcH = src.bitmap.height,
} = "bitmap" in parsed ? ({ src: parsed } as BlitOptionsComplex) : parsed;
if (!("bitmap" in src)) {
throw new Error("The source must be a Jimp image");
}
if (typeof x !== "number" || typeof y !== "number") {
throw new Error("x and y must be numbers");
}
// round input
x = Math.round(x);
y = Math.round(y);
// round input
srcX = Math.round(srcX);
srcY = Math.round(srcY);
srcW = Math.round(srcW);
srcH = Math.round(srcH);
const maxWidth = image.bitmap.width;
const maxHeight = image.bitmap.height;
scan(src, srcX, srcY, srcW, srcH, function (sx, sy, idx) {
const xOffset = x + sx - srcX;
const yOffset = y + sy - srcY;
if (
xOffset >= 0 &&
yOffset >= 0 &&
maxWidth - xOffset > 0 &&
maxHeight - yOffset > 0
) {
const dstIdx = image.getPixelIndex(xOffset, yOffset);
const srcColor = {
r: src.bitmap.data[idx] || 0,
g: src.bitmap.data[idx + 1] || 0,
b: src.bitmap.data[idx + 2] || 0,
a: src.bitmap.data[idx + 3] || 0,
};
const dst = {
r: image.bitmap.data[dstIdx] || 0,
g: image.bitmap.data[dstIdx + 1] || 0,
b: image.bitmap.data[dstIdx + 2] || 0,
a: image.bitmap.data[dstIdx + 3] || 0,
};
image.bitmap.data[dstIdx] =
((srcColor.a * (srcColor.r - dst.r) - dst.r + 255) >> 8) + dst.r;
image.bitmap.data[dstIdx + 1] =
((srcColor.a * (srcColor.g - dst.g) - dst.g + 255) >> 8) + dst.g;
image.bitmap.data[dstIdx + 2] =
((srcColor.a * (srcColor.b - dst.b) - dst.b + 255) >> 8) + dst.b;
image.bitmap.data[dstIdx + 3] = limit255(dst.a + srcColor.a);
}
});
return image;
},
};
+6
View File
@@ -0,0 +1,6 @@
{
"extends": "@jimp/config-typescript/base.json",
"compilerOptions": {
"outDir": "dist"
}
}
+3
View File
@@ -0,0 +1,3 @@
import config from "@jimp/config-vitest/browser";
export default config;