初始化

This commit is contained in:
yziiy
2025-08-11 11:06:07 +08:00
parent 083bc37c00
commit 5607d11395
19772 changed files with 3108723 additions and 18 deletions

View File

@@ -0,0 +1,11 @@
# v0.9.3 (Tue Nov 26 2019)
#### 🐛 Bug Fix
- `@jimp/cli`, `@jimp/core`, `@jimp/custom`, `jimp`, `@jimp/plugin-blit`, `@jimp/plugin-blur`, `@jimp/plugin-circle`, `@jimp/plugin-color`, `@jimp/plugin-contain`, `@jimp/plugin-cover`, `@jimp/plugin-crop`, `@jimp/plugin-displace`, `@jimp/plugin-dither`, `@jimp/plugin-fisheye`, `@jimp/plugin-flip`, `@jimp/plugin-gaussian`, `@jimp/plugin-invert`, `@jimp/plugin-mask`, `@jimp/plugin-normalize`, `@jimp/plugin-print`, `@jimp/plugin-resize`, `@jimp/plugin-rotate`, `@jimp/plugin-scale`, `@jimp/plugin-shadow`, `@jimp/plugin-threshold`, `@jimp/plugins`, `@jimp/test-utils`, `@jimp/bmp`, `@jimp/gif`, `@jimp/jpeg`, `@jimp/png`, `@jimp/tiff`, `@jimp/types`, `@jimp/utils`
- Fix regeneratorRuntime errors [#815](https://github.com/oliver-moran/jimp/pull/815) ([@crutchcorn](https://github.com/crutchcorn) [@hipstersmoothie](https://github.com/hipstersmoothie))
#### Authors: 2
- Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
- Corbin Crutchley ([@crutchcorn](https://github.com/crutchcorn))

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.

View File

@@ -0,0 +1,34 @@
<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.
## Usage
Blits a source image on to this image
- @param {Jimp} src image to blit
- @param {number} x the x position to blit the image
- @param {number} y the y position to blit the image
- @param {number} srcx (optional) the x position from which to crop the source image
- @param {number} srcy (optional) the y position from which to crop the source image
- @param {number} srcw (optional) the width to which to crop the source image
- @param {number} srch (optional) the height to which to crop the source image
- @param {function(Error, Jimp)} cb (optional) a callback for when complete
```js
import jimp from 'jimp';
async function main() {
const image = await jimp.read('test/image.png');
const parrot = await jimp.read('test/party-parrot.png');
image.blit(parrot, x, y);
}
main();
```

View File

@@ -0,0 +1,99 @@
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
var _utils = require("@jimp/utils");
var _default = function _default() {
return {
/**
* Blits a source image on to this image
* @param {Jimp} src the source Jimp instance
* @param {number} x the x position to blit the image
* @param {number} y the y position to blit the image
* @param {number} srcx (optional) the x position from which to crop the source image
* @param {number} srcy (optional) the y position from which to crop the source image
* @param {number} srcw (optional) the width to which to crop the source image
* @param {number} srch (optional) the height to which to crop the source image
* @param {function(Error, Jimp)} cb (optional) a callback for when complete
* @returns {Jimp} this for chaining of methods
*/
blit: function blit(src, x, y, srcx, srcy, srcw, srch, cb) {
if (!(src instanceof this.constructor)) {
return _utils.throwError.call(this, 'The source must be a Jimp image', cb);
}
if (typeof x !== 'number' || typeof y !== 'number') {
return _utils.throwError.call(this, 'x and y must be numbers', cb);
}
if (typeof srcx === 'function') {
cb = srcx;
srcx = 0;
srcy = 0;
srcw = src.bitmap.width;
srch = src.bitmap.height;
} else if ((0, _typeof2["default"])(srcx) === (0, _typeof2["default"])(srcy) && (0, _typeof2["default"])(srcy) === (0, _typeof2["default"])(srcw) && (0, _typeof2["default"])(srcw) === (0, _typeof2["default"])(srch)) {
srcx = srcx || 0;
srcy = srcy || 0;
srcw = srcw || src.bitmap.width;
srch = srch || src.bitmap.height;
} else {
return _utils.throwError.call(this, 'srcx, srcy, srcw, srch must be numbers', cb);
} // 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);
var maxWidth = this.bitmap.width;
var maxHeight = this.bitmap.height;
var baseImage = this;
src.scanQuiet(srcx, srcy, srcw, srch, function (sx, sy, idx) {
var xOffset = x + sx - srcx;
var yOffset = y + sy - srcy;
if (xOffset >= 0 && yOffset >= 0 && maxWidth - xOffset > 0 && maxHeight - yOffset > 0) {
var dstIdx = baseImage.getPixelIndex(xOffset, yOffset);
var _src = {
r: this.bitmap.data[idx],
g: this.bitmap.data[idx + 1],
b: this.bitmap.data[idx + 2],
a: this.bitmap.data[idx + 3]
};
var dst = {
r: baseImage.bitmap.data[dstIdx],
g: baseImage.bitmap.data[dstIdx + 1],
b: baseImage.bitmap.data[dstIdx + 2],
a: baseImage.bitmap.data[dstIdx + 3]
};
baseImage.bitmap.data[dstIdx] = (_src.a * (_src.r - dst.r) - dst.r + 255 >> 8) + dst.r;
baseImage.bitmap.data[dstIdx + 1] = (_src.a * (_src.g - dst.g) - dst.g + 255 >> 8) + dst.g;
baseImage.bitmap.data[dstIdx + 2] = (_src.a * (_src.b - dst.b) - dst.b + 255 >> 8) + dst.b;
baseImage.bitmap.data[dstIdx + 3] = this.constructor.limit255(dst.a + _src.a);
}
});
if ((0, _utils.isNodePattern)(cb)) {
cb.call(this, null, this);
}
return this;
}
};
};
exports["default"] = _default;
module.exports = exports.default;
//# sourceMappingURL=index.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,98 @@
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
var _utils = require("@jimp/utils");
var _default = function _default() {
return {
/**
* Blits a source image on to this image
* @param {Jimp} src the source Jimp instance
* @param {number} x the x position to blit the image
* @param {number} y the y position to blit the image
* @param {number} srcx (optional) the x position from which to crop the source image
* @param {number} srcy (optional) the y position from which to crop the source image
* @param {number} srcw (optional) the width to which to crop the source image
* @param {number} srch (optional) the height to which to crop the source image
* @param {function(Error, Jimp)} cb (optional) a callback for when complete
* @returns {Jimp} this for chaining of methods
*/
blit: function blit(src, x, y, srcx, srcy, srcw, srch, cb) {
if (!(src instanceof this.constructor)) {
return _utils.throwError.call(this, 'The source must be a Jimp image', cb);
}
if (typeof x !== 'number' || typeof y !== 'number') {
return _utils.throwError.call(this, 'x and y must be numbers', cb);
}
if (typeof srcx === 'function') {
cb = srcx;
srcx = 0;
srcy = 0;
srcw = src.bitmap.width;
srch = src.bitmap.height;
} else if ((0, _typeof2["default"])(srcx) === (0, _typeof2["default"])(srcy) && (0, _typeof2["default"])(srcy) === (0, _typeof2["default"])(srcw) && (0, _typeof2["default"])(srcw) === (0, _typeof2["default"])(srch)) {
srcx = srcx || 0;
srcy = srcy || 0;
srcw = srcw || src.bitmap.width;
srch = srch || src.bitmap.height;
} else {
return _utils.throwError.call(this, 'srcx, srcy, srcw, srch must be numbers', cb);
} // 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);
var maxWidth = this.bitmap.width;
var maxHeight = this.bitmap.height;
var baseImage = this;
src.scanQuiet(srcx, srcy, srcw, srch, function (sx, sy, idx) {
var xOffset = x + sx - srcx;
var yOffset = y + sy - srcy;
if (xOffset >= 0 && yOffset >= 0 && maxWidth - xOffset > 0 && maxHeight - yOffset > 0) {
var dstIdx = baseImage.getPixelIndex(xOffset, yOffset);
var _src = {
r: this.bitmap.data[idx],
g: this.bitmap.data[idx + 1],
b: this.bitmap.data[idx + 2],
a: this.bitmap.data[idx + 3]
};
var dst = {
r: baseImage.bitmap.data[dstIdx],
g: baseImage.bitmap.data[dstIdx + 1],
b: baseImage.bitmap.data[dstIdx + 2],
a: baseImage.bitmap.data[dstIdx + 3]
};
baseImage.bitmap.data[dstIdx] = (_src.a * (_src.r - dst.r) - dst.r + 255 >> 8) + dst.r;
baseImage.bitmap.data[dstIdx + 1] = (_src.a * (_src.g - dst.g) - dst.g + 255 >> 8) + dst.g;
baseImage.bitmap.data[dstIdx + 2] = (_src.a * (_src.b - dst.b) - dst.b + 255 >> 8) + dst.b;
baseImage.bitmap.data[dstIdx + 3] = this.constructor.limit255(dst.a + _src.a);
}
});
if ((0, _utils.isNodePattern)(cb)) {
cb.call(this, null, this);
}
return this;
}
};
};
exports["default"] = _default;
//# sourceMappingURL=index.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,17 @@
import { Jimp, ImageCallback } from '@jimp/core';
interface Blit {
blit(src: Jimp, x: number, y: number, cb?: ImageCallback<this>): this;
blit(
src: Jimp,
x: number,
y: number,
srcx: number,
srcy: number,
srcw: number,
srch: number,
cb?: ImageCallback<this>
): this;
}
export default function(): Blit;

View File

@@ -0,0 +1,39 @@
{
"name": "@jimp/plugin-blit",
"version": "0.10.3",
"description": "Blit an image.",
"main": "dist/index.js",
"module": "es/index.js",
"types": "index.d.ts",
"scripts": {
"test": "cross-env BABEL_ENV=test mocha --require @babel/register",
"test:watch": "npm run test -- --reporter min --watch",
"test:coverage": "nyc npm run test",
"build": "npm run build:node:production && npm run build:module",
"build:watch": "npm run build:node:debug -- -- --watch --verbose",
"build:debug": "npm run build:node:debug",
"build:module": "cross-env BABEL_ENV=module babel src -d es --source-maps --config-file ../../babel.config.js",
"build:node": "babel src -d dist --source-maps --config-file ../../babel.config.js",
"build:node:debug": "cross-env BABEL_ENV=development npm run build:node",
"build:node:production": "cross-env BABEL_ENV=production npm run build:node"
},
"author": "",
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.7.2",
"@jimp/utils": "^0.10.3",
"core-js": "^3.4.1"
},
"devDependencies": {
"@jimp/custom": "^0.10.3",
"@jimp/jpeg": "^0.10.3",
"@jimp/test-utils": "^0.10.3"
},
"peerDependencies": {
"@jimp/custom": ">=0.3.5"
},
"publishConfig": {
"access": "public"
},
"gitHead": "37197106eae5c26231018dfdc0254422f6b43927"
}

View File

@@ -0,0 +1,105 @@
import { throwError, isNodePattern } from '@jimp/utils';
export default () => ({
/**
* Blits a source image on to this image
* @param {Jimp} src the source Jimp instance
* @param {number} x the x position to blit the image
* @param {number} y the y position to blit the image
* @param {number} srcx (optional) the x position from which to crop the source image
* @param {number} srcy (optional) the y position from which to crop the source image
* @param {number} srcw (optional) the width to which to crop the source image
* @param {number} srch (optional) the height to which to crop the source image
* @param {function(Error, Jimp)} cb (optional) a callback for when complete
* @returns {Jimp} this for chaining of methods
*/
blit(src, x, y, srcx, srcy, srcw, srch, cb) {
if (!(src instanceof this.constructor)) {
return throwError.call(this, 'The source must be a Jimp image', cb);
}
if (typeof x !== 'number' || typeof y !== 'number') {
return throwError.call(this, 'x and y must be numbers', cb);
}
if (typeof srcx === 'function') {
cb = srcx;
srcx = 0;
srcy = 0;
srcw = src.bitmap.width;
srch = src.bitmap.height;
} else if (
typeof srcx === typeof srcy &&
typeof srcy === typeof srcw &&
typeof srcw === typeof srch
) {
srcx = srcx || 0;
srcy = srcy || 0;
srcw = srcw || src.bitmap.width;
srch = srch || src.bitmap.height;
} else {
return throwError.call(
this,
'srcx, srcy, srcw, srch must be numbers',
cb
);
}
// 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 = this.bitmap.width;
const maxHeight = this.bitmap.height;
const baseImage = this;
src.scanQuiet(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 = baseImage.getPixelIndex(xOffset, yOffset);
const src = {
r: this.bitmap.data[idx],
g: this.bitmap.data[idx + 1],
b: this.bitmap.data[idx + 2],
a: this.bitmap.data[idx + 3]
};
const dst = {
r: baseImage.bitmap.data[dstIdx],
g: baseImage.bitmap.data[dstIdx + 1],
b: baseImage.bitmap.data[dstIdx + 2],
a: baseImage.bitmap.data[dstIdx + 3]
};
baseImage.bitmap.data[dstIdx] =
((src.a * (src.r - dst.r) - dst.r + 255) >> 8) + dst.r;
baseImage.bitmap.data[dstIdx + 1] =
((src.a * (src.g - dst.g) - dst.g + 255) >> 8) + dst.g;
baseImage.bitmap.data[dstIdx + 2] =
((src.a * (src.b - dst.b) - dst.b + 255) >> 8) + dst.b;
baseImage.bitmap.data[dstIdx + 3] = this.constructor.limit255(
dst.a + src.a
);
}
});
if (isNodePattern(cb)) {
cb.call(this, null, this);
}
return this;
}
});

View File

@@ -0,0 +1,235 @@
import { Jimp, mkJGD, getTestDir } from '@jimp/test-utils';
import jpeg from '@jimp/jpeg';
import configure from '@jimp/custom';
import blit from '../src';
const jimp = configure({ types: [jpeg], plugins: [blit] }, Jimp);
const testDir = getTestDir(__dirname);
describe('Blit over image', function() {
this.timeout(15000);
const targetJGD = mkJGD(
'▴▴▴▴▸▸▸▸',
'▴▴▴▴▸▸▸▸',
'▴▴▴▴▸▸▸▸',
'▴▴▴▴▸▸▸▸',
'▾▾▾▾◆◆◆◆',
'▾▾▾▾◆◆◆◆',
'▾▾▾▾◆◆◆◆',
'▾▾▾▾◆◆◆◆'
);
const srcJGD = mkJGD(
'□□□□□□',
'□▥▥▥▥□',
'□▥■■▥□',
'□▥■■▥□',
'□▥▥▥▥□',
'□□□□□□'
);
let targetImg;
let srcImg; // stores the Jimp instances of the JGD images above.
before(done => {
const img1 = jimp.read(targetJGD);
const img2 = jimp.read(srcJGD);
Promise.all([img1, img2])
.then(images => {
targetImg = images[0];
srcImg = images[1];
done();
})
.catch(done);
});
it('blit on top, with no crop', () => {
targetImg
.clone()
.blit(srcImg, 0, 0)
.getJGDSync()
.should.be.sameJGD(
mkJGD(
'□□□□□□▸▸',
'□▥▥▥▥□▸▸',
'□▥■■▥□▸▸',
'□▥■■▥□▸▸',
'□▥▥▥▥□◆◆',
'□□□□□□◆◆',
'▾▾▾▾◆◆◆◆',
'▾▾▾▾◆◆◆◆'
)
);
});
it('blit on middle, with no crop', () => {
targetImg
.clone()
.blit(srcImg, 1, 1)
.getJGDSync()
.should.be.sameJGD(
mkJGD(
'▴▴▴▴▸▸▸▸',
'▴□□□□□□▸',
'▴□▥▥▥▥□▸',
'▴□▥■■▥□▸',
'▾□▥■■▥□◆',
'▾□▥▥▥▥□◆',
'▾□□□□□□◆',
'▾▾▾▾◆◆◆◆'
)
);
});
it('blit on middle, with x,y crop', () => {
targetImg
.clone()
.blit(srcImg, 2, 2, 1, 1, 5, 5)
.getJGDSync()
.should.be.sameJGD(
mkJGD(
'▴▴▴▴▸▸▸▸',
'▴▴▴▴▸▸▸▸',
'▴▴▥▥▥▥□▸',
'▴▴▥■■▥□▸',
'▾▾▥■■▥□◆',
'▾▾▥▥▥▥□◆',
'▾▾□□□□□◆',
'▾▾▾▾◆◆◆◆'
)
);
});
it('blit on middle, with x,y,w,h crop', () => {
targetImg
.clone()
.blit(srcImg, 2, 2, 1, 1, 4, 4)
.getJGDSync()
.should.be.sameJGD(
mkJGD(
'▴▴▴▴▸▸▸▸',
'▴▴▴▴▸▸▸▸',
'▴▴▥▥▥▥▸▸',
'▴▴▥■■▥▸▸',
'▾▾▥■■▥◆◆',
'▾▾▥▥▥▥◆◆',
'▾▾▾▾◆◆◆◆',
'▾▾▾▾◆◆◆◆'
)
);
});
it('blit partially out, on top-left', () => {
targetImg
.clone()
.blit(srcImg, -1, -1)
.getJGDSync()
.should.be.sameJGD(
mkJGD(
'▥▥▥▥□▸▸▸',
'▥■■▥□▸▸▸',
'▥■■▥□▸▸▸',
'▥▥▥▥□▸▸▸',
'□□□□□◆◆◆',
'▾▾▾▾◆◆◆◆',
'▾▾▾▾◆◆◆◆',
'▾▾▾▾◆◆◆◆'
)
);
});
it('blit partially out, on bottom-right', () => {
targetImg
.clone()
.blit(srcImg, 3, 3)
.getJGDSync()
.should.be.sameJGD(
mkJGD(
'▴▴▴▴▸▸▸▸',
'▴▴▴▴▸▸▸▸',
'▴▴▴▴▸▸▸▸',
'▴▴▴□□□□□',
'▾▾▾□▥▥▥▥',
'▾▾▾□▥■■▥',
'▾▾▾□▥■■▥',
'▾▾▾□▥▥▥▥'
)
);
});
it('blit alpha', async () => {
const expectedImg = await Jimp.read(testDir + '/images/blit-alpha.png');
const dice = await Jimp.read(testDir + '/images/dice.png');
const image = await Jimp.read(testDir + '/images/cops.jpg');
image
.blit(dice, 0, 0)
.bitmap.data.should.be.deepEqual(expectedImg.bitmap.data);
});
async function createCat(catNum, len) {
let imgHeight = 60;
const butt = await Jimp.read(testDir + '/images/cat_butt.png');
const head = await Jimp.read(testDir + '/images/cat_head.png');
const fuzz = await Jimp.read(testDir + '/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 = await Jimp.create(
butt.bitmap.width + head.bitmap.width + fuzz.bitmap.width * longCat,
imgHeight,
0x00000000
);
newImage.blit(butt, 0, 0, 0, cat, butt.bitmap.width, imgHeight);
for (let i = 0; i < longCat; i++) {
newImage.blit(
fuzz,
butt.bitmap.width + fuzz.bitmap.width * i,
0,
0,
cat,
fuzz.bitmap.width,
imgHeight
);
}
newImage.blit(
head,
butt.bitmap.width + fuzz.bitmap.width * longCat,
0,
0,
cat,
head.bitmap.width,
imgHeight
);
return newImage;
}
it('uses src params correctly', async () => {
const expectedSmall = await Jimp.read(
testDir + '/images/cat-results/small-cat.png'
);
const small = await createCat(0.3, 1);
small.bitmap.data.should.be.deepEqual(expectedSmall.bitmap.data);
const expectedMedium = await Jimp.read(
testDir + '/images/cat-results/medium-cat.png'
);
const medium = await createCat(0.6, 7);
medium.bitmap.data.should.be.deepEqual(expectedMedium.bitmap.data);
const expectedLarge = await Jimp.read(
testDir + '/images/cat-results/large-cat.png'
);
const large = await createCat(0.9, 20);
large.bitmap.data.should.be.deepEqual(expectedLarge.bitmap.data);
});
});

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 213 KiB