Initial commit
This commit is contained in:
commit
e49726988c
5445 files changed
+1089914
No files matched your search
+8
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"extends": "../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"rootDir": "../src",
|
||||
"module": "nodenext",
|
||||
"moduleResolution": "nodenext"
|
||||
}
|
||||
}
|
||||
+17
@@ -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
@@ -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
@@ -0,0 +1,5 @@
|
||||
|
||||
|
||||
> @jimp/plugin-resize@1.5.0 build /Users/andrewlisowski/Documents/jimp/plugins/plugin-resize
|
||||
> tshy
|
||||
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
|
||||
|
||||
> @jimp/plugin-resize@1.1.2 lint /Users/andrewlisowski/Documents/jimp/plugins/plugin-resize
|
||||
> eslint .
|
||||
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
|
||||
|
||||
> @jimp/plugin-resize@1.1.2 test:browser /Users/andrewlisowski/Documents/jimp/plugins/plugin-resize
|
||||
> vitest --config vitest.config.browser.mjs "--watch=false"
|
||||
|
||||
Re-optimizing dependencies because lockfile has changed
|
||||
|
||||
[7m[1m[36m RUN [39m[22m[27m [36mv2.0.5[39m [90m/Users/andrewlisowski/Documents/jimp/plugins/plugin-resize[39m
|
||||
[2m[32m Browser runner started at http://localhost:5173/[39m[22m
|
||||
|
||||
[2m1:39:23 AM[22m [36m[1m[vite][22m[39m [32m✨ new dependencies optimized: [33mvite-plugin-node-polyfills/shims/buffer, vite-plugin-node-polyfills/shims/global, vite-plugin-node-polyfills/shims/process, path[32m[39m
|
||||
[2m1:39:23 AM[22m [36m[1m[vite][22m[39m [32m✨ optimized dependencies changed. reloading[39m
|
||||
[?25l [90m·[39m to default 6x6
|
||||
[90m·[39m to NEAREST_NEIGHBOR 6x6
|
||||
[90m·[39m to BILINEAR 6x6
|
||||
[90m·[39m to BICUBIC 6x6
|
||||
[90m·[39m to HERMITE 6x6
|
||||
[90m·[39m to BEZIER 6x6
|
||||
[90m·[39m mutch contrast 4x4[2m (6)[22m
|
||||
[90m·[39m to default 6x6
|
||||
[90m·[39m to NEAREST_NEIGHBOR 6x6
|
||||
[90m·[39m to BILINEAR 6x6
|
||||
[90m·[39m to BICUBIC 6x6
|
||||
[90m·[39m to HERMITE 6x6
|
||||
[90m·[39m to BEZIER 6x6
|
||||
[?25l[?25l[?25l[?25l[?25l[?25l[?25l[?25l[?25l[?25l[?25l[?25l[?25l[?25l[?25l[?25l[?25l[?25l[?25l[?25l[?25l[?25l[?25l[?25l[?25l[?25l[?25l[?25l[?25l[?25l[?25l[?25l[?25l[2K[1A[2K[1A[2K[1A[2K[1A[2K[1A[2K[1A[2K[1A[2K[1A[2K[1A[2K[1A[2K[1A[2K[1A[2K[1A[2K[G [32m✓[39m to default 6x6
|
||||
[32m✓[39m to NEAREST_NEIGHBOR 6x6
|
||||
[32m✓[39m to BILINEAR 6x6
|
||||
[32m✓[39m to BICUBIC 6x6
|
||||
[32m✓[39m to HERMITE 6x6
|
||||
[32m✓[39m to BEZIER 6x6
|
||||
[32m✓[39m mutch contrast 4x4[2m (6)[22m
|
||||
[32m✓[39m to default 6x6
|
||||
[32m✓[39m to NEAREST_NEIGHBOR 6x6
|
||||
[32m✓[39m to BILINEAR 6x6
|
||||
[32m✓[39m to BICUBIC 6x6
|
||||
[32m✓[39m to HERMITE 6x6
|
||||
[32m✓[39m to BEZIER 6x6
|
||||
[?25l[2K[1A[2K[1A[2K[1A[2K[1A[2K[1A[2K[1A[2K[1A[2K[1A[2K[1A[2K[1A[2K[1A[2K[1A[2K[1A[2K[G [32m✓[39m [2msrc/[22mindex[2m.test.ts[22m[2m (24)[22m
|
||||
[32m✓[39m Resize images[2m (24)[22m
|
||||
[32m✓[39m max contrast 8x8[2m (12)[22m
|
||||
[32m✓[39m to default 4x4
|
||||
[32m✓[39m to NEAREST_NEIGHBOR 4x4
|
||||
[32m✓[39m to BILINEAR 4x4
|
||||
[32m✓[39m to BICUBIC 4x4
|
||||
[32m✓[39m to HERMITE 4x4
|
||||
[32m✓[39m to BEZIER 4x4
|
||||
[32m✓[39m to default 2x5
|
||||
[32m✓[39m to NEAREST_NEIGHBOR 2x5
|
||||
[32m✓[39m to BILINEAR 2x5
|
||||
[32m✓[39m to BICUBIC 2x5
|
||||
[32m✓[39m to HERMITE 2x5
|
||||
[32m✓[39m to BEZIER 2x5
|
||||
[32m✓[39m max contrast 12x12 with dots[2m (6)[22m
|
||||
[32m✓[39m to default 6x6
|
||||
[32m✓[39m to NEAREST_NEIGHBOR 6x6
|
||||
[32m✓[39m to BILINEAR 6x6
|
||||
[32m✓[39m to BICUBIC 6x6
|
||||
[32m✓[39m to HERMITE 6x6
|
||||
[32m✓[39m to BEZIER 6x6
|
||||
[32m✓[39m mutch contrast 4x4[2m (6)[22m
|
||||
[32m✓[39m to default 6x6
|
||||
[32m✓[39m to NEAREST_NEIGHBOR 6x6
|
||||
[32m✓[39m to BILINEAR 6x6
|
||||
[32m✓[39m to BICUBIC 6x6
|
||||
[32m✓[39m to HERMITE 6x6
|
||||
[32m✓[39m to BEZIER 6x6
|
||||
|
||||
[2m Test Files [22m [1m[32m1 passed[39m[22m[90m (1)[39m
|
||||
[2m Tests [22m [1m[32m24 passed[39m[22m[90m (24)[39m
|
||||
[2m Start at [22m 01:39:12
|
||||
[2m Duration [22m 13.87s[2m (transform 0ms, setup 0ms, collect 133ms, tests 9ms, environment 0ms, prepare 1.63s)[22m
|
||||
|
||||
[?25h[?25h
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
|
||||
|
||||
> @jimp/plugin-resize@1.1.2 test /Users/andrewlisowski/Documents/jimp/plugins/plugin-resize
|
||||
> vitest "--watch=false"
|
||||
|
||||
|
||||
[7m[1m[36m RUN [39m[22m[27m [36mv2.0.5[39m [90m/Users/andrewlisowski/Documents/jimp/plugins/plugin-resize[39m
|
||||
|
||||
[?25l [90m·[39m to BEZIER 2x5
|
||||
[90m·[39m max contrast 12x12 with dots[2m (6)[22m
|
||||
[90m·[39m to default 6x6
|
||||
[90m·[39m to NEAREST_NEIGHBOR 6x6
|
||||
[90m·[39m to BILINEAR 6x6
|
||||
[90m·[39m to BICUBIC 6x6
|
||||
[90m·[39m to HERMITE 6x6
|
||||
[90m·[39m to BEZIER 6x6
|
||||
[90m·[39m mutch contrast 4x4[2m (6)[22m
|
||||
[90m·[39m to default 6x6
|
||||
[90m·[39m to NEAREST_NEIGHBOR 6x6
|
||||
[90m·[39m to BILINEAR 6x6
|
||||
[90m·[39m to BICUBIC 6x6
|
||||
[90m·[39m to HERMITE 6x6
|
||||
[90m·[39m to BEZIER 6x6
|
||||
[?25l[2K[1A[2K[1A[2K[1A[2K[1A[2K[1A[2K[1A[2K[1A[2K[1A[2K[1A[2K[1A[2K[1A[2K[1A[2K[1A[2K[1A[2K[1A[2K[G [32m✓[39m to BEZIER 2x5
|
||||
[32m✓[39m max contrast 12x12 with dots[2m (6)[22m
|
||||
[32m✓[39m to default 6x6
|
||||
[32m✓[39m to NEAREST_NEIGHBOR 6x6
|
||||
[32m✓[39m to BILINEAR 6x6
|
||||
[32m✓[39m to BICUBIC 6x6
|
||||
[32m✓[39m to HERMITE 6x6
|
||||
[32m✓[39m to BEZIER 6x6
|
||||
[32m✓[39m mutch contrast 4x4[2m (6)[22m
|
||||
[32m✓[39m to default 6x6
|
||||
[32m✓[39m to NEAREST_NEIGHBOR 6x6
|
||||
[32m✓[39m to BILINEAR 6x6
|
||||
[32m✓[39m to BICUBIC 6x6
|
||||
[32m✓[39m to HERMITE 6x6
|
||||
[32m✓[39m to BEZIER 6x6
|
||||
[?25l[2K[1A[2K[1A[2K[1A[2K[1A[2K[1A[2K[1A[2K[1A[2K[1A[2K[1A[2K[1A[2K[1A[2K[1A[2K[1A[2K[1A[2K[1A[2K[G [32m✓[39m [2msrc/[22mindex[2m.test.ts[22m[2m (24)[22m
|
||||
[32m✓[39m Resize images[2m (24)[22m
|
||||
[32m✓[39m max contrast 8x8[2m (12)[22m
|
||||
[32m✓[39m to default 4x4
|
||||
[32m✓[39m to NEAREST_NEIGHBOR 4x4
|
||||
[32m✓[39m to BILINEAR 4x4
|
||||
[32m✓[39m to BICUBIC 4x4
|
||||
[32m✓[39m to HERMITE 4x4
|
||||
[32m✓[39m to BEZIER 4x4
|
||||
[32m✓[39m to default 2x5
|
||||
[32m✓[39m to NEAREST_NEIGHBOR 2x5
|
||||
[32m✓[39m to BILINEAR 2x5
|
||||
[32m✓[39m to BICUBIC 2x5
|
||||
[32m✓[39m to HERMITE 2x5
|
||||
[32m✓[39m to BEZIER 2x5
|
||||
[32m✓[39m max contrast 12x12 with dots[2m (6)[22m
|
||||
[32m✓[39m to default 6x6
|
||||
[32m✓[39m to NEAREST_NEIGHBOR 6x6
|
||||
[32m✓[39m to BILINEAR 6x6
|
||||
[32m✓[39m to BICUBIC 6x6
|
||||
[32m✓[39m to HERMITE 6x6
|
||||
[32m✓[39m to BEZIER 6x6
|
||||
[32m✓[39m mutch contrast 4x4[2m (6)[22m
|
||||
[32m✓[39m to default 6x6
|
||||
[32m✓[39m to NEAREST_NEIGHBOR 6x6
|
||||
[32m✓[39m to BILINEAR 6x6
|
||||
[32m✓[39m to BICUBIC 6x6
|
||||
[32m✓[39m to HERMITE 6x6
|
||||
[32m✓[39m to BEZIER 6x6
|
||||
|
||||
[2m Test Files [22m [1m[32m1 passed[39m[22m[90m (1)[39m
|
||||
[2m Tests [22m [1m[32m24 passed[39m[22m[90m (24)[39m
|
||||
[2m Start at [22m 01:33:45
|
||||
[2m Duration [22m 2.28s[2m (transform 518ms, setup 0ms, collect 842ms, tests 14ms, environment 1ms, prepare 531ms)[22m
|
||||
|
||||
[?25h[?25h
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
# 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
@@ -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.
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
<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-resize</h1>
|
||||
<p>Resize an image.</p>
|
||||
</div>
|
||||
|
||||
Resizes the image to a set width and height using a 2-pass bilinear algorithm.
|
||||
|
||||
- [resize](http://jimp-dev.github.io/jimp/api/jimp/classes/jimp#resize)
|
||||
- [scale](http://jimp-dev.github.io/jimp/api/jimp/classes/jimp#scale)
|
||||
- [scaleToFit](http://jimp-dev.github.io/jimp/api/jimp/classes/jimp#scaletofit)
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
/**
|
||||
* What resizing algorithm to use.
|
||||
*/
|
||||
export declare enum ResizeStrategy {
|
||||
/**
|
||||
* Nearest Neighbor resizing is a method used in image processing that assigns the value of the nearest pixel to the output pixel when resizing an image.
|
||||
* While fast, it can lead to lower quality outputs with noticeable pixelation, especially at larger scaling factors.
|
||||
*/
|
||||
NEAREST_NEIGHBOR = "nearestNeighbor",
|
||||
/**
|
||||
* Bilinear resizing is an image scaling method that uses the weighted average of the four nearest pixel values, providing smoother gradients than nearest neighbor resizing.
|
||||
* It's computationally more intense than nearest neighbor but results in images of higher quality and fewer artifacts.
|
||||
*/
|
||||
BILINEAR = "bilinearInterpolation",
|
||||
/**
|
||||
* Bicubic resizing is an image interpolation method that uses the values of the nearest 16 pixels in the input image to calculate the output pixel value, providing even more smoothness and sharpness than bilinear resizing.
|
||||
* Although it's computationally more expensive than bilinear and nearest neighbor, it produces higher quality images, making it ideal for photographic image scaling.
|
||||
*/
|
||||
BICUBIC = "bicubicInterpolation",
|
||||
/**
|
||||
* Hermite resizing is an image resizing method that uses Hermite interpolation, a mathematical formula, to determine the values of output pixels based on a weighted average of the surrounding pixels.
|
||||
* Although slower than some simpler techniques like bilinear or nearest neighbor, Hermite resizing can produce higher quality visuals and detailed renderings with less blurring.
|
||||
*/
|
||||
HERMITE = "hermiteInterpolation",
|
||||
BEZIER = "bezierInterpolation"
|
||||
}
|
||||
//# sourceMappingURL=constants.d.ts.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,oBAAY,cAAc;IACxB;;;OAGG;IACH,gBAAgB,oBAAoB;IACpC;;;OAGG;IACH,QAAQ,0BAA0B;IAClC;;;OAGG;IACH,OAAO,yBAAyB;IAChC;;;OAGG;IACH,OAAO,yBAAyB;IAChC,MAAM,wBAAwB;CAC/B"}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.ResizeStrategy = void 0;
|
||||
/**
|
||||
* What resizing algorithm to use.
|
||||
*/
|
||||
var ResizeStrategy;
|
||||
(function (ResizeStrategy) {
|
||||
/**
|
||||
* Nearest Neighbor resizing is a method used in image processing that assigns the value of the nearest pixel to the output pixel when resizing an image.
|
||||
* While fast, it can lead to lower quality outputs with noticeable pixelation, especially at larger scaling factors.
|
||||
*/
|
||||
ResizeStrategy["NEAREST_NEIGHBOR"] = "nearestNeighbor";
|
||||
/**
|
||||
* Bilinear resizing is an image scaling method that uses the weighted average of the four nearest pixel values, providing smoother gradients than nearest neighbor resizing.
|
||||
* It's computationally more intense than nearest neighbor but results in images of higher quality and fewer artifacts.
|
||||
*/
|
||||
ResizeStrategy["BILINEAR"] = "bilinearInterpolation";
|
||||
/**
|
||||
* Bicubic resizing is an image interpolation method that uses the values of the nearest 16 pixels in the input image to calculate the output pixel value, providing even more smoothness and sharpness than bilinear resizing.
|
||||
* Although it's computationally more expensive than bilinear and nearest neighbor, it produces higher quality images, making it ideal for photographic image scaling.
|
||||
*/
|
||||
ResizeStrategy["BICUBIC"] = "bicubicInterpolation";
|
||||
/**
|
||||
* Hermite resizing is an image resizing method that uses Hermite interpolation, a mathematical formula, to determine the values of output pixels based on a weighted average of the surrounding pixels.
|
||||
* Although slower than some simpler techniques like bilinear or nearest neighbor, Hermite resizing can produce higher quality visuals and detailed renderings with less blurring.
|
||||
*/
|
||||
ResizeStrategy["HERMITE"] = "hermiteInterpolation";
|
||||
ResizeStrategy["BEZIER"] = "bezierInterpolation";
|
||||
})(ResizeStrategy || (exports.ResizeStrategy = ResizeStrategy = {}));
|
||||
//# sourceMappingURL=constants.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":";;;AAAA;;GAEG;AACH,IAAY,cAsBX;AAtBD,WAAY,cAAc;IACxB;;;OAGG;IACH,sDAAoC,CAAA;IACpC;;;OAGG;IACH,oDAAkC,CAAA;IAClC;;;OAGG;IACH,kDAAgC,CAAA;IAChC;;;OAGG;IACH,kDAAgC,CAAA;IAChC,gDAA8B,CAAA;AAChC,CAAC,EAtBW,cAAc,8BAAd,cAAc,QAsBzB"}
|
||||
+111
@@ -0,0 +1,111 @@
|
||||
import { JimpClass } from "@jimp/types";
|
||||
import { ResizeStrategy } from "./constants.js";
|
||||
import { z } from "zod";
|
||||
export * from "./constants.js";
|
||||
declare const ResizeOptionsSchema: z.ZodUnion<[z.ZodObject<{
|
||||
/** the width to resize the image to */
|
||||
w: z.ZodNumber;
|
||||
/** the height to resize the image to */
|
||||
h: z.ZodOptional<z.ZodNumber>;
|
||||
/** a scaling method (e.g. ResizeStrategy.BEZIER) */
|
||||
mode: z.ZodOptional<z.ZodNativeEnum<typeof ResizeStrategy>>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
w: number;
|
||||
h?: number | undefined;
|
||||
mode?: ResizeStrategy | undefined;
|
||||
}, {
|
||||
w: number;
|
||||
h?: number | undefined;
|
||||
mode?: ResizeStrategy | undefined;
|
||||
}>, z.ZodObject<{
|
||||
/** the width to resize the image to */
|
||||
w: z.ZodOptional<z.ZodNumber>;
|
||||
/** the height to resize the image to */
|
||||
h: z.ZodNumber;
|
||||
/** a scaling method (e.g. ResizeStrategy.BEZIER) */
|
||||
mode: z.ZodOptional<z.ZodNativeEnum<typeof ResizeStrategy>>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
h: number;
|
||||
w?: number | undefined;
|
||||
mode?: ResizeStrategy | undefined;
|
||||
}, {
|
||||
h: number;
|
||||
w?: number | undefined;
|
||||
mode?: ResizeStrategy | undefined;
|
||||
}>]>;
|
||||
export type ResizeOptions = z.infer<typeof ResizeOptionsSchema>;
|
||||
declare const ScaleToFitOptionsSchema: z.ZodObject<{
|
||||
/** the width to resize the image to */
|
||||
w: z.ZodNumber;
|
||||
/** the height to resize the image to */
|
||||
h: z.ZodNumber;
|
||||
/** a scaling method (e.g. Jimp.RESIZE_BEZIER) */
|
||||
mode: z.ZodOptional<z.ZodNativeEnum<typeof ResizeStrategy>>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
w: number;
|
||||
h: number;
|
||||
mode?: ResizeStrategy | undefined;
|
||||
}, {
|
||||
w: number;
|
||||
h: number;
|
||||
mode?: ResizeStrategy | undefined;
|
||||
}>;
|
||||
export type ScaleToFitOptions = z.infer<typeof ScaleToFitOptionsSchema>;
|
||||
declare const ScaleComplexOptionsSchema: z.ZodObject<{
|
||||
/** the width to resize the image to */
|
||||
f: z.ZodNumber;
|
||||
/** a scaling method (e.g. Jimp.RESIZE_BEZIER) */
|
||||
mode: z.ZodOptional<z.ZodNativeEnum<typeof ResizeStrategy>>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
f: number;
|
||||
mode?: ResizeStrategy | undefined;
|
||||
}, {
|
||||
f: number;
|
||||
mode?: ResizeStrategy | undefined;
|
||||
}>;
|
||||
export type ScaleComplexOptions = z.infer<typeof ScaleComplexOptionsSchema>;
|
||||
export type ScaleOptions = number | ScaleComplexOptions;
|
||||
export declare const methods: {
|
||||
/**
|
||||
* Resizes the image to a set width and height using a 2-pass bilinear algorithm
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Jimp } from "jimp";
|
||||
*
|
||||
* const image = await Jimp.read("test/image.png");
|
||||
*
|
||||
* image.resize({ w: 150 });
|
||||
* ```
|
||||
*/
|
||||
resize<I extends JimpClass>(image: I, options: ResizeOptions): I;
|
||||
/**
|
||||
* Uniformly scales the image by a factor.
|
||||
* @param f the factor to scale the image by
|
||||
* @param mode (optional) a scaling method (e.g. Jimp.RESIZE_BEZIER)
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Jimp } from "jimp";
|
||||
*
|
||||
* const image = await Jimp.read("test/image.png");
|
||||
*
|
||||
* image.scale(0.5);
|
||||
* ```
|
||||
*/
|
||||
scale<I extends JimpClass>(image: I, options: ScaleOptions): I;
|
||||
/**
|
||||
* Scale the image to the largest size that fits inside the rectangle that has the given width and height.
|
||||
* @param w the width to resize the image to
|
||||
* @param h the height to resize the image to
|
||||
* @param mode a scaling method (e.g. ResizeStrategy.BEZIER)
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Jimp } from "jimp";
|
||||
*
|
||||
* const image = await Jimp.read("test/image.png");
|
||||
*
|
||||
* image.scaleToFit(100, 100);
|
||||
* ```
|
||||
*/
|
||||
scaleToFit<I extends JimpClass>(image: I, options: ScaleToFitOptions): I;
|
||||
};
|
||||
//# sourceMappingURL=index.d.ts.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,cAAc,gBAAgB,CAAC;AAkB/B,QAAA,MAAM,mBAAmB;IAErB,uCAAuC;;IAEvC,wCAAwC;;IAExC,oDAAoD;;;;;;;;;;;IAIpD,uCAAuC;;IAEvC,wCAAwC;;IAExC,oDAAoD;;;;;;;;;;IAGtD,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEhE,QAAA,MAAM,uBAAuB;IAC3B,uCAAuC;;IAEvC,wCAAwC;;IAExC,iDAAiD;;;;;;;;;;EAEjD,CAAC;AAEH,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAExE,QAAA,MAAM,yBAAyB;IAC7B,uCAAuC;;IAEvC,iDAAiD;;;;;;;;EAEjD,CAAC;AAEH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAC5E,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,mBAAmB,CAAC;AAExD,eAAO,MAAM,OAAO;IAClB;;;;;;;;;;OAUG;WACI,CAAC,SAAS,SAAS,SAAS,CAAC,WAAW,aAAa;IAiD5D;;;;;;;;;;;;OAYG;UACG,CAAC,SAAS,SAAS,SAAS,CAAC,WAAW,YAAY;IAW1D;;;;;;;;;;;;;OAaG;eACQ,CAAC,SAAS,SAAS,SAAS,CAAC,WAAW,iBAAiB;CASrE,CAAC"}
|
||||
+150
@@ -0,0 +1,150 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
||||
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
||||
};
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.methods = void 0;
|
||||
const constants_js_1 = require("./constants.js");
|
||||
const zod_1 = require("zod");
|
||||
const resize_js_1 = __importDefault(require("./modules/resize.js"));
|
||||
const resize2_js_1 = require("./modules/resize2.js");
|
||||
__exportStar(require("./constants.js"), exports);
|
||||
const ResizeOptionsSchema = zod_1.z.union([
|
||||
zod_1.z.object({
|
||||
/** the width to resize the image to */
|
||||
w: zod_1.z.number().min(0),
|
||||
/** the height to resize the image to */
|
||||
h: zod_1.z.number().min(0).optional(),
|
||||
/** a scaling method (e.g. ResizeStrategy.BEZIER) */
|
||||
mode: zod_1.z.nativeEnum(constants_js_1.ResizeStrategy).optional(),
|
||||
}),
|
||||
zod_1.z.object({
|
||||
/** the width to resize the image to */
|
||||
w: zod_1.z.number().min(0).optional(),
|
||||
/** the height to resize the image to */
|
||||
h: zod_1.z.number().min(0),
|
||||
/** a scaling method (e.g. ResizeStrategy.BEZIER) */
|
||||
mode: zod_1.z.nativeEnum(constants_js_1.ResizeStrategy).optional(),
|
||||
}),
|
||||
]);
|
||||
const ScaleToFitOptionsSchema = zod_1.z.object({
|
||||
/** the width to resize the image to */
|
||||
w: zod_1.z.number().min(0),
|
||||
/** the height to resize the image to */
|
||||
h: zod_1.z.number().min(0),
|
||||
/** a scaling method (e.g. Jimp.RESIZE_BEZIER) */
|
||||
mode: zod_1.z.nativeEnum(constants_js_1.ResizeStrategy).optional(),
|
||||
});
|
||||
const ScaleComplexOptionsSchema = zod_1.z.object({
|
||||
/** the width to resize the image to */
|
||||
f: zod_1.z.number().min(0),
|
||||
/** a scaling method (e.g. Jimp.RESIZE_BEZIER) */
|
||||
mode: zod_1.z.nativeEnum(constants_js_1.ResizeStrategy).optional(),
|
||||
});
|
||||
exports.methods = {
|
||||
/**
|
||||
* Resizes the image to a set width and height using a 2-pass bilinear algorithm
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Jimp } from "jimp";
|
||||
*
|
||||
* const image = await Jimp.read("test/image.png");
|
||||
*
|
||||
* image.resize({ w: 150 });
|
||||
* ```
|
||||
*/
|
||||
resize(image, options) {
|
||||
const { mode } = ResizeOptionsSchema.parse(options);
|
||||
let w;
|
||||
let h;
|
||||
if (typeof options.w === "number") {
|
||||
w = options.w;
|
||||
h = options.h ?? image.bitmap.height * (w / image.bitmap.width);
|
||||
}
|
||||
else if (typeof options.h === "number") {
|
||||
h = options.h;
|
||||
w = options.w ?? image.bitmap.width * (h / image.bitmap.height);
|
||||
}
|
||||
else {
|
||||
throw new Error("w must be a number");
|
||||
}
|
||||
// round inputs
|
||||
w = Math.round(w) || 1;
|
||||
h = Math.round(h) || 1;
|
||||
if (mode && typeof resize2_js_1.operations[mode] === "function") {
|
||||
const dst = {
|
||||
data: Buffer.alloc(w * h * 4),
|
||||
width: w,
|
||||
height: h,
|
||||
};
|
||||
resize2_js_1.operations[mode](image.bitmap, dst);
|
||||
image.bitmap = dst;
|
||||
}
|
||||
else {
|
||||
const resize = new resize_js_1.default(image.bitmap.width, image.bitmap.height, w, h, true, true, (buffer) => {
|
||||
image.bitmap.data = Buffer.from(buffer);
|
||||
image.bitmap.width = w;
|
||||
image.bitmap.height = h;
|
||||
});
|
||||
resize.resize(image.bitmap.data);
|
||||
}
|
||||
return image;
|
||||
},
|
||||
/**
|
||||
* Uniformly scales the image by a factor.
|
||||
* @param f the factor to scale the image by
|
||||
* @param mode (optional) a scaling method (e.g. Jimp.RESIZE_BEZIER)
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Jimp } from "jimp";
|
||||
*
|
||||
* const image = await Jimp.read("test/image.png");
|
||||
*
|
||||
* image.scale(0.5);
|
||||
* ```
|
||||
*/
|
||||
scale(image, options) {
|
||||
const { f, mode } = typeof options === "number"
|
||||
? { f: options }
|
||||
: ScaleComplexOptionsSchema.parse(options);
|
||||
const w = image.bitmap.width * f;
|
||||
const h = image.bitmap.height * f;
|
||||
return this.resize(image, { w, h, mode: mode });
|
||||
},
|
||||
/**
|
||||
* Scale the image to the largest size that fits inside the rectangle that has the given width and height.
|
||||
* @param w the width to resize the image to
|
||||
* @param h the height to resize the image to
|
||||
* @param mode a scaling method (e.g. ResizeStrategy.BEZIER)
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Jimp } from "jimp";
|
||||
*
|
||||
* const image = await Jimp.read("test/image.png");
|
||||
*
|
||||
* image.scaleToFit(100, 100);
|
||||
* ```
|
||||
*/
|
||||
scaleToFit(image, options) {
|
||||
const { h, w, mode } = ScaleToFitOptionsSchema.parse(options);
|
||||
const f = w / h > image.bitmap.width / image.bitmap.height
|
||||
? h / image.bitmap.height
|
||||
: w / image.bitmap.width;
|
||||
return this.scale(image, { f, mode: mode });
|
||||
},
|
||||
};
|
||||
//# sourceMappingURL=index.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
declare function Resize(widthOriginal: any, heightOriginal: any, targetWidth: any, targetHeight: any, blendAlpha: any, interpolationPass: any, resizeCallback: any): void;
|
||||
export default Resize;
|
||||
//# sourceMappingURL=resize.d.ts.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"resize.d.ts","sourceRoot":"","sources":["../../../src/modules/resize.ts"],"names":[],"mappings":"AAMA,iBAAS,MAAM,CACb,aAAa,KAAA,EACb,cAAc,KAAA,EACd,WAAW,KAAA,EACX,YAAY,KAAA,EACZ,UAAU,KAAA,EACV,iBAAiB,KAAA,EACjB,cAAc,KAAA,QAqBf;AAwgBD,eAAe,MAAM,CAAC"}
|
||||
+412
@@ -0,0 +1,412 @@
|
||||
"use strict";
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-nocheck
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
// JavaScript Image Resizer (c) 2012 - Grant Galitz
|
||||
// Released to public domain 29 July 2013: https://github.com/grantgalitz/JS-Image-Resizer/issues/4
|
||||
function Resize(widthOriginal, heightOriginal, targetWidth, targetHeight, blendAlpha, interpolationPass, resizeCallback) {
|
||||
this.widthOriginal = Math.abs(Math.floor(widthOriginal) || 0);
|
||||
this.heightOriginal = Math.abs(Math.floor(heightOriginal) || 0);
|
||||
this.targetWidth = Math.abs(Math.floor(targetWidth) || 0);
|
||||
this.targetHeight = Math.abs(Math.floor(targetHeight) || 0);
|
||||
this.colorChannels = blendAlpha ? 4 : 3;
|
||||
this.interpolationPass = Boolean(interpolationPass);
|
||||
this.resizeCallback =
|
||||
typeof resizeCallback === "function" ? resizeCallback : function () { };
|
||||
this.targetWidthMultipliedByChannels = this.targetWidth * this.colorChannels;
|
||||
this.originalWidthMultipliedByChannels =
|
||||
this.widthOriginal * this.colorChannels;
|
||||
this.originalHeightMultipliedByChannels =
|
||||
this.heightOriginal * this.colorChannels;
|
||||
this.widthPassResultSize =
|
||||
this.targetWidthMultipliedByChannels * this.heightOriginal;
|
||||
this.finalResultSize =
|
||||
this.targetWidthMultipliedByChannels * this.targetHeight;
|
||||
this.initialize();
|
||||
}
|
||||
Resize.prototype.initialize = function () {
|
||||
// Perform some checks:
|
||||
if (this.widthOriginal > 0 &&
|
||||
this.heightOriginal > 0 &&
|
||||
this.targetWidth > 0 &&
|
||||
this.targetHeight > 0) {
|
||||
this.configurePasses();
|
||||
}
|
||||
else {
|
||||
console.log(this);
|
||||
throw new Error("Invalid settings specified for the resizer.");
|
||||
}
|
||||
};
|
||||
Resize.prototype.configurePasses = function () {
|
||||
if (this.widthOriginal === this.targetWidth) {
|
||||
// Bypass the width resizer pass:
|
||||
this.resizeWidth = this.bypassResizer;
|
||||
}
|
||||
else {
|
||||
// Setup the width resizer pass:
|
||||
this.ratioWeightWidthPass = this.widthOriginal / this.targetWidth;
|
||||
if (this.ratioWeightWidthPass < 1 && this.interpolationPass) {
|
||||
this.initializeFirstPassBuffers(true);
|
||||
this.resizeWidth =
|
||||
this.colorChannels === 4
|
||||
? this.resizeWidthInterpolatedRGBA
|
||||
: this.resizeWidthInterpolatedRGB;
|
||||
}
|
||||
else {
|
||||
this.initializeFirstPassBuffers(false);
|
||||
this.resizeWidth =
|
||||
this.colorChannels === 4 ? this.resizeWidthRGBA : this.resizeWidthRGB;
|
||||
}
|
||||
}
|
||||
if (this.heightOriginal === this.targetHeight) {
|
||||
// Bypass the height resizer pass:
|
||||
this.resizeHeight = this.bypassResizer;
|
||||
}
|
||||
else {
|
||||
// Setup the height resizer pass:
|
||||
this.ratioWeightHeightPass = this.heightOriginal / this.targetHeight;
|
||||
if (this.ratioWeightHeightPass < 1 && this.interpolationPass) {
|
||||
this.initializeSecondPassBuffers(true);
|
||||
this.resizeHeight = this.resizeHeightInterpolated;
|
||||
}
|
||||
else {
|
||||
this.initializeSecondPassBuffers(false);
|
||||
this.resizeHeight =
|
||||
this.colorChannels === 4 ? this.resizeHeightRGBA : this.resizeHeightRGB;
|
||||
}
|
||||
}
|
||||
};
|
||||
Resize.prototype._resizeWidthInterpolatedRGBChannels = function (buffer, fourthChannel) {
|
||||
const channelsNum = fourthChannel ? 4 : 3;
|
||||
const ratioWeight = this.ratioWeightWidthPass;
|
||||
const outputBuffer = this.widthBuffer;
|
||||
let weight = 0;
|
||||
let finalOffset = 0;
|
||||
let pixelOffset = 0;
|
||||
let firstWeight = 0;
|
||||
let secondWeight = 0;
|
||||
let targetPosition;
|
||||
// Handle for only one interpolation input being valid for start calculation:
|
||||
for (targetPosition = 0; weight < 1 / 3; targetPosition += channelsNum, weight += ratioWeight) {
|
||||
for (finalOffset = targetPosition, pixelOffset = 0; finalOffset < this.widthPassResultSize; pixelOffset += this.originalWidthMultipliedByChannels,
|
||||
finalOffset += this.targetWidthMultipliedByChannels) {
|
||||
outputBuffer[finalOffset] = buffer[pixelOffset];
|
||||
outputBuffer[finalOffset + 1] = buffer[pixelOffset + 1];
|
||||
outputBuffer[finalOffset + 2] = buffer[pixelOffset + 2];
|
||||
if (fourthChannel)
|
||||
outputBuffer[finalOffset + 3] = buffer[pixelOffset + 3];
|
||||
}
|
||||
}
|
||||
// Adjust for overshoot of the last pass's counter:
|
||||
weight -= 1 / 3;
|
||||
let interpolationWidthSourceReadStop;
|
||||
for (interpolationWidthSourceReadStop = this.widthOriginal - 1; weight < interpolationWidthSourceReadStop; targetPosition += channelsNum, weight += ratioWeight) {
|
||||
// Calculate weightings:
|
||||
secondWeight = weight % 1;
|
||||
firstWeight = 1 - secondWeight;
|
||||
// Interpolate:
|
||||
for (finalOffset = targetPosition,
|
||||
pixelOffset = Math.floor(weight) * channelsNum; finalOffset < this.widthPassResultSize; pixelOffset += this.originalWidthMultipliedByChannels,
|
||||
finalOffset += this.targetWidthMultipliedByChannels) {
|
||||
outputBuffer[finalOffset + 0] =
|
||||
buffer[pixelOffset + 0] * firstWeight +
|
||||
buffer[pixelOffset + channelsNum + 0] * secondWeight;
|
||||
outputBuffer[finalOffset + 1] =
|
||||
buffer[pixelOffset + 1] * firstWeight +
|
||||
buffer[pixelOffset + channelsNum + 1] * secondWeight;
|
||||
outputBuffer[finalOffset + 2] =
|
||||
buffer[pixelOffset + 2] * firstWeight +
|
||||
buffer[pixelOffset + channelsNum + 2] * secondWeight;
|
||||
if (fourthChannel)
|
||||
outputBuffer[finalOffset + 3] =
|
||||
buffer[pixelOffset + 3] * firstWeight +
|
||||
buffer[pixelOffset + channelsNum + 3] * secondWeight;
|
||||
}
|
||||
}
|
||||
// Handle for only one interpolation input being valid for end calculation:
|
||||
for (interpolationWidthSourceReadStop =
|
||||
this.originalWidthMultipliedByChannels - channelsNum; targetPosition < this.targetWidthMultipliedByChannels; targetPosition += channelsNum) {
|
||||
for (finalOffset = targetPosition,
|
||||
pixelOffset = interpolationWidthSourceReadStop; finalOffset < this.widthPassResultSize; pixelOffset += this.originalWidthMultipliedByChannels,
|
||||
finalOffset += this.targetWidthMultipliedByChannels) {
|
||||
outputBuffer[finalOffset] = buffer[pixelOffset];
|
||||
outputBuffer[finalOffset + 1] = buffer[pixelOffset + 1];
|
||||
outputBuffer[finalOffset + 2] = buffer[pixelOffset + 2];
|
||||
if (fourthChannel)
|
||||
outputBuffer[finalOffset + 3] = buffer[pixelOffset + 3];
|
||||
}
|
||||
}
|
||||
return outputBuffer;
|
||||
};
|
||||
Resize.prototype._resizeWidthRGBChannels = function (buffer, fourthChannel) {
|
||||
const channelsNum = fourthChannel ? 4 : 3;
|
||||
const ratioWeight = this.ratioWeightWidthPass;
|
||||
const ratioWeightDivisor = 1 / ratioWeight;
|
||||
const nextLineOffsetOriginalWidth = this.originalWidthMultipliedByChannels - channelsNum + 1;
|
||||
const nextLineOffsetTargetWidth = this.targetWidthMultipliedByChannels - channelsNum + 1;
|
||||
const output = this.outputWidthWorkBench;
|
||||
const outputBuffer = this.widthBuffer;
|
||||
const trustworthyColorsCount = this.outputWidthWorkBenchOpaquePixelsCount;
|
||||
let weight = 0;
|
||||
let amountToNext = 0;
|
||||
let actualPosition = 0;
|
||||
let currentPosition = 0;
|
||||
let line = 0;
|
||||
let pixelOffset = 0;
|
||||
let outputOffset = 0;
|
||||
let multiplier = 1;
|
||||
let r = 0;
|
||||
let g = 0;
|
||||
let b = 0;
|
||||
let a = 0;
|
||||
do {
|
||||
for (line = 0; line < this.originalHeightMultipliedByChannels;) {
|
||||
output[line++] = 0;
|
||||
output[line++] = 0;
|
||||
output[line++] = 0;
|
||||
if (fourthChannel) {
|
||||
output[line++] = 0;
|
||||
trustworthyColorsCount[line / channelsNum - 1] = 0;
|
||||
}
|
||||
}
|
||||
weight = ratioWeight;
|
||||
do {
|
||||
amountToNext = 1 + actualPosition - currentPosition;
|
||||
multiplier = Math.min(weight, amountToNext);
|
||||
for (line = 0, pixelOffset = actualPosition; line < this.originalHeightMultipliedByChannels; pixelOffset += nextLineOffsetOriginalWidth) {
|
||||
r = buffer[pixelOffset];
|
||||
g = buffer[++pixelOffset];
|
||||
b = buffer[++pixelOffset];
|
||||
a = fourthChannel ? buffer[++pixelOffset] : 255;
|
||||
// Ignore RGB values if pixel is completely transparent
|
||||
output[line++] += (a ? r : 0) * multiplier;
|
||||
output[line++] += (a ? g : 0) * multiplier;
|
||||
output[line++] += (a ? b : 0) * multiplier;
|
||||
if (fourthChannel) {
|
||||
output[line++] += a * multiplier;
|
||||
trustworthyColorsCount[line / channelsNum - 1] += a ? multiplier : 0;
|
||||
}
|
||||
}
|
||||
if (weight >= amountToNext) {
|
||||
actualPosition += channelsNum;
|
||||
currentPosition = actualPosition;
|
||||
weight -= amountToNext;
|
||||
}
|
||||
else {
|
||||
currentPosition += weight;
|
||||
break;
|
||||
}
|
||||
} while (weight > 0 &&
|
||||
actualPosition < this.originalWidthMultipliedByChannels);
|
||||
for (line = 0, pixelOffset = outputOffset; line < this.originalHeightMultipliedByChannels; pixelOffset += nextLineOffsetTargetWidth) {
|
||||
weight = fourthChannel ? trustworthyColorsCount[line / channelsNum] : 1;
|
||||
multiplier = fourthChannel
|
||||
? weight
|
||||
? 1 / weight
|
||||
: 0
|
||||
: ratioWeightDivisor;
|
||||
outputBuffer[pixelOffset] = output[line++] * multiplier;
|
||||
outputBuffer[++pixelOffset] = output[line++] * multiplier;
|
||||
outputBuffer[++pixelOffset] = output[line++] * multiplier;
|
||||
if (fourthChannel)
|
||||
outputBuffer[++pixelOffset] = output[line++] * ratioWeightDivisor;
|
||||
}
|
||||
outputOffset += channelsNum;
|
||||
} while (outputOffset < this.targetWidthMultipliedByChannels);
|
||||
return outputBuffer;
|
||||
};
|
||||
Resize.prototype._resizeHeightRGBChannels = function (buffer, fourthChannel) {
|
||||
const ratioWeight = this.ratioWeightHeightPass;
|
||||
const ratioWeightDivisor = 1 / ratioWeight;
|
||||
const output = this.outputHeightWorkBench;
|
||||
const outputBuffer = this.heightBuffer;
|
||||
const trustworthyColorsCount = this.outputHeightWorkBenchOpaquePixelsCount;
|
||||
let weight = 0;
|
||||
let amountToNext = 0;
|
||||
let actualPosition = 0;
|
||||
let currentPosition = 0;
|
||||
let pixelOffset = 0;
|
||||
let outputOffset = 0;
|
||||
let caret = 0;
|
||||
let multiplier = 1;
|
||||
let r = 0;
|
||||
let g = 0;
|
||||
let b = 0;
|
||||
let a = 0;
|
||||
do {
|
||||
for (pixelOffset = 0; pixelOffset < this.targetWidthMultipliedByChannels;) {
|
||||
output[pixelOffset++] = 0;
|
||||
output[pixelOffset++] = 0;
|
||||
output[pixelOffset++] = 0;
|
||||
if (fourthChannel) {
|
||||
output[pixelOffset++] = 0;
|
||||
trustworthyColorsCount[pixelOffset / 4 - 1] = 0;
|
||||
}
|
||||
}
|
||||
weight = ratioWeight;
|
||||
do {
|
||||
amountToNext = 1 + actualPosition - currentPosition;
|
||||
multiplier = Math.min(weight, amountToNext);
|
||||
caret = actualPosition;
|
||||
for (pixelOffset = 0; pixelOffset < this.targetWidthMultipliedByChannels;) {
|
||||
r = buffer[caret++];
|
||||
g = buffer[caret++];
|
||||
b = buffer[caret++];
|
||||
a = fourthChannel ? buffer[caret++] : 255;
|
||||
// Ignore RGB values if pixel is completely transparent
|
||||
output[pixelOffset++] += (a ? r : 0) * multiplier;
|
||||
output[pixelOffset++] += (a ? g : 0) * multiplier;
|
||||
output[pixelOffset++] += (a ? b : 0) * multiplier;
|
||||
if (fourthChannel) {
|
||||
output[pixelOffset++] += a * multiplier;
|
||||
trustworthyColorsCount[pixelOffset / 4 - 1] += a ? multiplier : 0;
|
||||
}
|
||||
}
|
||||
if (weight >= amountToNext) {
|
||||
actualPosition = caret;
|
||||
currentPosition = actualPosition;
|
||||
weight -= amountToNext;
|
||||
}
|
||||
else {
|
||||
currentPosition += weight;
|
||||
break;
|
||||
}
|
||||
} while (weight > 0 && actualPosition < this.widthPassResultSize);
|
||||
for (pixelOffset = 0; pixelOffset < this.targetWidthMultipliedByChannels;) {
|
||||
weight = fourthChannel ? trustworthyColorsCount[pixelOffset / 4] : 1;
|
||||
multiplier = fourthChannel
|
||||
? weight
|
||||
? 1 / weight
|
||||
: 0
|
||||
: ratioWeightDivisor;
|
||||
outputBuffer[outputOffset++] = Math.round(output[pixelOffset++] * multiplier);
|
||||
outputBuffer[outputOffset++] = Math.round(output[pixelOffset++] * multiplier);
|
||||
outputBuffer[outputOffset++] = Math.round(output[pixelOffset++] * multiplier);
|
||||
if (fourthChannel) {
|
||||
outputBuffer[outputOffset++] = Math.round(output[pixelOffset++] * ratioWeightDivisor);
|
||||
}
|
||||
}
|
||||
} while (outputOffset < this.finalResultSize);
|
||||
return outputBuffer;
|
||||
};
|
||||
Resize.prototype.resizeWidthInterpolatedRGB = function (buffer) {
|
||||
return this._resizeWidthInterpolatedRGBChannels(buffer, false);
|
||||
};
|
||||
Resize.prototype.resizeWidthInterpolatedRGBA = function (buffer) {
|
||||
return this._resizeWidthInterpolatedRGBChannels(buffer, true);
|
||||
};
|
||||
Resize.prototype.resizeWidthRGB = function (buffer) {
|
||||
return this._resizeWidthRGBChannels(buffer, false);
|
||||
};
|
||||
Resize.prototype.resizeWidthRGBA = function (buffer) {
|
||||
return this._resizeWidthRGBChannels(buffer, true);
|
||||
};
|
||||
Resize.prototype.resizeHeightInterpolated = function (buffer) {
|
||||
const ratioWeight = this.ratioWeightHeightPass;
|
||||
const outputBuffer = this.heightBuffer;
|
||||
let weight = 0;
|
||||
let finalOffset = 0;
|
||||
let pixelOffset = 0;
|
||||
let pixelOffsetAccumulated = 0;
|
||||
let pixelOffsetAccumulated2 = 0;
|
||||
let firstWeight = 0;
|
||||
let secondWeight = 0;
|
||||
let interpolationHeightSourceReadStop;
|
||||
// Handle for only one interpolation input being valid for start calculation:
|
||||
for (; weight < 1 / 3; weight += ratioWeight) {
|
||||
for (pixelOffset = 0; pixelOffset < this.targetWidthMultipliedByChannels;) {
|
||||
outputBuffer[finalOffset++] = Math.round(buffer[pixelOffset++]);
|
||||
}
|
||||
}
|
||||
// Adjust for overshoot of the last pass's counter:
|
||||
weight -= 1 / 3;
|
||||
for (interpolationHeightSourceReadStop = this.heightOriginal - 1; weight < interpolationHeightSourceReadStop; weight += ratioWeight) {
|
||||
// Calculate weightings:
|
||||
secondWeight = weight % 1;
|
||||
firstWeight = 1 - secondWeight;
|
||||
// Interpolate:
|
||||
pixelOffsetAccumulated =
|
||||
Math.floor(weight) * this.targetWidthMultipliedByChannels;
|
||||
pixelOffsetAccumulated2 =
|
||||
pixelOffsetAccumulated + this.targetWidthMultipliedByChannels;
|
||||
for (pixelOffset = 0; pixelOffset < this.targetWidthMultipliedByChannels; ++pixelOffset) {
|
||||
outputBuffer[finalOffset++] = Math.round(buffer[pixelOffsetAccumulated++] * firstWeight +
|
||||
buffer[pixelOffsetAccumulated2++] * secondWeight);
|
||||
}
|
||||
}
|
||||
// Handle for only one interpolation input being valid for end calculation:
|
||||
while (finalOffset < this.finalResultSize) {
|
||||
for (pixelOffset = 0,
|
||||
pixelOffsetAccumulated =
|
||||
interpolationHeightSourceReadStop *
|
||||
this.targetWidthMultipliedByChannels; pixelOffset < this.targetWidthMultipliedByChannels; ++pixelOffset) {
|
||||
outputBuffer[finalOffset++] = Math.round(buffer[pixelOffsetAccumulated++]);
|
||||
}
|
||||
}
|
||||
return outputBuffer;
|
||||
};
|
||||
Resize.prototype.resizeHeightRGB = function (buffer) {
|
||||
return this._resizeHeightRGBChannels(buffer, false);
|
||||
};
|
||||
Resize.prototype.resizeHeightRGBA = function (buffer) {
|
||||
return this._resizeHeightRGBChannels(buffer, true);
|
||||
};
|
||||
Resize.prototype.resize = function (buffer) {
|
||||
this.resizeCallback(this.resizeHeight(this.resizeWidth(buffer)));
|
||||
};
|
||||
Resize.prototype.bypassResizer = function (buffer) {
|
||||
// Just return the buffer passed:
|
||||
return buffer;
|
||||
};
|
||||
Resize.prototype.initializeFirstPassBuffers = function (BILINEARAlgo) {
|
||||
// Initialize the internal width pass buffers:
|
||||
this.widthBuffer = this.generateFloatBuffer(this.widthPassResultSize);
|
||||
if (!BILINEARAlgo) {
|
||||
this.outputWidthWorkBench = this.generateFloatBuffer(this.originalHeightMultipliedByChannels);
|
||||
if (this.colorChannels > 3) {
|
||||
this.outputWidthWorkBenchOpaquePixelsCount = this.generateFloat64Buffer(this.heightOriginal);
|
||||
}
|
||||
}
|
||||
};
|
||||
Resize.prototype.initializeSecondPassBuffers = function (BILINEARAlgo) {
|
||||
// Initialize the internal height pass buffers:
|
||||
this.heightBuffer = this.generateUint8Buffer(this.finalResultSize);
|
||||
if (!BILINEARAlgo) {
|
||||
this.outputHeightWorkBench = this.generateFloatBuffer(this.targetWidthMultipliedByChannels);
|
||||
if (this.colorChannels > 3) {
|
||||
this.outputHeightWorkBenchOpaquePixelsCount = this.generateFloat64Buffer(this.targetWidth);
|
||||
}
|
||||
}
|
||||
};
|
||||
Resize.prototype.generateFloatBuffer = function (bufferLength) {
|
||||
// Generate a float32 typed array buffer:
|
||||
try {
|
||||
return new Float32Array(bufferLength);
|
||||
}
|
||||
catch (error) {
|
||||
console.error(error);
|
||||
return [];
|
||||
}
|
||||
};
|
||||
Resize.prototype.generateFloat64Buffer = function (bufferLength) {
|
||||
// Generate a float64 typed array buffer:
|
||||
try {
|
||||
return new Float64Array(bufferLength);
|
||||
}
|
||||
catch (error) {
|
||||
console.error(error);
|
||||
return [];
|
||||
}
|
||||
};
|
||||
Resize.prototype.generateUint8Buffer = function (bufferLength) {
|
||||
// Generate a uint8 typed array buffer:
|
||||
try {
|
||||
return new Uint8Array(bufferLength);
|
||||
}
|
||||
catch (error) {
|
||||
console.error(error);
|
||||
return [];
|
||||
}
|
||||
};
|
||||
exports.default = Resize;
|
||||
//# sourceMappingURL=resize.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"resize.js","sourceRoot":"","sources":["../../../src/modules/resize.ts"],"names":[],"mappings":"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 truncated
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
/**
|
||||
* Copyright (c) 2015 Guyon Roche
|
||||
*
|
||||
* 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:</p>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
export declare const operations: {
|
||||
nearestNeighbor(src: any, dst: any): void;
|
||||
bilinearInterpolation(src: any, dst: any): void;
|
||||
_interpolate2D(src: any, dst: any, options?: any, interpolate?: any): void;
|
||||
bicubicInterpolation(src: any, dst: any, options?: any): void;
|
||||
hermiteInterpolation(src: any, dst: any, options?: any): void;
|
||||
bezierInterpolation(src: any, dst: any, options?: any): void;
|
||||
};
|
||||
//# sourceMappingURL=resize2.d.ts.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"resize2.d.ts","sourceRoot":"","sources":["../../../src/modules/resize2.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,eAAO,MAAM,UAAU;yBACA,GAAG,OAAO,GAAG;+BA0BP,GAAG,OAAO,GAAG;wBAuEpB,GAAG,OAAO,GAAG,YAAY,GAAG,gBAAgB,GAAG;8BAmIzC,GAAG,OAAO,GAAG,YAAY,GAAG;8BAqB5B,GAAG,OAAO,GAAG,YAAY,GAAG;6BAqB7B,GAAG,OAAO,GAAG,YAAY,GAAG;CAgCtD,CAAC"}
|
||||
+251
@@ -0,0 +1,251 @@
|
||||
"use strict";
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
/**
|
||||
* Copyright (c) 2015 Guyon Roche
|
||||
*
|
||||
* 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:</p>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.operations = void 0;
|
||||
exports.operations = {
|
||||
nearestNeighbor(src, dst) {
|
||||
const wSrc = src.width;
|
||||
const hSrc = src.height;
|
||||
const wDst = dst.width;
|
||||
const hDst = dst.height;
|
||||
const bufSrc = src.data;
|
||||
const bufDst = dst.data;
|
||||
for (let i = 0; i < hDst; i++) {
|
||||
for (let j = 0; j < wDst; j++) {
|
||||
let posDst = (i * wDst + j) * 4;
|
||||
const iSrc = Math.floor((i * hSrc) / hDst);
|
||||
const jSrc = Math.floor((j * wSrc) / wDst);
|
||||
let posSrc = (iSrc * wSrc + jSrc) * 4;
|
||||
bufDst[posDst++] = bufSrc[posSrc++];
|
||||
bufDst[posDst++] = bufSrc[posSrc++];
|
||||
bufDst[posDst++] = bufSrc[posSrc++];
|
||||
bufDst[posDst++] = bufSrc[posSrc++];
|
||||
}
|
||||
}
|
||||
},
|
||||
bilinearInterpolation(src, dst) {
|
||||
const wSrc = src.width;
|
||||
const hSrc = src.height;
|
||||
const wDst = dst.width;
|
||||
const hDst = dst.height;
|
||||
const bufSrc = src.data;
|
||||
const bufDst = dst.data;
|
||||
const interpolate = function (k, kMin, vMin, kMax, vMax) {
|
||||
// special case - k is integer
|
||||
if (kMin === kMax) {
|
||||
return vMin;
|
||||
}
|
||||
return Math.round((k - kMin) * vMax + (kMax - k) * vMin);
|
||||
};
|
||||
const assign = function (pos, offset, x, xMin, xMax, y, yMin, yMax) {
|
||||
let posMin = (yMin * wSrc + xMin) * 4 + offset;
|
||||
let posMax = (yMin * wSrc + xMax) * 4 + offset;
|
||||
const vMin = interpolate(x, xMin, bufSrc[posMin], xMax, bufSrc[posMax]);
|
||||
// special case, y is integer
|
||||
if (yMax === yMin) {
|
||||
bufDst[pos + offset] = vMin;
|
||||
}
|
||||
else {
|
||||
posMin = (yMax * wSrc + xMin) * 4 + offset;
|
||||
posMax = (yMax * wSrc + xMax) * 4 + offset;
|
||||
const vMax = interpolate(x, xMin, bufSrc[posMin], xMax, bufSrc[posMax]);
|
||||
bufDst[pos + offset] = interpolate(y, yMin, vMin, yMax, vMax);
|
||||
}
|
||||
};
|
||||
for (let i = 0; i < hDst; i++) {
|
||||
for (let j = 0; j < wDst; j++) {
|
||||
const posDst = (i * wDst + j) * 4;
|
||||
// x & y in src coordinates
|
||||
const x = (j * wSrc) / wDst;
|
||||
const xMin = Math.floor(x);
|
||||
const xMax = Math.min(Math.ceil(x), wSrc - 1);
|
||||
const y = (i * hSrc) / hDst;
|
||||
const yMin = Math.floor(y);
|
||||
const yMax = Math.min(Math.ceil(y), hSrc - 1);
|
||||
assign(posDst, 0, x, xMin, xMax, y, yMin, yMax);
|
||||
assign(posDst, 1, x, xMin, xMax, y, yMin, yMax);
|
||||
assign(posDst, 2, x, xMin, xMax, y, yMin, yMax);
|
||||
assign(posDst, 3, x, xMin, xMax, y, yMin, yMax);
|
||||
}
|
||||
}
|
||||
},
|
||||
_interpolate2D(src, dst, options, interpolate) {
|
||||
const bufSrc = src.data;
|
||||
const bufDst = dst.data;
|
||||
const wSrc = src.width;
|
||||
const hSrc = src.height;
|
||||
const wDst = dst.width;
|
||||
const hDst = dst.height;
|
||||
// when dst smaller than src/2, interpolate first to a multiple between 0.5 and 1.0 src, then sum squares
|
||||
const wM = Math.max(1, Math.floor(wSrc / wDst));
|
||||
const wDst2 = wDst * wM;
|
||||
const hM = Math.max(1, Math.floor(hSrc / hDst));
|
||||
const hDst2 = hDst * hM;
|
||||
// ===========================================================
|
||||
// Pass 1 - interpolate rows
|
||||
// buf1 has width of dst2 and height of src
|
||||
const buf1 = Buffer.alloc(wDst2 * hSrc * 4);
|
||||
for (let i = 0; i < hSrc; i++) {
|
||||
for (let j = 0; j < wDst2; j++) {
|
||||
// i in src coords, j in dst coords
|
||||
// calculate x in src coords
|
||||
// this interpolation requires 4 sample points and the two inner ones must be real
|
||||
// the outer points can be fudged for the edges.
|
||||
// therefore (wSrc-1)/wDst2
|
||||
const x = (j * (wSrc - 1)) / wDst2;
|
||||
const xPos = Math.floor(x);
|
||||
const t = x - xPos;
|
||||
const srcPos = (i * wSrc + xPos) * 4;
|
||||
const buf1Pos = (i * wDst2 + j) * 4;
|
||||
for (let k = 0; k < 4; k++) {
|
||||
const kPos = srcPos + k;
|
||||
const x0 = xPos > 0 ? bufSrc[kPos - 4] : 2 * bufSrc[kPos] - bufSrc[kPos + 4];
|
||||
const x1 = bufSrc[kPos];
|
||||
const x2 = bufSrc[kPos + 4];
|
||||
const x3 = xPos < wSrc - 2
|
||||
? bufSrc[kPos + 8]
|
||||
: 2 * bufSrc[kPos + 4] - bufSrc[kPos];
|
||||
buf1[buf1Pos + k] = interpolate(x0, x1, x2, x3, t);
|
||||
}
|
||||
}
|
||||
}
|
||||
// this._writeFile(wDst2, hSrc, buf1, "out/buf1.jpg");
|
||||
// ===========================================================
|
||||
// Pass 2 - interpolate columns
|
||||
// buf2 has width and height of dst2
|
||||
const buf2 = Buffer.alloc(wDst2 * hDst2 * 4);
|
||||
for (let i = 0; i < hDst2; i++) {
|
||||
for (let j = 0; j < wDst2; j++) {
|
||||
// i&j in dst2 coords
|
||||
// calculate y in buf1 coords
|
||||
// this interpolation requires 4 sample points and the two inner ones must be real
|
||||
// the outer points can be fudged for the edges.
|
||||
// therefore (hSrc-1)/hDst2
|
||||
const y = (i * (hSrc - 1)) / hDst2;
|
||||
const yPos = Math.floor(y);
|
||||
const t = y - yPos;
|
||||
const buf1Pos = (yPos * wDst2 + j) * 4;
|
||||
const buf2Pos = (i * wDst2 + j) * 4;
|
||||
for (let k = 0; k < 4; k++) {
|
||||
const kPos = buf1Pos + k;
|
||||
const y0 = yPos > 0
|
||||
? buf1[kPos - wDst2 * 4]
|
||||
: 2 * buf1[kPos] - buf1[kPos + wDst2 * 4];
|
||||
const y1 = buf1[kPos];
|
||||
const y2 = buf1[kPos + wDst2 * 4];
|
||||
const y3 = yPos < hSrc - 2
|
||||
? buf1[kPos + wDst2 * 8]
|
||||
: 2 * buf1[kPos + wDst2 * 4] - buf1[kPos];
|
||||
buf2[buf2Pos + k] = interpolate(y0, y1, y2, y3, t);
|
||||
}
|
||||
}
|
||||
}
|
||||
// this._writeFile(wDst2, hDst2, buf2, "out/buf2.jpg");
|
||||
// ===========================================================
|
||||
// Pass 3 - scale to dst
|
||||
const m = wM * hM;
|
||||
if (m > 1) {
|
||||
for (let i = 0; i < hDst; i++) {
|
||||
for (let j = 0; j < wDst; j++) {
|
||||
// i&j in dst bounded coords
|
||||
let r = 0;
|
||||
let g = 0;
|
||||
let b = 0;
|
||||
let a = 0;
|
||||
let realColors = 0;
|
||||
for (let y = 0; y < hM; y++) {
|
||||
const yPos = i * hM + y;
|
||||
for (let x = 0; x < wM; x++) {
|
||||
const xPos = j * wM + x;
|
||||
const xyPos = (yPos * wDst2 + xPos) * 4;
|
||||
const pixelAlpha = buf2[xyPos + 3];
|
||||
if (pixelAlpha) {
|
||||
r += buf2[xyPos];
|
||||
g += buf2[xyPos + 1];
|
||||
b += buf2[xyPos + 2];
|
||||
realColors++;
|
||||
}
|
||||
a += pixelAlpha;
|
||||
}
|
||||
}
|
||||
const pos = (i * wDst + j) * 4;
|
||||
bufDst[pos] = realColors ? Math.round(r / realColors) : 0;
|
||||
bufDst[pos + 1] = realColors ? Math.round(g / realColors) : 0;
|
||||
bufDst[pos + 2] = realColors ? Math.round(b / realColors) : 0;
|
||||
bufDst[pos + 3] = Math.round(a / m);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// replace dst buffer with buf2
|
||||
dst.data = buf2;
|
||||
}
|
||||
},
|
||||
bicubicInterpolation(src, dst, options) {
|
||||
const interpolateCubic = function (x0, x1, x2, x3, t) {
|
||||
const a0 = x3 - x2 - x0 + x1;
|
||||
const a1 = x0 - x1 - a0;
|
||||
const a2 = x2 - x0;
|
||||
const a3 = x1;
|
||||
return Math.max(0, Math.min(255, a0 * (t * t * t) + a1 * (t * t) + a2 * t + a3));
|
||||
};
|
||||
return this._interpolate2D(src, dst, options, interpolateCubic);
|
||||
},
|
||||
hermiteInterpolation(src, dst, options) {
|
||||
const interpolateHermite = function (x0, x1, x2, x3, t) {
|
||||
const c0 = x1;
|
||||
const c1 = 0.5 * (x2 - x0);
|
||||
const c2 = x0 - 2.5 * x1 + 2 * x2 - 0.5 * x3;
|
||||
const c3 = 0.5 * (x3 - x0) + 1.5 * (x1 - x2);
|
||||
return Math.max(0, Math.min(255, Math.round(((c3 * t + c2) * t + c1) * t + c0)));
|
||||
};
|
||||
return this._interpolate2D(src, dst, options, interpolateHermite);
|
||||
},
|
||||
bezierInterpolation(src, dst, options) {
|
||||
// between 2 points y(n), y(n+1), use next points out, y(n-1), y(n+2)
|
||||
// to predict control points (a & b) to be placed at n+0.5
|
||||
// ya(n) = y(n) + (y(n+1)-y(n-1))/4
|
||||
// yb(n) = y(n+1) - (y(n+2)-y(n))/4
|
||||
// then use std bezier to interpolate [n,n+1)
|
||||
// y(n+t) = y(n)*(1-t)^3 + 3 * ya(n)*(1-t)^2*t + 3 * yb(n)*(1-t)*t^2 + y(n+1)*t^3
|
||||
// note the 3* factor for the two control points
|
||||
// for edge cases, can choose:
|
||||
// y(-1) = y(0) - 2*(y(1)-y(0))
|
||||
// y(w) = y(w-1) + 2*(y(w-1)-y(w-2))
|
||||
// but can go with y(-1) = y(0) and y(w) = y(w-1)
|
||||
const interpolateBezier = function (x0, x1, x2, x3, t) {
|
||||
// x1, x2 are the knots, use x0 and x3 to calculate control points
|
||||
const cp1 = x1 + (x2 - x0) / 4;
|
||||
const cp2 = x2 - (x3 - x1) / 4;
|
||||
const nt = 1 - t;
|
||||
const c0 = x1 * nt * nt * nt;
|
||||
const c1 = 3 * cp1 * nt * nt * t;
|
||||
const c2 = 3 * cp2 * nt * t * t;
|
||||
const c3 = x2 * t * t * t;
|
||||
return Math.max(0, Math.min(255, Math.round(c0 + c1 + c2 + c3)));
|
||||
};
|
||||
return this._interpolate2D(src, dst, options, interpolateBezier);
|
||||
},
|
||||
};
|
||||
//# sourceMappingURL=resize2.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"resize2.js","sourceRoot":"","sources":["../../../src/modules/resize2.ts"],"names":[],"mappings":"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 truncated
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"type": "commonjs"
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
/**
|
||||
* What resizing algorithm to use.
|
||||
*/
|
||||
export declare enum ResizeStrategy {
|
||||
/**
|
||||
* Nearest Neighbor resizing is a method used in image processing that assigns the value of the nearest pixel to the output pixel when resizing an image.
|
||||
* While fast, it can lead to lower quality outputs with noticeable pixelation, especially at larger scaling factors.
|
||||
*/
|
||||
NEAREST_NEIGHBOR = "nearestNeighbor",
|
||||
/**
|
||||
* Bilinear resizing is an image scaling method that uses the weighted average of the four nearest pixel values, providing smoother gradients than nearest neighbor resizing.
|
||||
* It's computationally more intense than nearest neighbor but results in images of higher quality and fewer artifacts.
|
||||
*/
|
||||
BILINEAR = "bilinearInterpolation",
|
||||
/**
|
||||
* Bicubic resizing is an image interpolation method that uses the values of the nearest 16 pixels in the input image to calculate the output pixel value, providing even more smoothness and sharpness than bilinear resizing.
|
||||
* Although it's computationally more expensive than bilinear and nearest neighbor, it produces higher quality images, making it ideal for photographic image scaling.
|
||||
*/
|
||||
BICUBIC = "bicubicInterpolation",
|
||||
/**
|
||||
* Hermite resizing is an image resizing method that uses Hermite interpolation, a mathematical formula, to determine the values of output pixels based on a weighted average of the surrounding pixels.
|
||||
* Although slower than some simpler techniques like bilinear or nearest neighbor, Hermite resizing can produce higher quality visuals and detailed renderings with less blurring.
|
||||
*/
|
||||
HERMITE = "hermiteInterpolation",
|
||||
BEZIER = "bezierInterpolation"
|
||||
}
|
||||
//# sourceMappingURL=constants.d.ts.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,oBAAY,cAAc;IACxB;;;OAGG;IACH,gBAAgB,oBAAoB;IACpC;;;OAGG;IACH,QAAQ,0BAA0B;IAClC;;;OAGG;IACH,OAAO,yBAAyB;IAChC;;;OAGG;IACH,OAAO,yBAAyB;IAChC,MAAM,wBAAwB;CAC/B"}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
/**
|
||||
* What resizing algorithm to use.
|
||||
*/
|
||||
export var ResizeStrategy;
|
||||
(function (ResizeStrategy) {
|
||||
/**
|
||||
* Nearest Neighbor resizing is a method used in image processing that assigns the value of the nearest pixel to the output pixel when resizing an image.
|
||||
* While fast, it can lead to lower quality outputs with noticeable pixelation, especially at larger scaling factors.
|
||||
*/
|
||||
ResizeStrategy["NEAREST_NEIGHBOR"] = "nearestNeighbor";
|
||||
/**
|
||||
* Bilinear resizing is an image scaling method that uses the weighted average of the four nearest pixel values, providing smoother gradients than nearest neighbor resizing.
|
||||
* It's computationally more intense than nearest neighbor but results in images of higher quality and fewer artifacts.
|
||||
*/
|
||||
ResizeStrategy["BILINEAR"] = "bilinearInterpolation";
|
||||
/**
|
||||
* Bicubic resizing is an image interpolation method that uses the values of the nearest 16 pixels in the input image to calculate the output pixel value, providing even more smoothness and sharpness than bilinear resizing.
|
||||
* Although it's computationally more expensive than bilinear and nearest neighbor, it produces higher quality images, making it ideal for photographic image scaling.
|
||||
*/
|
||||
ResizeStrategy["BICUBIC"] = "bicubicInterpolation";
|
||||
/**
|
||||
* Hermite resizing is an image resizing method that uses Hermite interpolation, a mathematical formula, to determine the values of output pixels based on a weighted average of the surrounding pixels.
|
||||
* Although slower than some simpler techniques like bilinear or nearest neighbor, Hermite resizing can produce higher quality visuals and detailed renderings with less blurring.
|
||||
*/
|
||||
ResizeStrategy["HERMITE"] = "hermiteInterpolation";
|
||||
ResizeStrategy["BEZIER"] = "bezierInterpolation";
|
||||
})(ResizeStrategy || (ResizeStrategy = {}));
|
||||
//# sourceMappingURL=constants.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,CAAN,IAAY,cAsBX;AAtBD,WAAY,cAAc;IACxB;;;OAGG;IACH,sDAAoC,CAAA;IACpC;;;OAGG;IACH,oDAAkC,CAAA;IAClC;;;OAGG;IACH,kDAAgC,CAAA;IAChC;;;OAGG;IACH,kDAAgC,CAAA;IAChC,gDAA8B,CAAA;AAChC,CAAC,EAtBW,cAAc,KAAd,cAAc,QAsBzB"}
|
||||
+111
@@ -0,0 +1,111 @@
|
||||
import { JimpClass } from "@jimp/types";
|
||||
import { ResizeStrategy } from "./constants.js";
|
||||
import { z } from "zod";
|
||||
export * from "./constants.js";
|
||||
declare const ResizeOptionsSchema: z.ZodUnion<[z.ZodObject<{
|
||||
/** the width to resize the image to */
|
||||
w: z.ZodNumber;
|
||||
/** the height to resize the image to */
|
||||
h: z.ZodOptional<z.ZodNumber>;
|
||||
/** a scaling method (e.g. ResizeStrategy.BEZIER) */
|
||||
mode: z.ZodOptional<z.ZodNativeEnum<typeof ResizeStrategy>>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
w: number;
|
||||
h?: number | undefined;
|
||||
mode?: ResizeStrategy | undefined;
|
||||
}, {
|
||||
w: number;
|
||||
h?: number | undefined;
|
||||
mode?: ResizeStrategy | undefined;
|
||||
}>, z.ZodObject<{
|
||||
/** the width to resize the image to */
|
||||
w: z.ZodOptional<z.ZodNumber>;
|
||||
/** the height to resize the image to */
|
||||
h: z.ZodNumber;
|
||||
/** a scaling method (e.g. ResizeStrategy.BEZIER) */
|
||||
mode: z.ZodOptional<z.ZodNativeEnum<typeof ResizeStrategy>>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
h: number;
|
||||
w?: number | undefined;
|
||||
mode?: ResizeStrategy | undefined;
|
||||
}, {
|
||||
h: number;
|
||||
w?: number | undefined;
|
||||
mode?: ResizeStrategy | undefined;
|
||||
}>]>;
|
||||
export type ResizeOptions = z.infer<typeof ResizeOptionsSchema>;
|
||||
declare const ScaleToFitOptionsSchema: z.ZodObject<{
|
||||
/** the width to resize the image to */
|
||||
w: z.ZodNumber;
|
||||
/** the height to resize the image to */
|
||||
h: z.ZodNumber;
|
||||
/** a scaling method (e.g. Jimp.RESIZE_BEZIER) */
|
||||
mode: z.ZodOptional<z.ZodNativeEnum<typeof ResizeStrategy>>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
w: number;
|
||||
h: number;
|
||||
mode?: ResizeStrategy | undefined;
|
||||
}, {
|
||||
w: number;
|
||||
h: number;
|
||||
mode?: ResizeStrategy | undefined;
|
||||
}>;
|
||||
export type ScaleToFitOptions = z.infer<typeof ScaleToFitOptionsSchema>;
|
||||
declare const ScaleComplexOptionsSchema: z.ZodObject<{
|
||||
/** the width to resize the image to */
|
||||
f: z.ZodNumber;
|
||||
/** a scaling method (e.g. Jimp.RESIZE_BEZIER) */
|
||||
mode: z.ZodOptional<z.ZodNativeEnum<typeof ResizeStrategy>>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
f: number;
|
||||
mode?: ResizeStrategy | undefined;
|
||||
}, {
|
||||
f: number;
|
||||
mode?: ResizeStrategy | undefined;
|
||||
}>;
|
||||
export type ScaleComplexOptions = z.infer<typeof ScaleComplexOptionsSchema>;
|
||||
export type ScaleOptions = number | ScaleComplexOptions;
|
||||
export declare const methods: {
|
||||
/**
|
||||
* Resizes the image to a set width and height using a 2-pass bilinear algorithm
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Jimp } from "jimp";
|
||||
*
|
||||
* const image = await Jimp.read("test/image.png");
|
||||
*
|
||||
* image.resize({ w: 150 });
|
||||
* ```
|
||||
*/
|
||||
resize<I extends JimpClass>(image: I, options: ResizeOptions): I;
|
||||
/**
|
||||
* Uniformly scales the image by a factor.
|
||||
* @param f the factor to scale the image by
|
||||
* @param mode (optional) a scaling method (e.g. Jimp.RESIZE_BEZIER)
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Jimp } from "jimp";
|
||||
*
|
||||
* const image = await Jimp.read("test/image.png");
|
||||
*
|
||||
* image.scale(0.5);
|
||||
* ```
|
||||
*/
|
||||
scale<I extends JimpClass>(image: I, options: ScaleOptions): I;
|
||||
/**
|
||||
* Scale the image to the largest size that fits inside the rectangle that has the given width and height.
|
||||
* @param w the width to resize the image to
|
||||
* @param h the height to resize the image to
|
||||
* @param mode a scaling method (e.g. ResizeStrategy.BEZIER)
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Jimp } from "jimp";
|
||||
*
|
||||
* const image = await Jimp.read("test/image.png");
|
||||
*
|
||||
* image.scaleToFit(100, 100);
|
||||
* ```
|
||||
*/
|
||||
scaleToFit<I extends JimpClass>(image: I, options: ScaleToFitOptions): I;
|
||||
};
|
||||
//# sourceMappingURL=index.d.ts.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,cAAc,gBAAgB,CAAC;AAkB/B,QAAA,MAAM,mBAAmB;IAErB,uCAAuC;;IAEvC,wCAAwC;;IAExC,oDAAoD;;;;;;;;;;;IAIpD,uCAAuC;;IAEvC,wCAAwC;;IAExC,oDAAoD;;;;;;;;;;IAGtD,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEhE,QAAA,MAAM,uBAAuB;IAC3B,uCAAuC;;IAEvC,wCAAwC;;IAExC,iDAAiD;;;;;;;;;;EAEjD,CAAC;AAEH,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAExE,QAAA,MAAM,yBAAyB;IAC7B,uCAAuC;;IAEvC,iDAAiD;;;;;;;;EAEjD,CAAC;AAEH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAC5E,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,mBAAmB,CAAC;AAExD,eAAO,MAAM,OAAO;IAClB;;;;;;;;;;OAUG;WACI,CAAC,SAAS,SAAS,SAAS,CAAC,WAAW,aAAa;IAiD5D;;;;;;;;;;;;OAYG;UACG,CAAC,SAAS,SAAS,SAAS,CAAC,WAAW,YAAY;IAW1D;;;;;;;;;;;;;OAaG;eACQ,CAAC,SAAS,SAAS,SAAS,CAAC,WAAW,iBAAiB;CASrE,CAAC"}
|
||||
+130
@@ -0,0 +1,130 @@
|
||||
import { ResizeStrategy } from "./constants.js";
|
||||
import { z } from "zod";
|
||||
import Resize from "./modules/resize.js";
|
||||
import { operations as Resize2 } from "./modules/resize2.js";
|
||||
export * from "./constants.js";
|
||||
const ResizeOptionsSchema = z.union([
|
||||
z.object({
|
||||
/** the width to resize the image to */
|
||||
w: z.number().min(0),
|
||||
/** the height to resize the image to */
|
||||
h: z.number().min(0).optional(),
|
||||
/** a scaling method (e.g. ResizeStrategy.BEZIER) */
|
||||
mode: z.nativeEnum(ResizeStrategy).optional(),
|
||||
}),
|
||||
z.object({
|
||||
/** the width to resize the image to */
|
||||
w: z.number().min(0).optional(),
|
||||
/** the height to resize the image to */
|
||||
h: z.number().min(0),
|
||||
/** a scaling method (e.g. ResizeStrategy.BEZIER) */
|
||||
mode: z.nativeEnum(ResizeStrategy).optional(),
|
||||
}),
|
||||
]);
|
||||
const ScaleToFitOptionsSchema = z.object({
|
||||
/** the width to resize the image to */
|
||||
w: z.number().min(0),
|
||||
/** the height to resize the image to */
|
||||
h: z.number().min(0),
|
||||
/** a scaling method (e.g. Jimp.RESIZE_BEZIER) */
|
||||
mode: z.nativeEnum(ResizeStrategy).optional(),
|
||||
});
|
||||
const ScaleComplexOptionsSchema = z.object({
|
||||
/** the width to resize the image to */
|
||||
f: z.number().min(0),
|
||||
/** a scaling method (e.g. Jimp.RESIZE_BEZIER) */
|
||||
mode: z.nativeEnum(ResizeStrategy).optional(),
|
||||
});
|
||||
export const methods = {
|
||||
/**
|
||||
* Resizes the image to a set width and height using a 2-pass bilinear algorithm
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Jimp } from "jimp";
|
||||
*
|
||||
* const image = await Jimp.read("test/image.png");
|
||||
*
|
||||
* image.resize({ w: 150 });
|
||||
* ```
|
||||
*/
|
||||
resize(image, options) {
|
||||
const { mode } = ResizeOptionsSchema.parse(options);
|
||||
let w;
|
||||
let h;
|
||||
if (typeof options.w === "number") {
|
||||
w = options.w;
|
||||
h = options.h ?? image.bitmap.height * (w / image.bitmap.width);
|
||||
}
|
||||
else if (typeof options.h === "number") {
|
||||
h = options.h;
|
||||
w = options.w ?? image.bitmap.width * (h / image.bitmap.height);
|
||||
}
|
||||
else {
|
||||
throw new Error("w must be a number");
|
||||
}
|
||||
// round inputs
|
||||
w = Math.round(w) || 1;
|
||||
h = Math.round(h) || 1;
|
||||
if (mode && typeof Resize2[mode] === "function") {
|
||||
const dst = {
|
||||
data: Buffer.alloc(w * h * 4),
|
||||
width: w,
|
||||
height: h,
|
||||
};
|
||||
Resize2[mode](image.bitmap, dst);
|
||||
image.bitmap = dst;
|
||||
}
|
||||
else {
|
||||
const resize = new Resize(image.bitmap.width, image.bitmap.height, w, h, true, true, (buffer) => {
|
||||
image.bitmap.data = Buffer.from(buffer);
|
||||
image.bitmap.width = w;
|
||||
image.bitmap.height = h;
|
||||
});
|
||||
resize.resize(image.bitmap.data);
|
||||
}
|
||||
return image;
|
||||
},
|
||||
/**
|
||||
* Uniformly scales the image by a factor.
|
||||
* @param f the factor to scale the image by
|
||||
* @param mode (optional) a scaling method (e.g. Jimp.RESIZE_BEZIER)
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Jimp } from "jimp";
|
||||
*
|
||||
* const image = await Jimp.read("test/image.png");
|
||||
*
|
||||
* image.scale(0.5);
|
||||
* ```
|
||||
*/
|
||||
scale(image, options) {
|
||||
const { f, mode } = typeof options === "number"
|
||||
? { f: options }
|
||||
: ScaleComplexOptionsSchema.parse(options);
|
||||
const w = image.bitmap.width * f;
|
||||
const h = image.bitmap.height * f;
|
||||
return this.resize(image, { w, h, mode: mode });
|
||||
},
|
||||
/**
|
||||
* Scale the image to the largest size that fits inside the rectangle that has the given width and height.
|
||||
* @param w the width to resize the image to
|
||||
* @param h the height to resize the image to
|
||||
* @param mode a scaling method (e.g. ResizeStrategy.BEZIER)
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Jimp } from "jimp";
|
||||
*
|
||||
* const image = await Jimp.read("test/image.png");
|
||||
*
|
||||
* image.scaleToFit(100, 100);
|
||||
* ```
|
||||
*/
|
||||
scaleToFit(image, options) {
|
||||
const { h, w, mode } = ScaleToFitOptionsSchema.parse(options);
|
||||
const f = w / h > image.bitmap.width / image.bitmap.height
|
||||
? h / image.bitmap.height
|
||||
: w / image.bitmap.width;
|
||||
return this.scale(image, { f, mode: mode });
|
||||
},
|
||||
};
|
||||
//# sourceMappingURL=index.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
declare function Resize(widthOriginal: any, heightOriginal: any, targetWidth: any, targetHeight: any, blendAlpha: any, interpolationPass: any, resizeCallback: any): void;
|
||||
export default Resize;
|
||||
//# sourceMappingURL=resize.d.ts.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"resize.d.ts","sourceRoot":"","sources":["../../../src/modules/resize.ts"],"names":[],"mappings":"AAMA,iBAAS,MAAM,CACb,aAAa,KAAA,EACb,cAAc,KAAA,EACd,WAAW,KAAA,EACX,YAAY,KAAA,EACZ,UAAU,KAAA,EACV,iBAAiB,KAAA,EACjB,cAAc,KAAA,QAqBf;AAwgBD,eAAe,MAAM,CAAC"}
|
||||
+410
@@ -0,0 +1,410 @@
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-nocheck
|
||||
// JavaScript Image Resizer (c) 2012 - Grant Galitz
|
||||
// Released to public domain 29 July 2013: https://github.com/grantgalitz/JS-Image-Resizer/issues/4
|
||||
function Resize(widthOriginal, heightOriginal, targetWidth, targetHeight, blendAlpha, interpolationPass, resizeCallback) {
|
||||
this.widthOriginal = Math.abs(Math.floor(widthOriginal) || 0);
|
||||
this.heightOriginal = Math.abs(Math.floor(heightOriginal) || 0);
|
||||
this.targetWidth = Math.abs(Math.floor(targetWidth) || 0);
|
||||
this.targetHeight = Math.abs(Math.floor(targetHeight) || 0);
|
||||
this.colorChannels = blendAlpha ? 4 : 3;
|
||||
this.interpolationPass = Boolean(interpolationPass);
|
||||
this.resizeCallback =
|
||||
typeof resizeCallback === "function" ? resizeCallback : function () { };
|
||||
this.targetWidthMultipliedByChannels = this.targetWidth * this.colorChannels;
|
||||
this.originalWidthMultipliedByChannels =
|
||||
this.widthOriginal * this.colorChannels;
|
||||
this.originalHeightMultipliedByChannels =
|
||||
this.heightOriginal * this.colorChannels;
|
||||
this.widthPassResultSize =
|
||||
this.targetWidthMultipliedByChannels * this.heightOriginal;
|
||||
this.finalResultSize =
|
||||
this.targetWidthMultipliedByChannels * this.targetHeight;
|
||||
this.initialize();
|
||||
}
|
||||
Resize.prototype.initialize = function () {
|
||||
// Perform some checks:
|
||||
if (this.widthOriginal > 0 &&
|
||||
this.heightOriginal > 0 &&
|
||||
this.targetWidth > 0 &&
|
||||
this.targetHeight > 0) {
|
||||
this.configurePasses();
|
||||
}
|
||||
else {
|
||||
console.log(this);
|
||||
throw new Error("Invalid settings specified for the resizer.");
|
||||
}
|
||||
};
|
||||
Resize.prototype.configurePasses = function () {
|
||||
if (this.widthOriginal === this.targetWidth) {
|
||||
// Bypass the width resizer pass:
|
||||
this.resizeWidth = this.bypassResizer;
|
||||
}
|
||||
else {
|
||||
// Setup the width resizer pass:
|
||||
this.ratioWeightWidthPass = this.widthOriginal / this.targetWidth;
|
||||
if (this.ratioWeightWidthPass < 1 && this.interpolationPass) {
|
||||
this.initializeFirstPassBuffers(true);
|
||||
this.resizeWidth =
|
||||
this.colorChannels === 4
|
||||
? this.resizeWidthInterpolatedRGBA
|
||||
: this.resizeWidthInterpolatedRGB;
|
||||
}
|
||||
else {
|
||||
this.initializeFirstPassBuffers(false);
|
||||
this.resizeWidth =
|
||||
this.colorChannels === 4 ? this.resizeWidthRGBA : this.resizeWidthRGB;
|
||||
}
|
||||
}
|
||||
if (this.heightOriginal === this.targetHeight) {
|
||||
// Bypass the height resizer pass:
|
||||
this.resizeHeight = this.bypassResizer;
|
||||
}
|
||||
else {
|
||||
// Setup the height resizer pass:
|
||||
this.ratioWeightHeightPass = this.heightOriginal / this.targetHeight;
|
||||
if (this.ratioWeightHeightPass < 1 && this.interpolationPass) {
|
||||
this.initializeSecondPassBuffers(true);
|
||||
this.resizeHeight = this.resizeHeightInterpolated;
|
||||
}
|
||||
else {
|
||||
this.initializeSecondPassBuffers(false);
|
||||
this.resizeHeight =
|
||||
this.colorChannels === 4 ? this.resizeHeightRGBA : this.resizeHeightRGB;
|
||||
}
|
||||
}
|
||||
};
|
||||
Resize.prototype._resizeWidthInterpolatedRGBChannels = function (buffer, fourthChannel) {
|
||||
const channelsNum = fourthChannel ? 4 : 3;
|
||||
const ratioWeight = this.ratioWeightWidthPass;
|
||||
const outputBuffer = this.widthBuffer;
|
||||
let weight = 0;
|
||||
let finalOffset = 0;
|
||||
let pixelOffset = 0;
|
||||
let firstWeight = 0;
|
||||
let secondWeight = 0;
|
||||
let targetPosition;
|
||||
// Handle for only one interpolation input being valid for start calculation:
|
||||
for (targetPosition = 0; weight < 1 / 3; targetPosition += channelsNum, weight += ratioWeight) {
|
||||
for (finalOffset = targetPosition, pixelOffset = 0; finalOffset < this.widthPassResultSize; pixelOffset += this.originalWidthMultipliedByChannels,
|
||||
finalOffset += this.targetWidthMultipliedByChannels) {
|
||||
outputBuffer[finalOffset] = buffer[pixelOffset];
|
||||
outputBuffer[finalOffset + 1] = buffer[pixelOffset + 1];
|
||||
outputBuffer[finalOffset + 2] = buffer[pixelOffset + 2];
|
||||
if (fourthChannel)
|
||||
outputBuffer[finalOffset + 3] = buffer[pixelOffset + 3];
|
||||
}
|
||||
}
|
||||
// Adjust for overshoot of the last pass's counter:
|
||||
weight -= 1 / 3;
|
||||
let interpolationWidthSourceReadStop;
|
||||
for (interpolationWidthSourceReadStop = this.widthOriginal - 1; weight < interpolationWidthSourceReadStop; targetPosition += channelsNum, weight += ratioWeight) {
|
||||
// Calculate weightings:
|
||||
secondWeight = weight % 1;
|
||||
firstWeight = 1 - secondWeight;
|
||||
// Interpolate:
|
||||
for (finalOffset = targetPosition,
|
||||
pixelOffset = Math.floor(weight) * channelsNum; finalOffset < this.widthPassResultSize; pixelOffset += this.originalWidthMultipliedByChannels,
|
||||
finalOffset += this.targetWidthMultipliedByChannels) {
|
||||
outputBuffer[finalOffset + 0] =
|
||||
buffer[pixelOffset + 0] * firstWeight +
|
||||
buffer[pixelOffset + channelsNum + 0] * secondWeight;
|
||||
outputBuffer[finalOffset + 1] =
|
||||
buffer[pixelOffset + 1] * firstWeight +
|
||||
buffer[pixelOffset + channelsNum + 1] * secondWeight;
|
||||
outputBuffer[finalOffset + 2] =
|
||||
buffer[pixelOffset + 2] * firstWeight +
|
||||
buffer[pixelOffset + channelsNum + 2] * secondWeight;
|
||||
if (fourthChannel)
|
||||
outputBuffer[finalOffset + 3] =
|
||||
buffer[pixelOffset + 3] * firstWeight +
|
||||
buffer[pixelOffset + channelsNum + 3] * secondWeight;
|
||||
}
|
||||
}
|
||||
// Handle for only one interpolation input being valid for end calculation:
|
||||
for (interpolationWidthSourceReadStop =
|
||||
this.originalWidthMultipliedByChannels - channelsNum; targetPosition < this.targetWidthMultipliedByChannels; targetPosition += channelsNum) {
|
||||
for (finalOffset = targetPosition,
|
||||
pixelOffset = interpolationWidthSourceReadStop; finalOffset < this.widthPassResultSize; pixelOffset += this.originalWidthMultipliedByChannels,
|
||||
finalOffset += this.targetWidthMultipliedByChannels) {
|
||||
outputBuffer[finalOffset] = buffer[pixelOffset];
|
||||
outputBuffer[finalOffset + 1] = buffer[pixelOffset + 1];
|
||||
outputBuffer[finalOffset + 2] = buffer[pixelOffset + 2];
|
||||
if (fourthChannel)
|
||||
outputBuffer[finalOffset + 3] = buffer[pixelOffset + 3];
|
||||
}
|
||||
}
|
||||
return outputBuffer;
|
||||
};
|
||||
Resize.prototype._resizeWidthRGBChannels = function (buffer, fourthChannel) {
|
||||
const channelsNum = fourthChannel ? 4 : 3;
|
||||
const ratioWeight = this.ratioWeightWidthPass;
|
||||
const ratioWeightDivisor = 1 / ratioWeight;
|
||||
const nextLineOffsetOriginalWidth = this.originalWidthMultipliedByChannels - channelsNum + 1;
|
||||
const nextLineOffsetTargetWidth = this.targetWidthMultipliedByChannels - channelsNum + 1;
|
||||
const output = this.outputWidthWorkBench;
|
||||
const outputBuffer = this.widthBuffer;
|
||||
const trustworthyColorsCount = this.outputWidthWorkBenchOpaquePixelsCount;
|
||||
let weight = 0;
|
||||
let amountToNext = 0;
|
||||
let actualPosition = 0;
|
||||
let currentPosition = 0;
|
||||
let line = 0;
|
||||
let pixelOffset = 0;
|
||||
let outputOffset = 0;
|
||||
let multiplier = 1;
|
||||
let r = 0;
|
||||
let g = 0;
|
||||
let b = 0;
|
||||
let a = 0;
|
||||
do {
|
||||
for (line = 0; line < this.originalHeightMultipliedByChannels;) {
|
||||
output[line++] = 0;
|
||||
output[line++] = 0;
|
||||
output[line++] = 0;
|
||||
if (fourthChannel) {
|
||||
output[line++] = 0;
|
||||
trustworthyColorsCount[line / channelsNum - 1] = 0;
|
||||
}
|
||||
}
|
||||
weight = ratioWeight;
|
||||
do {
|
||||
amountToNext = 1 + actualPosition - currentPosition;
|
||||
multiplier = Math.min(weight, amountToNext);
|
||||
for (line = 0, pixelOffset = actualPosition; line < this.originalHeightMultipliedByChannels; pixelOffset += nextLineOffsetOriginalWidth) {
|
||||
r = buffer[pixelOffset];
|
||||
g = buffer[++pixelOffset];
|
||||
b = buffer[++pixelOffset];
|
||||
a = fourthChannel ? buffer[++pixelOffset] : 255;
|
||||
// Ignore RGB values if pixel is completely transparent
|
||||
output[line++] += (a ? r : 0) * multiplier;
|
||||
output[line++] += (a ? g : 0) * multiplier;
|
||||
output[line++] += (a ? b : 0) * multiplier;
|
||||
if (fourthChannel) {
|
||||
output[line++] += a * multiplier;
|
||||
trustworthyColorsCount[line / channelsNum - 1] += a ? multiplier : 0;
|
||||
}
|
||||
}
|
||||
if (weight >= amountToNext) {
|
||||
actualPosition += channelsNum;
|
||||
currentPosition = actualPosition;
|
||||
weight -= amountToNext;
|
||||
}
|
||||
else {
|
||||
currentPosition += weight;
|
||||
break;
|
||||
}
|
||||
} while (weight > 0 &&
|
||||
actualPosition < this.originalWidthMultipliedByChannels);
|
||||
for (line = 0, pixelOffset = outputOffset; line < this.originalHeightMultipliedByChannels; pixelOffset += nextLineOffsetTargetWidth) {
|
||||
weight = fourthChannel ? trustworthyColorsCount[line / channelsNum] : 1;
|
||||
multiplier = fourthChannel
|
||||
? weight
|
||||
? 1 / weight
|
||||
: 0
|
||||
: ratioWeightDivisor;
|
||||
outputBuffer[pixelOffset] = output[line++] * multiplier;
|
||||
outputBuffer[++pixelOffset] = output[line++] * multiplier;
|
||||
outputBuffer[++pixelOffset] = output[line++] * multiplier;
|
||||
if (fourthChannel)
|
||||
outputBuffer[++pixelOffset] = output[line++] * ratioWeightDivisor;
|
||||
}
|
||||
outputOffset += channelsNum;
|
||||
} while (outputOffset < this.targetWidthMultipliedByChannels);
|
||||
return outputBuffer;
|
||||
};
|
||||
Resize.prototype._resizeHeightRGBChannels = function (buffer, fourthChannel) {
|
||||
const ratioWeight = this.ratioWeightHeightPass;
|
||||
const ratioWeightDivisor = 1 / ratioWeight;
|
||||
const output = this.outputHeightWorkBench;
|
||||
const outputBuffer = this.heightBuffer;
|
||||
const trustworthyColorsCount = this.outputHeightWorkBenchOpaquePixelsCount;
|
||||
let weight = 0;
|
||||
let amountToNext = 0;
|
||||
let actualPosition = 0;
|
||||
let currentPosition = 0;
|
||||
let pixelOffset = 0;
|
||||
let outputOffset = 0;
|
||||
let caret = 0;
|
||||
let multiplier = 1;
|
||||
let r = 0;
|
||||
let g = 0;
|
||||
let b = 0;
|
||||
let a = 0;
|
||||
do {
|
||||
for (pixelOffset = 0; pixelOffset < this.targetWidthMultipliedByChannels;) {
|
||||
output[pixelOffset++] = 0;
|
||||
output[pixelOffset++] = 0;
|
||||
output[pixelOffset++] = 0;
|
||||
if (fourthChannel) {
|
||||
output[pixelOffset++] = 0;
|
||||
trustworthyColorsCount[pixelOffset / 4 - 1] = 0;
|
||||
}
|
||||
}
|
||||
weight = ratioWeight;
|
||||
do {
|
||||
amountToNext = 1 + actualPosition - currentPosition;
|
||||
multiplier = Math.min(weight, amountToNext);
|
||||
caret = actualPosition;
|
||||
for (pixelOffset = 0; pixelOffset < this.targetWidthMultipliedByChannels;) {
|
||||
r = buffer[caret++];
|
||||
g = buffer[caret++];
|
||||
b = buffer[caret++];
|
||||
a = fourthChannel ? buffer[caret++] : 255;
|
||||
// Ignore RGB values if pixel is completely transparent
|
||||
output[pixelOffset++] += (a ? r : 0) * multiplier;
|
||||
output[pixelOffset++] += (a ? g : 0) * multiplier;
|
||||
output[pixelOffset++] += (a ? b : 0) * multiplier;
|
||||
if (fourthChannel) {
|
||||
output[pixelOffset++] += a * multiplier;
|
||||
trustworthyColorsCount[pixelOffset / 4 - 1] += a ? multiplier : 0;
|
||||
}
|
||||
}
|
||||
if (weight >= amountToNext) {
|
||||
actualPosition = caret;
|
||||
currentPosition = actualPosition;
|
||||
weight -= amountToNext;
|
||||
}
|
||||
else {
|
||||
currentPosition += weight;
|
||||
break;
|
||||
}
|
||||
} while (weight > 0 && actualPosition < this.widthPassResultSize);
|
||||
for (pixelOffset = 0; pixelOffset < this.targetWidthMultipliedByChannels;) {
|
||||
weight = fourthChannel ? trustworthyColorsCount[pixelOffset / 4] : 1;
|
||||
multiplier = fourthChannel
|
||||
? weight
|
||||
? 1 / weight
|
||||
: 0
|
||||
: ratioWeightDivisor;
|
||||
outputBuffer[outputOffset++] = Math.round(output[pixelOffset++] * multiplier);
|
||||
outputBuffer[outputOffset++] = Math.round(output[pixelOffset++] * multiplier);
|
||||
outputBuffer[outputOffset++] = Math.round(output[pixelOffset++] * multiplier);
|
||||
if (fourthChannel) {
|
||||
outputBuffer[outputOffset++] = Math.round(output[pixelOffset++] * ratioWeightDivisor);
|
||||
}
|
||||
}
|
||||
} while (outputOffset < this.finalResultSize);
|
||||
return outputBuffer;
|
||||
};
|
||||
Resize.prototype.resizeWidthInterpolatedRGB = function (buffer) {
|
||||
return this._resizeWidthInterpolatedRGBChannels(buffer, false);
|
||||
};
|
||||
Resize.prototype.resizeWidthInterpolatedRGBA = function (buffer) {
|
||||
return this._resizeWidthInterpolatedRGBChannels(buffer, true);
|
||||
};
|
||||
Resize.prototype.resizeWidthRGB = function (buffer) {
|
||||
return this._resizeWidthRGBChannels(buffer, false);
|
||||
};
|
||||
Resize.prototype.resizeWidthRGBA = function (buffer) {
|
||||
return this._resizeWidthRGBChannels(buffer, true);
|
||||
};
|
||||
Resize.prototype.resizeHeightInterpolated = function (buffer) {
|
||||
const ratioWeight = this.ratioWeightHeightPass;
|
||||
const outputBuffer = this.heightBuffer;
|
||||
let weight = 0;
|
||||
let finalOffset = 0;
|
||||
let pixelOffset = 0;
|
||||
let pixelOffsetAccumulated = 0;
|
||||
let pixelOffsetAccumulated2 = 0;
|
||||
let firstWeight = 0;
|
||||
let secondWeight = 0;
|
||||
let interpolationHeightSourceReadStop;
|
||||
// Handle for only one interpolation input being valid for start calculation:
|
||||
for (; weight < 1 / 3; weight += ratioWeight) {
|
||||
for (pixelOffset = 0; pixelOffset < this.targetWidthMultipliedByChannels;) {
|
||||
outputBuffer[finalOffset++] = Math.round(buffer[pixelOffset++]);
|
||||
}
|
||||
}
|
||||
// Adjust for overshoot of the last pass's counter:
|
||||
weight -= 1 / 3;
|
||||
for (interpolationHeightSourceReadStop = this.heightOriginal - 1; weight < interpolationHeightSourceReadStop; weight += ratioWeight) {
|
||||
// Calculate weightings:
|
||||
secondWeight = weight % 1;
|
||||
firstWeight = 1 - secondWeight;
|
||||
// Interpolate:
|
||||
pixelOffsetAccumulated =
|
||||
Math.floor(weight) * this.targetWidthMultipliedByChannels;
|
||||
pixelOffsetAccumulated2 =
|
||||
pixelOffsetAccumulated + this.targetWidthMultipliedByChannels;
|
||||
for (pixelOffset = 0; pixelOffset < this.targetWidthMultipliedByChannels; ++pixelOffset) {
|
||||
outputBuffer[finalOffset++] = Math.round(buffer[pixelOffsetAccumulated++] * firstWeight +
|
||||
buffer[pixelOffsetAccumulated2++] * secondWeight);
|
||||
}
|
||||
}
|
||||
// Handle for only one interpolation input being valid for end calculation:
|
||||
while (finalOffset < this.finalResultSize) {
|
||||
for (pixelOffset = 0,
|
||||
pixelOffsetAccumulated =
|
||||
interpolationHeightSourceReadStop *
|
||||
this.targetWidthMultipliedByChannels; pixelOffset < this.targetWidthMultipliedByChannels; ++pixelOffset) {
|
||||
outputBuffer[finalOffset++] = Math.round(buffer[pixelOffsetAccumulated++]);
|
||||
}
|
||||
}
|
||||
return outputBuffer;
|
||||
};
|
||||
Resize.prototype.resizeHeightRGB = function (buffer) {
|
||||
return this._resizeHeightRGBChannels(buffer, false);
|
||||
};
|
||||
Resize.prototype.resizeHeightRGBA = function (buffer) {
|
||||
return this._resizeHeightRGBChannels(buffer, true);
|
||||
};
|
||||
Resize.prototype.resize = function (buffer) {
|
||||
this.resizeCallback(this.resizeHeight(this.resizeWidth(buffer)));
|
||||
};
|
||||
Resize.prototype.bypassResizer = function (buffer) {
|
||||
// Just return the buffer passed:
|
||||
return buffer;
|
||||
};
|
||||
Resize.prototype.initializeFirstPassBuffers = function (BILINEARAlgo) {
|
||||
// Initialize the internal width pass buffers:
|
||||
this.widthBuffer = this.generateFloatBuffer(this.widthPassResultSize);
|
||||
if (!BILINEARAlgo) {
|
||||
this.outputWidthWorkBench = this.generateFloatBuffer(this.originalHeightMultipliedByChannels);
|
||||
if (this.colorChannels > 3) {
|
||||
this.outputWidthWorkBenchOpaquePixelsCount = this.generateFloat64Buffer(this.heightOriginal);
|
||||
}
|
||||
}
|
||||
};
|
||||
Resize.prototype.initializeSecondPassBuffers = function (BILINEARAlgo) {
|
||||
// Initialize the internal height pass buffers:
|
||||
this.heightBuffer = this.generateUint8Buffer(this.finalResultSize);
|
||||
if (!BILINEARAlgo) {
|
||||
this.outputHeightWorkBench = this.generateFloatBuffer(this.targetWidthMultipliedByChannels);
|
||||
if (this.colorChannels > 3) {
|
||||
this.outputHeightWorkBenchOpaquePixelsCount = this.generateFloat64Buffer(this.targetWidth);
|
||||
}
|
||||
}
|
||||
};
|
||||
Resize.prototype.generateFloatBuffer = function (bufferLength) {
|
||||
// Generate a float32 typed array buffer:
|
||||
try {
|
||||
return new Float32Array(bufferLength);
|
||||
}
|
||||
catch (error) {
|
||||
console.error(error);
|
||||
return [];
|
||||
}
|
||||
};
|
||||
Resize.prototype.generateFloat64Buffer = function (bufferLength) {
|
||||
// Generate a float64 typed array buffer:
|
||||
try {
|
||||
return new Float64Array(bufferLength);
|
||||
}
|
||||
catch (error) {
|
||||
console.error(error);
|
||||
return [];
|
||||
}
|
||||
};
|
||||
Resize.prototype.generateUint8Buffer = function (bufferLength) {
|
||||
// Generate a uint8 typed array buffer:
|
||||
try {
|
||||
return new Uint8Array(bufferLength);
|
||||
}
|
||||
catch (error) {
|
||||
console.error(error);
|
||||
return [];
|
||||
}
|
||||
};
|
||||
export default Resize;
|
||||
//# sourceMappingURL=resize.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"resize.js","sourceRoot":"","sources":["../../../src/modules/resize.ts"],"names":[],"mappings":"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 truncated
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
/**
|
||||
* Copyright (c) 2015 Guyon Roche
|
||||
*
|
||||
* 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:</p>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
export declare const operations: {
|
||||
nearestNeighbor(src: any, dst: any): void;
|
||||
bilinearInterpolation(src: any, dst: any): void;
|
||||
_interpolate2D(src: any, dst: any, options?: any, interpolate?: any): void;
|
||||
bicubicInterpolation(src: any, dst: any, options?: any): void;
|
||||
hermiteInterpolation(src: any, dst: any, options?: any): void;
|
||||
bezierInterpolation(src: any, dst: any, options?: any): void;
|
||||
};
|
||||
//# sourceMappingURL=resize2.d.ts.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"resize2.d.ts","sourceRoot":"","sources":["../../../src/modules/resize2.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,eAAO,MAAM,UAAU;yBACA,GAAG,OAAO,GAAG;+BA0BP,GAAG,OAAO,GAAG;wBAuEpB,GAAG,OAAO,GAAG,YAAY,GAAG,gBAAgB,GAAG;8BAmIzC,GAAG,OAAO,GAAG,YAAY,GAAG;8BAqB5B,GAAG,OAAO,GAAG,YAAY,GAAG;6BAqB7B,GAAG,OAAO,GAAG,YAAY,GAAG;CAgCtD,CAAC"}
|
||||
+248
@@ -0,0 +1,248 @@
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
/**
|
||||
* Copyright (c) 2015 Guyon Roche
|
||||
*
|
||||
* 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:</p>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
export const operations = {
|
||||
nearestNeighbor(src, dst) {
|
||||
const wSrc = src.width;
|
||||
const hSrc = src.height;
|
||||
const wDst = dst.width;
|
||||
const hDst = dst.height;
|
||||
const bufSrc = src.data;
|
||||
const bufDst = dst.data;
|
||||
for (let i = 0; i < hDst; i++) {
|
||||
for (let j = 0; j < wDst; j++) {
|
||||
let posDst = (i * wDst + j) * 4;
|
||||
const iSrc = Math.floor((i * hSrc) / hDst);
|
||||
const jSrc = Math.floor((j * wSrc) / wDst);
|
||||
let posSrc = (iSrc * wSrc + jSrc) * 4;
|
||||
bufDst[posDst++] = bufSrc[posSrc++];
|
||||
bufDst[posDst++] = bufSrc[posSrc++];
|
||||
bufDst[posDst++] = bufSrc[posSrc++];
|
||||
bufDst[posDst++] = bufSrc[posSrc++];
|
||||
}
|
||||
}
|
||||
},
|
||||
bilinearInterpolation(src, dst) {
|
||||
const wSrc = src.width;
|
||||
const hSrc = src.height;
|
||||
const wDst = dst.width;
|
||||
const hDst = dst.height;
|
||||
const bufSrc = src.data;
|
||||
const bufDst = dst.data;
|
||||
const interpolate = function (k, kMin, vMin, kMax, vMax) {
|
||||
// special case - k is integer
|
||||
if (kMin === kMax) {
|
||||
return vMin;
|
||||
}
|
||||
return Math.round((k - kMin) * vMax + (kMax - k) * vMin);
|
||||
};
|
||||
const assign = function (pos, offset, x, xMin, xMax, y, yMin, yMax) {
|
||||
let posMin = (yMin * wSrc + xMin) * 4 + offset;
|
||||
let posMax = (yMin * wSrc + xMax) * 4 + offset;
|
||||
const vMin = interpolate(x, xMin, bufSrc[posMin], xMax, bufSrc[posMax]);
|
||||
// special case, y is integer
|
||||
if (yMax === yMin) {
|
||||
bufDst[pos + offset] = vMin;
|
||||
}
|
||||
else {
|
||||
posMin = (yMax * wSrc + xMin) * 4 + offset;
|
||||
posMax = (yMax * wSrc + xMax) * 4 + offset;
|
||||
const vMax = interpolate(x, xMin, bufSrc[posMin], xMax, bufSrc[posMax]);
|
||||
bufDst[pos + offset] = interpolate(y, yMin, vMin, yMax, vMax);
|
||||
}
|
||||
};
|
||||
for (let i = 0; i < hDst; i++) {
|
||||
for (let j = 0; j < wDst; j++) {
|
||||
const posDst = (i * wDst + j) * 4;
|
||||
// x & y in src coordinates
|
||||
const x = (j * wSrc) / wDst;
|
||||
const xMin = Math.floor(x);
|
||||
const xMax = Math.min(Math.ceil(x), wSrc - 1);
|
||||
const y = (i * hSrc) / hDst;
|
||||
const yMin = Math.floor(y);
|
||||
const yMax = Math.min(Math.ceil(y), hSrc - 1);
|
||||
assign(posDst, 0, x, xMin, xMax, y, yMin, yMax);
|
||||
assign(posDst, 1, x, xMin, xMax, y, yMin, yMax);
|
||||
assign(posDst, 2, x, xMin, xMax, y, yMin, yMax);
|
||||
assign(posDst, 3, x, xMin, xMax, y, yMin, yMax);
|
||||
}
|
||||
}
|
||||
},
|
||||
_interpolate2D(src, dst, options, interpolate) {
|
||||
const bufSrc = src.data;
|
||||
const bufDst = dst.data;
|
||||
const wSrc = src.width;
|
||||
const hSrc = src.height;
|
||||
const wDst = dst.width;
|
||||
const hDst = dst.height;
|
||||
// when dst smaller than src/2, interpolate first to a multiple between 0.5 and 1.0 src, then sum squares
|
||||
const wM = Math.max(1, Math.floor(wSrc / wDst));
|
||||
const wDst2 = wDst * wM;
|
||||
const hM = Math.max(1, Math.floor(hSrc / hDst));
|
||||
const hDst2 = hDst * hM;
|
||||
// ===========================================================
|
||||
// Pass 1 - interpolate rows
|
||||
// buf1 has width of dst2 and height of src
|
||||
const buf1 = Buffer.alloc(wDst2 * hSrc * 4);
|
||||
for (let i = 0; i < hSrc; i++) {
|
||||
for (let j = 0; j < wDst2; j++) {
|
||||
// i in src coords, j in dst coords
|
||||
// calculate x in src coords
|
||||
// this interpolation requires 4 sample points and the two inner ones must be real
|
||||
// the outer points can be fudged for the edges.
|
||||
// therefore (wSrc-1)/wDst2
|
||||
const x = (j * (wSrc - 1)) / wDst2;
|
||||
const xPos = Math.floor(x);
|
||||
const t = x - xPos;
|
||||
const srcPos = (i * wSrc + xPos) * 4;
|
||||
const buf1Pos = (i * wDst2 + j) * 4;
|
||||
for (let k = 0; k < 4; k++) {
|
||||
const kPos = srcPos + k;
|
||||
const x0 = xPos > 0 ? bufSrc[kPos - 4] : 2 * bufSrc[kPos] - bufSrc[kPos + 4];
|
||||
const x1 = bufSrc[kPos];
|
||||
const x2 = bufSrc[kPos + 4];
|
||||
const x3 = xPos < wSrc - 2
|
||||
? bufSrc[kPos + 8]
|
||||
: 2 * bufSrc[kPos + 4] - bufSrc[kPos];
|
||||
buf1[buf1Pos + k] = interpolate(x0, x1, x2, x3, t);
|
||||
}
|
||||
}
|
||||
}
|
||||
// this._writeFile(wDst2, hSrc, buf1, "out/buf1.jpg");
|
||||
// ===========================================================
|
||||
// Pass 2 - interpolate columns
|
||||
// buf2 has width and height of dst2
|
||||
const buf2 = Buffer.alloc(wDst2 * hDst2 * 4);
|
||||
for (let i = 0; i < hDst2; i++) {
|
||||
for (let j = 0; j < wDst2; j++) {
|
||||
// i&j in dst2 coords
|
||||
// calculate y in buf1 coords
|
||||
// this interpolation requires 4 sample points and the two inner ones must be real
|
||||
// the outer points can be fudged for the edges.
|
||||
// therefore (hSrc-1)/hDst2
|
||||
const y = (i * (hSrc - 1)) / hDst2;
|
||||
const yPos = Math.floor(y);
|
||||
const t = y - yPos;
|
||||
const buf1Pos = (yPos * wDst2 + j) * 4;
|
||||
const buf2Pos = (i * wDst2 + j) * 4;
|
||||
for (let k = 0; k < 4; k++) {
|
||||
const kPos = buf1Pos + k;
|
||||
const y0 = yPos > 0
|
||||
? buf1[kPos - wDst2 * 4]
|
||||
: 2 * buf1[kPos] - buf1[kPos + wDst2 * 4];
|
||||
const y1 = buf1[kPos];
|
||||
const y2 = buf1[kPos + wDst2 * 4];
|
||||
const y3 = yPos < hSrc - 2
|
||||
? buf1[kPos + wDst2 * 8]
|
||||
: 2 * buf1[kPos + wDst2 * 4] - buf1[kPos];
|
||||
buf2[buf2Pos + k] = interpolate(y0, y1, y2, y3, t);
|
||||
}
|
||||
}
|
||||
}
|
||||
// this._writeFile(wDst2, hDst2, buf2, "out/buf2.jpg");
|
||||
// ===========================================================
|
||||
// Pass 3 - scale to dst
|
||||
const m = wM * hM;
|
||||
if (m > 1) {
|
||||
for (let i = 0; i < hDst; i++) {
|
||||
for (let j = 0; j < wDst; j++) {
|
||||
// i&j in dst bounded coords
|
||||
let r = 0;
|
||||
let g = 0;
|
||||
let b = 0;
|
||||
let a = 0;
|
||||
let realColors = 0;
|
||||
for (let y = 0; y < hM; y++) {
|
||||
const yPos = i * hM + y;
|
||||
for (let x = 0; x < wM; x++) {
|
||||
const xPos = j * wM + x;
|
||||
const xyPos = (yPos * wDst2 + xPos) * 4;
|
||||
const pixelAlpha = buf2[xyPos + 3];
|
||||
if (pixelAlpha) {
|
||||
r += buf2[xyPos];
|
||||
g += buf2[xyPos + 1];
|
||||
b += buf2[xyPos + 2];
|
||||
realColors++;
|
||||
}
|
||||
a += pixelAlpha;
|
||||
}
|
||||
}
|
||||
const pos = (i * wDst + j) * 4;
|
||||
bufDst[pos] = realColors ? Math.round(r / realColors) : 0;
|
||||
bufDst[pos + 1] = realColors ? Math.round(g / realColors) : 0;
|
||||
bufDst[pos + 2] = realColors ? Math.round(b / realColors) : 0;
|
||||
bufDst[pos + 3] = Math.round(a / m);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// replace dst buffer with buf2
|
||||
dst.data = buf2;
|
||||
}
|
||||
},
|
||||
bicubicInterpolation(src, dst, options) {
|
||||
const interpolateCubic = function (x0, x1, x2, x3, t) {
|
||||
const a0 = x3 - x2 - x0 + x1;
|
||||
const a1 = x0 - x1 - a0;
|
||||
const a2 = x2 - x0;
|
||||
const a3 = x1;
|
||||
return Math.max(0, Math.min(255, a0 * (t * t * t) + a1 * (t * t) + a2 * t + a3));
|
||||
};
|
||||
return this._interpolate2D(src, dst, options, interpolateCubic);
|
||||
},
|
||||
hermiteInterpolation(src, dst, options) {
|
||||
const interpolateHermite = function (x0, x1, x2, x3, t) {
|
||||
const c0 = x1;
|
||||
const c1 = 0.5 * (x2 - x0);
|
||||
const c2 = x0 - 2.5 * x1 + 2 * x2 - 0.5 * x3;
|
||||
const c3 = 0.5 * (x3 - x0) + 1.5 * (x1 - x2);
|
||||
return Math.max(0, Math.min(255, Math.round(((c3 * t + c2) * t + c1) * t + c0)));
|
||||
};
|
||||
return this._interpolate2D(src, dst, options, interpolateHermite);
|
||||
},
|
||||
bezierInterpolation(src, dst, options) {
|
||||
// between 2 points y(n), y(n+1), use next points out, y(n-1), y(n+2)
|
||||
// to predict control points (a & b) to be placed at n+0.5
|
||||
// ya(n) = y(n) + (y(n+1)-y(n-1))/4
|
||||
// yb(n) = y(n+1) - (y(n+2)-y(n))/4
|
||||
// then use std bezier to interpolate [n,n+1)
|
||||
// y(n+t) = y(n)*(1-t)^3 + 3 * ya(n)*(1-t)^2*t + 3 * yb(n)*(1-t)*t^2 + y(n+1)*t^3
|
||||
// note the 3* factor for the two control points
|
||||
// for edge cases, can choose:
|
||||
// y(-1) = y(0) - 2*(y(1)-y(0))
|
||||
// y(w) = y(w-1) + 2*(y(w-1)-y(w-2))
|
||||
// but can go with y(-1) = y(0) and y(w) = y(w-1)
|
||||
const interpolateBezier = function (x0, x1, x2, x3, t) {
|
||||
// x1, x2 are the knots, use x0 and x3 to calculate control points
|
||||
const cp1 = x1 + (x2 - x0) / 4;
|
||||
const cp2 = x2 - (x3 - x1) / 4;
|
||||
const nt = 1 - t;
|
||||
const c0 = x1 * nt * nt * nt;
|
||||
const c1 = 3 * cp1 * nt * nt * t;
|
||||
const c2 = 3 * cp2 * nt * t * t;
|
||||
const c3 = x2 * t * t * t;
|
||||
return Math.max(0, Math.min(255, Math.round(c0 + c1 + c2 + c3)));
|
||||
};
|
||||
return this._interpolate2D(src, dst, options, interpolateBezier);
|
||||
},
|
||||
};
|
||||
//# sourceMappingURL=resize2.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"resize2.js","sourceRoot":"","sources":["../../../src/modules/resize2.ts"],"names":[],"mappings":"AAAA,uDAAuD;AACvD;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,eAAe,CAAC,GAAQ,EAAE,GAAQ;QAChC,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC;QACvB,MAAM,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC;QAExB,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC;QACvB,MAAM,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC;QAExB,MAAM,MAAM,GAAG,GAAG,CAAC,IAAI,CAAC;QACxB,MAAM,MAAM,GAAG,GAAG,CAAC,IAAI,CAAC;QAExB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC;YAC9B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC9B,IAAI,MAAM,GAAG,CAAC,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;gBAEhC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;gBAC3C,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;gBAC3C,IAAI,MAAM,GAAG,CAAC,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC;gBAEtC,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;gBACpC,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;gBACpC,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;gBACpC,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;YACtC,CAAC;QACH,CAAC;IACH,CAAC;IAED,qBAAqB,CAAC,GAAQ,EAAE,GAAQ;QACtC,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC;QACvB,MAAM,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC;QAExB,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC;QACvB,MAAM,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC;QAExB,MAAM,MAAM,GAAG,GAAG,CAAC,IAAI,CAAC;QACxB,MAAM,MAAM,GAAG,GAAG,CAAC,IAAI,CAAC;QAExB,MAAM,WAAW,GAAG,UAClB,CAAS,EACT,IAAY,EACZ,IAAY,EACZ,IAAY,EACZ,IAAY;YAEZ,8BAA8B;YAC9B,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;gBAClB,OAAO,IAAI,CAAC;YACd,CAAC;YAED,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;QAC3D,CAAC,CAAC;QAEF,MAAM,MAAM,GAAG,UACb,GAAW,EACX,MAAc,EACd,CAAS,EACT,IAAY,EACZ,IAAY,EACZ,CAAS,EACT,IAAY,EACZ,IAAY;YAEZ,IAAI,MAAM,GAAG,CAAC,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC;YAC/C,IAAI,MAAM,GAAG,CAAC,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC;YAC/C,MAAM,IAAI,GAAG,WAAW,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;YAExE,6BAA6B;YAC7B,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;gBAClB,MAAM,CAAC,GAAG,GAAG,MAAM,CAAC,GAAG,IAAI,CAAC;YAC9B,CAAC;iBAAM,CAAC;gBACN,MAAM,GAAG,CAAC,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC;gBAC3C,MAAM,GAAG,CAAC,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC;gBAC3C,MAAM,IAAI,GAAG,WAAW,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;gBAExE,MAAM,CAAC,GAAG,GAAG,MAAM,CAAC,GAAG,WAAW,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;YAChE,CAAC;QACH,CAAC,CAAC;QAEF,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC;YAC9B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC9B,MAAM,MAAM,GAAG,CAAC,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;gBAClC,2BAA2B;gBAC3B,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC;gBAC5B,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;gBAC3B,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC;gBAE9C,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC;gBAC5B,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;gBAC3B,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC;gBAE9C,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;gBAChD,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;gBAChD,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;gBAChD,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;YAClD,CAAC;QACH,CAAC;IACH,CAAC;IAED,cAAc,CAAC,GAAQ,EAAE,GAAQ,EAAE,OAAa,EAAE,WAAiB;QACjE,MAAM,MAAM,GAAG,GAAG,CAAC,IAAI,CAAC;QACxB,MAAM,MAAM,GAAG,GAAG,CAAC,IAAI,CAAC;QAExB,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC;QACvB,MAAM,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC;QAExB,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC;QACvB,MAAM,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC;QAExB,yGAAyG;QACzG,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC;QAChD,MAAM,KAAK,GAAG,IAAI,GAAG,EAAE,CAAC;QACxB,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC;QAChD,MAAM,KAAK,GAAG,IAAI,GAAG,EAAE,CAAC;QAExB,8DAA8D;QAC9D,4BAA4B;QAC5B,2CAA2C;QAC3C,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC;QAC5C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC;YAC9B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC/B,mCAAmC;gBAEnC,4BAA4B;gBAC5B,kFAAkF;gBAClF,gDAAgD;gBAChD,2BAA2B;gBAC3B,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC;gBACnC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;gBAC3B,MAAM,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;gBACnB,MAAM,MAAM,GAAG,CAAC,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CLine truncated
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"type": "module"
|
||||
}
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
import shared from "@jimp/config-eslint/base.js";
|
||||
export default [...shared];
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
{
|
||||
"name": "@jimp/plugin-resize",
|
||||
"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/core": "1.6.0",
|
||||
"@jimp/types": "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/test-utils": "1.6.0",
|
||||
"@types/node": "^18.19.48",
|
||||
"@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"
|
||||
}
|
||||
+445
@@ -0,0 +1,445 @@
|
||||
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
||||
|
||||
exports[`Resize images > max contrast 8x8 > to BEZIER 2x5 1`] = `
|
||||
Visualization:
|
||||
|
||||
■▩
|
||||
■▩
|
||||
■▩
|
||||
□D
|
||||
□D
|
||||
|
||||
Data:
|
||||
|
||||
00-00-00ᶠᶠ DF-DF-DFᶠᶠ
|
||||
00-00-00ᶠᶠ DF-DF-DFᶠᶠ
|
||||
00-00-00ᶠᶠ DF-DF-DFᶠᶠ
|
||||
FF-FF-FFᶠᶠ 20-20-20ᶠᶠ
|
||||
FF-FF-FFᶠᶠ 20-20-20ᶠᶠ
|
||||
`;
|
||||
|
||||
exports[`Resize images > max contrast 8x8 > to BEZIER 4x4 1`] = `
|
||||
Visualization:
|
||||
|
||||
■■D□
|
||||
■■D□
|
||||
DD3▩
|
||||
□□▩■
|
||||
|
||||
Data:
|
||||
|
||||
00-00-00ᶠᶠ 00-00-00ᶠᶠ C0-C0-C0ᶠᶠ FF-FF-FFᶠᶠ
|
||||
00-00-00ᶠᶠ 00-00-00ᶠᶠ C0-C0-C0ᶠᶠ FF-FF-FFᶠᶠ
|
||||
C0-C0-C0ᶠᶠ C0-C0-C0ᶠᶠ 60-60-60ᶠᶠ 40-40-40ᶠᶠ
|
||||
FF-FF-FFᶠᶠ FF-FF-FFᶠᶠ 40-40-40ᶠᶠ 00-00-00ᶠᶠ
|
||||
`;
|
||||
|
||||
exports[`Resize images > max contrast 8x8 > to BICUBIC 2x5 1`] = `
|
||||
Visualization:
|
||||
|
||||
■▩
|
||||
■▩
|
||||
■▩
|
||||
□D
|
||||
□D
|
||||
|
||||
Data:
|
||||
|
||||
00-00-00ᶠᶠ DF-DF-DFᶠᶠ
|
||||
00-00-00ᶠᶠ DF-DF-DFᶠᶠ
|
||||
00-00-00ᶠᶠ DF-DF-DFᶠᶠ
|
||||
FF-FF-FFᶠᶠ 20-20-20ᶠᶠ
|
||||
FF-FF-FFᶠᶠ 20-20-20ᶠᶠ
|
||||
`;
|
||||
|
||||
exports[`Resize images > max contrast 8x8 > to BICUBIC 4x4 1`] = `
|
||||
Visualization:
|
||||
|
||||
■■▥□
|
||||
■■▥□
|
||||
▥▥!▩
|
||||
□□▩■
|
||||
|
||||
Data:
|
||||
|
||||
00-00-00ᶠᶠ 00-00-00ᶠᶠ BF-BF-BFᶠᶠ FF-FF-FFᶠᶠ
|
||||
00-00-00ᶠᶠ 00-00-00ᶠᶠ BF-BF-BFᶠᶠ FF-FF-FFᶠᶠ
|
||||
BF-BF-BFᶠᶠ BF-BF-BFᶠᶠ 5F-5F-5Fᶠᶠ 40-40-40ᶠᶠ
|
||||
FF-FF-FFᶠᶠ FF-FF-FFᶠᶠ 40-40-40ᶠᶠ 00-00-00ᶠᶠ
|
||||
`;
|
||||
|
||||
exports[`Resize images > max contrast 8x8 > to BILINEAR 2x5 1`] = `
|
||||
Visualization:
|
||||
|
||||
■□
|
||||
■□
|
||||
3C
|
||||
□■
|
||||
□■
|
||||
|
||||
Data:
|
||||
|
||||
00-00-00ᶠᶠ FF-FF-FFᶠᶠ
|
||||
00-00-00ᶠᶠ FF-FF-FFᶠᶠ
|
||||
33-33-33ᶠᶠ CC-CC-CCᶠᶠ
|
||||
FF-FF-FFᶠᶠ 00-00-00ᶠᶠ
|
||||
FF-FF-FFᶠᶠ 00-00-00ᶠᶠ
|
||||
`;
|
||||
|
||||
exports[`Resize images > max contrast 8x8 > to BILINEAR 4x4 1`] = `
|
||||
Visualization:
|
||||
|
||||
■■□□
|
||||
■■□□
|
||||
□□■■
|
||||
□□■■
|
||||
|
||||
Data:
|
||||
|
||||
00-00-00ᶠᶠ 00-00-00ᶠᶠ FF-FF-FFᶠᶠ FF-FF-FFᶠᶠ
|
||||
00-00-00ᶠᶠ 00-00-00ᶠᶠ FF-FF-FFᶠᶠ FF-FF-FFᶠᶠ
|
||||
FF-FF-FFᶠᶠ FF-FF-FFᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ
|
||||
FF-FF-FFᶠᶠ FF-FF-FFᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ
|
||||
`;
|
||||
|
||||
exports[`Resize images > max contrast 8x8 > to HERMITE 2x5 1`] = `
|
||||
Visualization:
|
||||
|
||||
■▩
|
||||
■▩
|
||||
■▩
|
||||
□D
|
||||
□D
|
||||
|
||||
Data:
|
||||
|
||||
00-00-00ᶠᶠ DF-DF-DFᶠᶠ
|
||||
00-00-00ᶠᶠ DF-DF-DFᶠᶠ
|
||||
00-00-00ᶠᶠ DF-DF-DFᶠᶠ
|
||||
FF-FF-FFᶠᶠ 20-20-20ᶠᶠ
|
||||
FF-FF-FFᶠᶠ 20-20-20ᶠᶠ
|
||||
`;
|
||||
|
||||
exports[`Resize images > max contrast 8x8 > to HERMITE 4x4 1`] = `
|
||||
Visualization:
|
||||
|
||||
■■D□
|
||||
■■D□
|
||||
DD3▩
|
||||
□□▩■
|
||||
|
||||
Data:
|
||||
|
||||
00-00-00ᶠᶠ 00-00-00ᶠᶠ C0-C0-C0ᶠᶠ FF-FF-FFᶠᶠ
|
||||
00-00-00ᶠᶠ 00-00-00ᶠᶠ C0-C0-C0ᶠᶠ FF-FF-FFᶠᶠ
|
||||
C0-C0-C0ᶠᶠ C0-C0-C0ᶠᶠ 60-60-60ᶠᶠ 40-40-40ᶠᶠ
|
||||
FF-FF-FFᶠᶠ FF-FF-FFᶠᶠ 40-40-40ᶠᶠ 00-00-00ᶠᶠ
|
||||
`;
|
||||
|
||||
exports[`Resize images > max contrast 8x8 > to NEAREST_NEIGHBOR 2x5 1`] = `
|
||||
Visualization:
|
||||
|
||||
■□
|
||||
■□
|
||||
■□
|
||||
□■
|
||||
□■
|
||||
|
||||
Data:
|
||||
|
||||
00-00-00ᶠᶠ FF-FF-FFᶠᶠ
|
||||
00-00-00ᶠᶠ FF-FF-FFᶠᶠ
|
||||
00-00-00ᶠᶠ FF-FF-FFᶠᶠ
|
||||
FF-FF-FFᶠᶠ 00-00-00ᶠᶠ
|
||||
FF-FF-FFᶠᶠ 00-00-00ᶠᶠ
|
||||
`;
|
||||
|
||||
exports[`Resize images > max contrast 8x8 > to NEAREST_NEIGHBOR 4x4 1`] = `
|
||||
Visualization:
|
||||
|
||||
■■□□
|
||||
■■□□
|
||||
□□■■
|
||||
□□■■
|
||||
|
||||
Data:
|
||||
|
||||
00-00-00ᶠᶠ 00-00-00ᶠᶠ FF-FF-FFᶠᶠ FF-FF-FFᶠᶠ
|
||||
00-00-00ᶠᶠ 00-00-00ᶠᶠ FF-FF-FFᶠᶠ FF-FF-FFᶠᶠ
|
||||
FF-FF-FFᶠᶠ FF-FF-FFᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ
|
||||
FF-FF-FFᶠᶠ FF-FF-FFᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ
|
||||
`;
|
||||
|
||||
exports[`Resize images > max contrast 8x8 > to default 2x5 1`] = `
|
||||
Visualization:
|
||||
|
||||
■□
|
||||
■□
|
||||
▦▦
|
||||
□■
|
||||
□■
|
||||
|
||||
Data:
|
||||
|
||||
00-00-00ᶠᶠ FF-FF-FFᶠᶠ
|
||||
00-00-00ᶠᶠ FF-FF-FFᶠᶠ
|
||||
80-80-80ᶠᶠ 80-80-80ᶠᶠ
|
||||
FF-FF-FFᶠᶠ 00-00-00ᶠᶠ
|
||||
FF-FF-FFᶠᶠ 00-00-00ᶠᶠ
|
||||
`;
|
||||
|
||||
exports[`Resize images > max contrast 8x8 > to default 4x4 1`] = `
|
||||
Visualization:
|
||||
|
||||
■■□□
|
||||
■■□□
|
||||
□□■■
|
||||
□□■■
|
||||
|
||||
Data:
|
||||
|
||||
00-00-00ᶠᶠ 00-00-00ᶠᶠ FF-FF-FFᶠᶠ FF-FF-FFᶠᶠ
|
||||
00-00-00ᶠᶠ 00-00-00ᶠᶠ FF-FF-FFᶠᶠ FF-FF-FFᶠᶠ
|
||||
FF-FF-FFᶠᶠ FF-FF-FFᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ
|
||||
FF-FF-FFᶠᶠ FF-FF-FFᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ
|
||||
`;
|
||||
|
||||
exports[`Resize images > max contrast 12x12 with dots > to BEZIER 6x6 1`] = `
|
||||
Visualization:
|
||||
|
||||
■■■D□□
|
||||
■4◇D◇□
|
||||
■■■D□□
|
||||
DDD3▩▩
|
||||
□▴◇▩3■
|
||||
□D▩▩▴■
|
||||
|
||||
Data:
|
||||
|
||||
00-00-00ᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ C0-C0-C0ᶠᶠ FF-FF-FFᶠᶠ FF-FF-FFᶠᶠ
|
||||
00-00-00ᶠᶠ 44-44-44ᶠᶠ 1D-1D-1Dᶠᶠ C0-C0-C0ᶠᶠ 9F-9F-9Fᶠᶠ FF-FF-FFᶠᶠ
|
||||
00-00-00ᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ C0-C0-C0ᶠᶠ FF-FF-FFᶠᶠ FF-FF-FFᶠᶠ
|
||||
C0-C0-C0ᶠᶠ C0-C0-C0ᶠᶠ C0-C0-C0ᶠᶠ 60-60-60ᶠᶠ 40-40-40ᶠᶠ 40-40-40ᶠᶠ
|
||||
FF-FF-FFᶠᶠ F0-F0-F0ᶠᶠ F9-F9-F9ᶠᶠ 40-40-40ᶠᶠ 15-15-15ᶠᶠ 00-00-00ᶠᶠ
|
||||
FF-FF-FFᶠᶠ CA-CA-CAᶠᶠ E9-E9-E9ᶠᶠ 40-40-40ᶠᶠ 4B-4B-4Bᶠᶠ 00-00-00ᶠᶠ
|
||||
`;
|
||||
|
||||
exports[`Resize images > max contrast 12x12 with dots > to BICUBIC 6x6 1`] = `
|
||||
Visualization:
|
||||
|
||||
■■■▥□□
|
||||
■3D▥3□
|
||||
■■■▥□□
|
||||
▥▥▥!▩▩
|
||||
□ED▩◇■
|
||||
□3▴▩▩■
|
||||
|
||||
Data:
|
||||
|
||||
00-00-00ᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ BF-BF-BFᶠᶠ FF-FF-FFᶠᶠ FF-FF-FFᶠᶠ
|
||||
00-00-00ᶠᶠ 47-47-47ᶠᶠ 20-20-20ᶠᶠ BF-BF-BFᶠᶠ 97-97-97ᶠᶠ FF-FF-FFᶠᶠ
|
||||
00-00-00ᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ BF-BF-BFᶠᶠ FF-FF-FFᶠᶠ FF-FF-FFᶠᶠ
|
||||
BF-BF-BFᶠᶠ BF-BF-BFᶠᶠ BF-BF-BFᶠᶠ 5F-5F-5Fᶠᶠ 40-40-40ᶠᶠ 40-40-40ᶠᶠ
|
||||
FF-FF-FFᶠᶠ EE-EE-EEᶠᶠ F7-F7-F7ᶠᶠ 40-40-40ᶠᶠ 18-18-18ᶠᶠ 00-00-00ᶠᶠ
|
||||
FF-FF-FFᶠᶠ C9-C9-C9ᶠᶠ E6-E6-E6ᶠᶠ 40-40-40ᶠᶠ 4E-4E-4Eᶠᶠ 00-00-00ᶠᶠ
|
||||
`;
|
||||
|
||||
exports[`Resize images > max contrast 12x12 with dots > to BILINEAR 6x6 1`] = `
|
||||
Visualization:
|
||||
|
||||
■■■□□□
|
||||
■■■□■□
|
||||
■■■□□□
|
||||
□□□■■■
|
||||
□□□■■■
|
||||
□□□■■■
|
||||
|
||||
Data:
|
||||
|
||||
00-00-00ᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ FF-FF-FFᶠᶠ FF-FF-FFᶠᶠ FF-FF-FFᶠᶠ
|
||||
00-00-00ᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ FF-FF-FFᶠᶠ 00-00-00ᶠᶠ FF-FF-FFᶠᶠ
|
||||
00-00-00ᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ FF-FF-FFᶠᶠ FF-FF-FFᶠᶠ FF-FF-FFᶠᶠ
|
||||
FF-FF-FFᶠᶠ FF-FF-FFᶠᶠ FF-FF-FFᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ
|
||||
FF-FF-FFᶠᶠ FF-FF-FFᶠᶠ FF-FF-FFᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ
|
||||
FF-FF-FFᶠᶠ FF-FF-FFᶠᶠ FF-FF-FFᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ
|
||||
`;
|
||||
|
||||
exports[`Resize images > max contrast 12x12 with dots > to HERMITE 6x6 1`] = `
|
||||
Visualization:
|
||||
|
||||
■■■D□□
|
||||
■▩▴D3□
|
||||
■■■D□□
|
||||
DDD3▩▩
|
||||
□▩▴▩1■
|
||||
□▩▴▩D■
|
||||
|
||||
Data:
|
||||
|
||||
00-00-00ᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ C0-C0-C0ᶠᶠ FF-FF-FFᶠᶠ FF-FF-FFᶠᶠ
|
||||
00-00-00ᶠᶠ 40-40-40ᶠᶠ 19-19-19ᶠᶠ C0-C0-C0ᶠᶠ A6-A6-A6ᶠᶠ FF-FF-FFᶠᶠ
|
||||
00-00-00ᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ C0-C0-C0ᶠᶠ FF-FF-FFᶠᶠ FF-FF-FFᶠᶠ
|
||||
C0-C0-C0ᶠᶠ C0-C0-C0ᶠᶠ C0-C0-C0ᶠᶠ 60-60-60ᶠᶠ 40-40-40ᶠᶠ 40-40-40ᶠᶠ
|
||||
FF-FF-FFᶠᶠ F3-F3-F3ᶠᶠ FA-FA-FAᶠᶠ 40-40-40ᶠᶠ 11-11-11ᶠᶠ 00-00-00ᶠᶠ
|
||||
FF-FF-FFᶠᶠ CB-CB-CBᶠᶠ EB-EB-EBᶠᶠ 40-40-40ᶠᶠ 48-48-48ᶠᶠ 00-00-00ᶠᶠ
|
||||
`;
|
||||
|
||||
exports[`Resize images > max contrast 12x12 with dots > to NEAREST_NEIGHBOR 6x6 1`] = `
|
||||
Visualization:
|
||||
|
||||
■■■□□□
|
||||
■■■□■□
|
||||
■■■□□□
|
||||
□□□■■■
|
||||
□□□■■■
|
||||
□□□■■■
|
||||
|
||||
Data:
|
||||
|
||||
00-00-00ᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ FF-FF-FFᶠᶠ FF-FF-FFᶠᶠ FF-FF-FFᶠᶠ
|
||||
00-00-00ᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ FF-FF-FFᶠᶠ 00-00-00ᶠᶠ FF-FF-FFᶠᶠ
|
||||
00-00-00ᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ FF-FF-FFᶠᶠ FF-FF-FFᶠᶠ FF-FF-FFᶠᶠ
|
||||
FF-FF-FFᶠᶠ FF-FF-FFᶠᶠ FF-FF-FFᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ
|
||||
FF-FF-FFᶠᶠ FF-FF-FFᶠᶠ FF-FF-FFᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ
|
||||
FF-FF-FFᶠᶠ FF-FF-FFᶠᶠ FF-FF-FFᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ
|
||||
`;
|
||||
|
||||
exports[`Resize images > max contrast 12x12 with dots > to default 6x6 1`] = `
|
||||
Visualization:
|
||||
|
||||
■■■□□□
|
||||
■▩■□▥□
|
||||
■■■□□□
|
||||
□□□■■■
|
||||
□▥□■▩■
|
||||
□□□■■■
|
||||
|
||||
Data:
|
||||
|
||||
00-00-00ᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ FF-FF-FFᶠᶠ FF-FF-FFᶠᶠ FF-FF-FFᶠᶠ
|
||||
00-00-00ᶠᶠ 40-40-40ᶠᶠ 00-00-00ᶠᶠ FF-FF-FFᶠᶠ BF-BF-BFᶠᶠ FF-FF-FFᶠᶠ
|
||||
00-00-00ᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ FF-FF-FFᶠᶠ FF-FF-FFᶠᶠ FF-FF-FFᶠᶠ
|
||||
FF-FF-FFᶠᶠ FF-FF-FFᶠᶠ FF-FF-FFᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ
|
||||
FF-FF-FFᶠᶠ BF-BF-BFᶠᶠ FF-FF-FFᶠᶠ 00-00-00ᶠᶠ 40-40-40ᶠᶠ 00-00-00ᶠᶠ
|
||||
FF-FF-FFᶠᶠ FF-FF-FFᶠᶠ FF-FF-FFᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ
|
||||
`;
|
||||
|
||||
exports[`Resize images > mutch contrast 4x4 > to BEZIER 6x6 1`] = `
|
||||
Visualization:
|
||||
|
||||
▩D▩▦▥▩
|
||||
D▩D▦▩D
|
||||
▩D▩▦▥▩
|
||||
▦▦▦▦▦▦
|
||||
▥▩▥▦▩D
|
||||
▩D▩▦D▩
|
||||
|
||||
Data:
|
||||
|
||||
40-40-40ᶠᶠ 34-34-34ᶠᶠ 40-40-40ᶠᶠ 80-80-80ᶠᶠ BF-BF-BFᶠᶠ CB-CB-CBᶠᶠ
|
||||
34-34-34ᶠᶠ 26-26-26ᶠᶠ 34-34-34ᶠᶠ 80-80-80ᶠᶠ CB-CB-CBᶠᶠ D9-D9-D9ᶠᶠ
|
||||
40-40-40ᶠᶠ 34-34-34ᶠᶠ 40-40-40ᶠᶠ 80-80-80ᶠᶠ BF-BF-BFᶠᶠ CB-CB-CBᶠᶠ
|
||||
80-80-80ᶠᶠ 80-80-80ᶠᶠ 80-80-80ᶠᶠ 80-80-80ᶠᶠ 80-80-80ᶠᶠ 80-80-80ᶠᶠ
|
||||
BF-BF-BFᶠᶠ CB-CB-CBᶠᶠ BF-BF-BFᶠᶠ 80-80-80ᶠᶠ 40-40-40ᶠᶠ 34-34-34ᶠᶠ
|
||||
CB-CB-CBᶠᶠ D9-D9-D9ᶠᶠ CB-CB-CBᶠᶠ 80-80-80ᶠᶠ 34-34-34ᶠᶠ 26-26-26ᶠᶠ
|
||||
`;
|
||||
|
||||
exports[`Resize images > mutch contrast 4x4 > to BICUBIC 6x6 1`] = `
|
||||
Visualization:
|
||||
|
||||
▩▩▩D▥3
|
||||
▩▩▩D3▴
|
||||
▩▩▩D▥3
|
||||
DDDDDD
|
||||
▥3▥D▩▩
|
||||
3▴3D▩▩
|
||||
|
||||
Data:
|
||||
|
||||
40-40-40ᶠᶠ 30-30-30ᶠᶠ 40-40-40ᶠᶠ 7F-7F-7Fᶠᶠ BF-BF-BFᶠᶠ CE-CE-CEᶠᶠ
|
||||
30-30-30ᶠᶠ 1C-1C-1Cᶠᶠ 30-30-30ᶠᶠ 7F-7F-7Fᶠᶠ CE-CE-CEᶠᶠ E1-E1-E1ᶠᶠ
|
||||
40-40-40ᶠᶠ 30-30-30ᶠᶠ 40-40-40ᶠᶠ 7F-7F-7Fᶠᶠ BF-BF-BFᶠᶠ CE-CE-CEᶠᶠ
|
||||
7F-7F-7Fᶠᶠ 7F-7F-7Fᶠᶠ 7F-7F-7Fᶠᶠ 7F-7F-7Fᶠᶠ 7F-7F-7Fᶠᶠ 7F-7F-7Fᶠᶠ
|
||||
BF-BF-BFᶠᶠ CE-CE-CEᶠᶠ BF-BF-BFᶠᶠ 7F-7F-7Fᶠᶠ 40-40-40ᶠᶠ 30-30-30ᶠᶠ
|
||||
CE-CE-CEᶠᶠ E1-E1-E1ᶠᶠ CE-CE-CEᶠᶠ 7F-7F-7Fᶠᶠ 30-30-30ᶠᶠ 1C-1C-1Cᶠᶠ
|
||||
`;
|
||||
|
||||
exports[`Resize images > mutch contrast 4x4 > to BILINEAR 6x6 1`] = `
|
||||
Visualization:
|
||||
|
||||
▩▩3▥▥▥
|
||||
▩▩3▥▥▥
|
||||
33▴◇◇◇
|
||||
▥▥◇▩▩▩
|
||||
▥▥◇▩▩▩
|
||||
▥▥◇▩▩▩
|
||||
|
||||
Data:
|
||||
|
||||
40-40-40ᶠᶠ 40-40-40ᶠᶠ 6A-6A-6Aᶠᶠ BF-BF-BFᶠᶠ BF-BF-BFᶠᶠ BF-BF-BFᶠᶠ
|
||||
40-40-40ᶠᶠ 40-40-40ᶠᶠ 6A-6A-6Aᶠᶠ BF-BF-BFᶠᶠ BF-BF-BFᶠᶠ BF-BF-BFᶠᶠ
|
||||
6A-6A-6Aᶠᶠ 6A-6A-6Aᶠᶠ 78-78-78ᶠᶠ 95-95-95ᶠᶠ 95-95-95ᶠᶠ 95-95-95ᶠᶠ
|
||||
BF-BF-BFᶠᶠ BF-BF-BFᶠᶠ 95-95-95ᶠᶠ 40-40-40ᶠᶠ 40-40-40ᶠᶠ 40-40-40ᶠᶠ
|
||||
BF-BF-BFᶠᶠ BF-BF-BFᶠᶠ 95-95-95ᶠᶠ 40-40-40ᶠᶠ 40-40-40ᶠᶠ 40-40-40ᶠᶠ
|
||||
BF-BF-BFᶠᶠ BF-BF-BFᶠᶠ 95-95-95ᶠᶠ 40-40-40ᶠᶠ 40-40-40ᶠᶠ 40-40-40ᶠᶠ
|
||||
`;
|
||||
|
||||
exports[`Resize images > mutch contrast 4x4 > to HERMITE 6x6 1`] = `
|
||||
Visualization:
|
||||
|
||||
▩3▩▦▥◇
|
||||
3D3▦◇▩
|
||||
▩3▩▦▥◇
|
||||
▦▦▦▦▦▦
|
||||
▥◇▥▦▩3
|
||||
◇▩◇▦3D
|
||||
|
||||
Data:
|
||||
|
||||
40-40-40ᶠᶠ 38-38-38ᶠᶠ 40-40-40ᶠᶠ 80-80-80ᶠᶠ BF-BF-BFᶠᶠ C7-C7-C7ᶠᶠ
|
||||
38-38-38ᶠᶠ 2F-2F-2Fᶠᶠ 38-38-38ᶠᶠ 80-80-80ᶠᶠ C7-C7-C7ᶠᶠ D0-D0-D0ᶠᶠ
|
||||
40-40-40ᶠᶠ 38-38-38ᶠᶠ 40-40-40ᶠᶠ 80-80-80ᶠᶠ BF-BF-BFᶠᶠ C7-C7-C7ᶠᶠ
|
||||
80-80-80ᶠᶠ 80-80-80ᶠᶠ 80-80-80ᶠᶠ 80-80-80ᶠᶠ 80-80-80ᶠᶠ 80-80-80ᶠᶠ
|
||||
BF-BF-BFᶠᶠ C7-C7-C7ᶠᶠ BF-BF-BFᶠᶠ 80-80-80ᶠᶠ 40-40-40ᶠᶠ 38-38-38ᶠᶠ
|
||||
C7-C7-C7ᶠᶠ D0-D0-D0ᶠᶠ C7-C7-C7ᶠᶠ 80-80-80ᶠᶠ 38-38-38ᶠᶠ 2F-2F-2Fᶠᶠ
|
||||
`;
|
||||
|
||||
exports[`Resize images > mutch contrast 4x4 > to NEAREST_NEIGHBOR 6x6 1`] = `
|
||||
Visualization:
|
||||
|
||||
▩▩▩▥▥▥
|
||||
▩▩▩▥▥▥
|
||||
▩▩▩▥▥▥
|
||||
▥▥▥▩▩▩
|
||||
▥▥▥▩▩▩
|
||||
▥▥▥▩▩▩
|
||||
|
||||
Data:
|
||||
|
||||
40-40-40ᶠᶠ 40-40-40ᶠᶠ 40-40-40ᶠᶠ BF-BF-BFᶠᶠ BF-BF-BFᶠᶠ BF-BF-BFᶠᶠ
|
||||
40-40-40ᶠᶠ 40-40-40ᶠᶠ 40-40-40ᶠᶠ BF-BF-BFᶠᶠ BF-BF-BFᶠᶠ BF-BF-BFᶠᶠ
|
||||
40-40-40ᶠᶠ 40-40-40ᶠᶠ 40-40-40ᶠᶠ BF-BF-BFᶠᶠ BF-BF-BFᶠᶠ BF-BF-BFᶠᶠ
|
||||
BF-BF-BFᶠᶠ BF-BF-BFᶠᶠ BF-BF-BFᶠᶠ 40-40-40ᶠᶠ 40-40-40ᶠᶠ 40-40-40ᶠᶠ
|
||||
BF-BF-BFᶠᶠ BF-BF-BFᶠᶠ BF-BF-BFᶠᶠ 40-40-40ᶠᶠ 40-40-40ᶠᶠ 40-40-40ᶠᶠ
|
||||
BF-BF-BFᶠᶠ BF-BF-BFᶠᶠ BF-BF-BFᶠᶠ 40-40-40ᶠᶠ 40-40-40ᶠᶠ 40-40-40ᶠᶠ
|
||||
`;
|
||||
|
||||
exports[`Resize images > mutch contrast 4x4 > to default 6x6 1`] = `
|
||||
Visualization:
|
||||
|
||||
▩▩▩◇▥▥
|
||||
▩▩▩◇▥▥
|
||||
▩▩▩◇▥▥
|
||||
◇◇◇▴33
|
||||
▥▥▥3▩▩
|
||||
▥▥▥3▩▩
|
||||
|
||||
Data:
|
||||
|
||||
40-40-40ᶠᶠ 40-40-40ᶠᶠ 40-40-40ᶠᶠ 95-95-95ᶠᶠ BF-BF-BFᶠᶠ BF-BF-BFᶠᶠ
|
||||
40-40-40ᶠᶠ 40-40-40ᶠᶠ 40-40-40ᶠᶠ 95-95-95ᶠᶠ BF-BF-BFᶠᶠ BF-BF-BFᶠᶠ
|
||||
40-40-40ᶠᶠ 40-40-40ᶠᶠ 40-40-40ᶠᶠ 95-95-95ᶠᶠ BF-BF-BFᶠᶠ BF-BF-BFᶠᶠ
|
||||
95-95-95ᶠᶠ 95-95-95ᶠᶠ 95-95-95ᶠᶠ 78-78-78ᶠᶠ 6A-6A-6Aᶠᶠ 6A-6A-6Aᶠᶠ
|
||||
BF-BF-BFᶠᶠ BF-BF-BFᶠᶠ BF-BF-BFᶠᶠ 6A-6A-6Aᶠᶠ 40-40-40ᶠᶠ 40-40-40ᶠᶠ
|
||||
BF-BF-BFᶠᶠ BF-BF-BFᶠᶠ BF-BF-BFᶠᶠ 6A-6A-6Aᶠᶠ 40-40-40ᶠᶠ 40-40-40ᶠᶠ
|
||||
`;
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* What resizing algorithm to use.
|
||||
*/
|
||||
export enum ResizeStrategy {
|
||||
/**
|
||||
* Nearest Neighbor resizing is a method used in image processing that assigns the value of the nearest pixel to the output pixel when resizing an image.
|
||||
* While fast, it can lead to lower quality outputs with noticeable pixelation, especially at larger scaling factors.
|
||||
*/
|
||||
NEAREST_NEIGHBOR = "nearestNeighbor",
|
||||
/**
|
||||
* Bilinear resizing is an image scaling method that uses the weighted average of the four nearest pixel values, providing smoother gradients than nearest neighbor resizing.
|
||||
* It's computationally more intense than nearest neighbor but results in images of higher quality and fewer artifacts.
|
||||
*/
|
||||
BILINEAR = "bilinearInterpolation",
|
||||
/**
|
||||
* Bicubic resizing is an image interpolation method that uses the values of the nearest 16 pixels in the input image to calculate the output pixel value, providing even more smoothness and sharpness than bilinear resizing.
|
||||
* Although it's computationally more expensive than bilinear and nearest neighbor, it produces higher quality images, making it ideal for photographic image scaling.
|
||||
*/
|
||||
BICUBIC = "bicubicInterpolation",
|
||||
/**
|
||||
* Hermite resizing is an image resizing method that uses Hermite interpolation, a mathematical formula, to determine the values of output pixels based on a weighted average of the surrounding pixels.
|
||||
* Although slower than some simpler techniques like bilinear or nearest neighbor, Hermite resizing can produce higher quality visuals and detailed renderings with less blurring.
|
||||
*/
|
||||
HERMITE = "hermiteInterpolation",
|
||||
BEZIER = "bezierInterpolation",
|
||||
}
|
||||
+101
@@ -0,0 +1,101 @@
|
||||
import { expect, test, describe } from "vitest";
|
||||
|
||||
import { makeTestImage } from "@jimp/test-utils";
|
||||
import { createJimp } from "@jimp/core";
|
||||
|
||||
import { methods, ResizeStrategy } from "./index.js";
|
||||
|
||||
const jimp = createJimp({ plugins: [methods], formats: [] });
|
||||
|
||||
describe("Resize images", () => {
|
||||
const testImages = [
|
||||
{
|
||||
title: "max contrast 8x8",
|
||||
src: jimp.fromBitmap(
|
||||
makeTestImage(
|
||||
"■■■■□□□□",
|
||||
"■■■■□□□□",
|
||||
"■■■■□□□□",
|
||||
"■■■■□□□□",
|
||||
"□□□□■■■■",
|
||||
"□□□□■■■■",
|
||||
"□□□□■■■■",
|
||||
"□□□□■■■■"
|
||||
)
|
||||
),
|
||||
tests: [
|
||||
{ mode: "default", size: { height: 4, width: 4 } },
|
||||
{ mode: "NEAREST_NEIGHBOR", size: { height: 4, width: 4 } },
|
||||
{ mode: "BILINEAR", size: { height: 4, width: 4 } },
|
||||
{ mode: "BICUBIC", size: { height: 4, width: 4 } },
|
||||
{ mode: "HERMITE", size: { height: 4, width: 4 } },
|
||||
{ mode: "BEZIER", size: { height: 4, width: 4 } },
|
||||
{ mode: "default", size: { height: 5, width: 2 } },
|
||||
{ mode: "NEAREST_NEIGHBOR", size: { height: 5, width: 2 } },
|
||||
{ mode: "BILINEAR", size: { height: 5, width: 2 } },
|
||||
{ mode: "BICUBIC", size: { height: 5, width: 2 } },
|
||||
{ mode: "HERMITE", size: { height: 5, width: 2 } },
|
||||
{ mode: "BEZIER", size: { height: 5, width: 2 } },
|
||||
],
|
||||
},
|
||||
/**********************************************************************/
|
||||
{
|
||||
title: "max contrast 12x12 with dots",
|
||||
src: jimp.fromBitmap(
|
||||
makeTestImage(
|
||||
"■■■■■■□□□□□□",
|
||||
"■■■■■■□□□□□□",
|
||||
"■■■□■■□□■□□□",
|
||||
"■■■■■■□□□□□□",
|
||||
"■■■■■■□□□□□□",
|
||||
"■■■■■■□□□□□□",
|
||||
"□□□□□□■■■■■■",
|
||||
"□□□□□□■■■■■■",
|
||||
"□□□□□□■■■■■■",
|
||||
"□□□■□□■■□■■■",
|
||||
"□□□□□□■■■■■■",
|
||||
"□□□□□□■■■■■■"
|
||||
)
|
||||
),
|
||||
tests: [
|
||||
{ mode: "default", size: { height: 6, width: 6 } },
|
||||
{ mode: "NEAREST_NEIGHBOR", size: { height: 6, width: 6 } },
|
||||
{ mode: "BILINEAR", size: { height: 6, width: 6 } },
|
||||
{ mode: "BICUBIC", size: { height: 6, width: 6 } },
|
||||
{ mode: "HERMITE", size: { height: 6, width: 6 } },
|
||||
{ mode: "BEZIER", size: { height: 6, width: 6 } },
|
||||
],
|
||||
},
|
||||
/**********************************************************************/
|
||||
{
|
||||
title: "mutch contrast 4x4",
|
||||
src: jimp.fromBitmap(makeTestImage("▩▩▥▥", "▩▩▥▥", "▥▥▩▩", "▥▥▩▩")),
|
||||
tests: [
|
||||
{ mode: "default", size: { height: 6, width: 6 } },
|
||||
{ mode: "NEAREST_NEIGHBOR", size: { height: 6, width: 6 } },
|
||||
{ mode: "BILINEAR", size: { height: 6, width: 6 } },
|
||||
{ mode: "BICUBIC", size: { height: 6, width: 6 } },
|
||||
{ mode: "HERMITE", size: { height: 6, width: 6 } },
|
||||
{ mode: "BEZIER", size: { height: 6, width: 6 } },
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
testImages.forEach((image) => {
|
||||
describe(image.title, () => {
|
||||
image.tests.forEach(({ mode: modeType, size }) => {
|
||||
test(`to ${modeType} ${size.width}x${size.height}`, () => {
|
||||
const mode = ResizeStrategy[modeType as keyof typeof ResizeStrategy];
|
||||
|
||||
expect(
|
||||
image.src.clone().resize({
|
||||
w: size.width,
|
||||
h: size.height,
|
||||
mode,
|
||||
})
|
||||
).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
+176
@@ -0,0 +1,176 @@
|
||||
import { JimpClass } from "@jimp/types";
|
||||
import { ResizeStrategy } from "./constants.js";
|
||||
import { z } from "zod";
|
||||
|
||||
import Resize from "./modules/resize.js";
|
||||
import { operations as Resize2 } from "./modules/resize2.js";
|
||||
|
||||
export * from "./constants.js";
|
||||
|
||||
interface ResizeClass {
|
||||
// eslint-disable-next-line @typescript-eslint/no-misused-new
|
||||
new (
|
||||
widthOriginal: number,
|
||||
heightOriginal: number,
|
||||
targetWidth: number,
|
||||
targetHeight: number,
|
||||
blendAlpha: boolean,
|
||||
interpolationPass: boolean,
|
||||
resizeCallback: (buffer: Buffer) => void
|
||||
): ResizeClass;
|
||||
resize(buffer: Buffer): void;
|
||||
}
|
||||
|
||||
type Constructable<T> = new (...args: unknown[]) => T;
|
||||
|
||||
const ResizeOptionsSchema = z.union([
|
||||
z.object({
|
||||
/** the width to resize the image to */
|
||||
w: z.number().min(0),
|
||||
/** the height to resize the image to */
|
||||
h: z.number().min(0).optional(),
|
||||
/** a scaling method (e.g. ResizeStrategy.BEZIER) */
|
||||
mode: z.nativeEnum(ResizeStrategy).optional(),
|
||||
}),
|
||||
z.object({
|
||||
/** the width to resize the image to */
|
||||
w: z.number().min(0).optional(),
|
||||
/** the height to resize the image to */
|
||||
h: z.number().min(0),
|
||||
/** a scaling method (e.g. ResizeStrategy.BEZIER) */
|
||||
mode: z.nativeEnum(ResizeStrategy).optional(),
|
||||
}),
|
||||
]);
|
||||
|
||||
export type ResizeOptions = z.infer<typeof ResizeOptionsSchema>;
|
||||
|
||||
const ScaleToFitOptionsSchema = z.object({
|
||||
/** the width to resize the image to */
|
||||
w: z.number().min(0),
|
||||
/** the height to resize the image to */
|
||||
h: z.number().min(0),
|
||||
/** a scaling method (e.g. Jimp.RESIZE_BEZIER) */
|
||||
mode: z.nativeEnum(ResizeStrategy).optional(),
|
||||
});
|
||||
|
||||
export type ScaleToFitOptions = z.infer<typeof ScaleToFitOptionsSchema>;
|
||||
|
||||
const ScaleComplexOptionsSchema = z.object({
|
||||
/** the width to resize the image to */
|
||||
f: z.number().min(0),
|
||||
/** a scaling method (e.g. Jimp.RESIZE_BEZIER) */
|
||||
mode: z.nativeEnum(ResizeStrategy).optional(),
|
||||
});
|
||||
|
||||
export type ScaleComplexOptions = z.infer<typeof ScaleComplexOptionsSchema>;
|
||||
export type ScaleOptions = number | ScaleComplexOptions;
|
||||
|
||||
export const methods = {
|
||||
/**
|
||||
* Resizes the image to a set width and height using a 2-pass bilinear algorithm
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Jimp } from "jimp";
|
||||
*
|
||||
* const image = await Jimp.read("test/image.png");
|
||||
*
|
||||
* image.resize({ w: 150 });
|
||||
* ```
|
||||
*/
|
||||
resize<I extends JimpClass>(image: I, options: ResizeOptions) {
|
||||
const { mode } = ResizeOptionsSchema.parse(options);
|
||||
|
||||
let w: number;
|
||||
let h: number;
|
||||
|
||||
if (typeof options.w === "number") {
|
||||
w = options.w;
|
||||
h = options.h ?? image.bitmap.height * (w / image.bitmap.width);
|
||||
} else if (typeof options.h === "number") {
|
||||
h = options.h;
|
||||
w = options.w ?? image.bitmap.width * (h / image.bitmap.height);
|
||||
} else {
|
||||
throw new Error("w must be a number");
|
||||
}
|
||||
|
||||
// round inputs
|
||||
w = Math.round(w) || 1;
|
||||
h = Math.round(h) || 1;
|
||||
|
||||
if (mode && typeof Resize2[mode] === "function") {
|
||||
const dst = {
|
||||
data: Buffer.alloc(w * h * 4),
|
||||
width: w,
|
||||
height: h,
|
||||
};
|
||||
Resize2[mode](image.bitmap, dst);
|
||||
image.bitmap = dst;
|
||||
} else {
|
||||
const resize = new (Resize as unknown as Constructable<ResizeClass>)(
|
||||
image.bitmap.width,
|
||||
image.bitmap.height,
|
||||
w,
|
||||
h,
|
||||
true,
|
||||
true,
|
||||
(buffer: Buffer) => {
|
||||
image.bitmap.data = Buffer.from(buffer);
|
||||
image.bitmap.width = w;
|
||||
image.bitmap.height = h;
|
||||
}
|
||||
);
|
||||
|
||||
resize.resize(image.bitmap.data);
|
||||
}
|
||||
|
||||
return image;
|
||||
},
|
||||
|
||||
/**
|
||||
* Uniformly scales the image by a factor.
|
||||
* @param f the factor to scale the image by
|
||||
* @param mode (optional) a scaling method (e.g. Jimp.RESIZE_BEZIER)
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Jimp } from "jimp";
|
||||
*
|
||||
* const image = await Jimp.read("test/image.png");
|
||||
*
|
||||
* image.scale(0.5);
|
||||
* ```
|
||||
*/
|
||||
scale<I extends JimpClass>(image: I, options: ScaleOptions) {
|
||||
const { f, mode } =
|
||||
typeof options === "number"
|
||||
? ({ f: options } as ScaleComplexOptions)
|
||||
: ScaleComplexOptionsSchema.parse(options);
|
||||
const w = image.bitmap.width * f;
|
||||
const h = image.bitmap.height * f;
|
||||
|
||||
return this.resize(image, { w, h, mode: mode });
|
||||
},
|
||||
|
||||
/**
|
||||
* Scale the image to the largest size that fits inside the rectangle that has the given width and height.
|
||||
* @param w the width to resize the image to
|
||||
* @param h the height to resize the image to
|
||||
* @param mode a scaling method (e.g. ResizeStrategy.BEZIER)
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Jimp } from "jimp";
|
||||
*
|
||||
* const image = await Jimp.read("test/image.png");
|
||||
*
|
||||
* image.scaleToFit(100, 100);
|
||||
* ```
|
||||
*/
|
||||
scaleToFit<I extends JimpClass>(image: I, options: ScaleToFitOptions) {
|
||||
const { h, w, mode } = ScaleToFitOptionsSchema.parse(options);
|
||||
const f =
|
||||
w / h > image.bitmap.width / image.bitmap.height
|
||||
? h / image.bitmap.height
|
||||
: w / image.bitmap.width;
|
||||
|
||||
return this.scale(image, { f, mode: mode });
|
||||
},
|
||||
};
|
||||
+555
@@ -0,0 +1,555 @@
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-nocheck
|
||||
|
||||
// JavaScript Image Resizer (c) 2012 - Grant Galitz
|
||||
// Released to public domain 29 July 2013: https://github.com/grantgalitz/JS-Image-Resizer/issues/4
|
||||
|
||||
function Resize(
|
||||
widthOriginal,
|
||||
heightOriginal,
|
||||
targetWidth,
|
||||
targetHeight,
|
||||
blendAlpha,
|
||||
interpolationPass,
|
||||
resizeCallback
|
||||
) {
|
||||
this.widthOriginal = Math.abs(Math.floor(widthOriginal) || 0);
|
||||
this.heightOriginal = Math.abs(Math.floor(heightOriginal) || 0);
|
||||
this.targetWidth = Math.abs(Math.floor(targetWidth) || 0);
|
||||
this.targetHeight = Math.abs(Math.floor(targetHeight) || 0);
|
||||
this.colorChannels = blendAlpha ? 4 : 3;
|
||||
this.interpolationPass = Boolean(interpolationPass);
|
||||
this.resizeCallback =
|
||||
typeof resizeCallback === "function" ? resizeCallback : function () {};
|
||||
|
||||
this.targetWidthMultipliedByChannels = this.targetWidth * this.colorChannels;
|
||||
this.originalWidthMultipliedByChannels =
|
||||
this.widthOriginal * this.colorChannels;
|
||||
this.originalHeightMultipliedByChannels =
|
||||
this.heightOriginal * this.colorChannels;
|
||||
this.widthPassResultSize =
|
||||
this.targetWidthMultipliedByChannels * this.heightOriginal;
|
||||
this.finalResultSize =
|
||||
this.targetWidthMultipliedByChannels * this.targetHeight;
|
||||
this.initialize();
|
||||
}
|
||||
|
||||
Resize.prototype.initialize = function () {
|
||||
// Perform some checks:
|
||||
if (
|
||||
this.widthOriginal > 0 &&
|
||||
this.heightOriginal > 0 &&
|
||||
this.targetWidth > 0 &&
|
||||
this.targetHeight > 0
|
||||
) {
|
||||
this.configurePasses();
|
||||
} else {
|
||||
console.log(this);
|
||||
throw new Error("Invalid settings specified for the resizer.");
|
||||
}
|
||||
};
|
||||
|
||||
Resize.prototype.configurePasses = function () {
|
||||
if (this.widthOriginal === this.targetWidth) {
|
||||
// Bypass the width resizer pass:
|
||||
this.resizeWidth = this.bypassResizer;
|
||||
} else {
|
||||
// Setup the width resizer pass:
|
||||
this.ratioWeightWidthPass = this.widthOriginal / this.targetWidth;
|
||||
if (this.ratioWeightWidthPass < 1 && this.interpolationPass) {
|
||||
this.initializeFirstPassBuffers(true);
|
||||
this.resizeWidth =
|
||||
this.colorChannels === 4
|
||||
? this.resizeWidthInterpolatedRGBA
|
||||
: this.resizeWidthInterpolatedRGB;
|
||||
} else {
|
||||
this.initializeFirstPassBuffers(false);
|
||||
this.resizeWidth =
|
||||
this.colorChannels === 4 ? this.resizeWidthRGBA : this.resizeWidthRGB;
|
||||
}
|
||||
}
|
||||
|
||||
if (this.heightOriginal === this.targetHeight) {
|
||||
// Bypass the height resizer pass:
|
||||
this.resizeHeight = this.bypassResizer;
|
||||
} else {
|
||||
// Setup the height resizer pass:
|
||||
this.ratioWeightHeightPass = this.heightOriginal / this.targetHeight;
|
||||
if (this.ratioWeightHeightPass < 1 && this.interpolationPass) {
|
||||
this.initializeSecondPassBuffers(true);
|
||||
this.resizeHeight = this.resizeHeightInterpolated;
|
||||
} else {
|
||||
this.initializeSecondPassBuffers(false);
|
||||
this.resizeHeight =
|
||||
this.colorChannels === 4 ? this.resizeHeightRGBA : this.resizeHeightRGB;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Resize.prototype._resizeWidthInterpolatedRGBChannels = function (
|
||||
buffer,
|
||||
fourthChannel
|
||||
) {
|
||||
const channelsNum = fourthChannel ? 4 : 3;
|
||||
const ratioWeight = this.ratioWeightWidthPass;
|
||||
const outputBuffer = this.widthBuffer;
|
||||
|
||||
let weight = 0;
|
||||
let finalOffset = 0;
|
||||
let pixelOffset = 0;
|
||||
let firstWeight = 0;
|
||||
let secondWeight = 0;
|
||||
let targetPosition;
|
||||
|
||||
// Handle for only one interpolation input being valid for start calculation:
|
||||
for (
|
||||
targetPosition = 0;
|
||||
weight < 1 / 3;
|
||||
targetPosition += channelsNum, weight += ratioWeight
|
||||
) {
|
||||
for (
|
||||
finalOffset = targetPosition, pixelOffset = 0;
|
||||
finalOffset < this.widthPassResultSize;
|
||||
pixelOffset += this.originalWidthMultipliedByChannels,
|
||||
finalOffset += this.targetWidthMultipliedByChannels
|
||||
) {
|
||||
outputBuffer[finalOffset] = buffer[pixelOffset];
|
||||
outputBuffer[finalOffset + 1] = buffer[pixelOffset + 1];
|
||||
outputBuffer[finalOffset + 2] = buffer[pixelOffset + 2];
|
||||
if (fourthChannel)
|
||||
outputBuffer[finalOffset + 3] = buffer[pixelOffset + 3];
|
||||
}
|
||||
}
|
||||
|
||||
// Adjust for overshoot of the last pass's counter:
|
||||
weight -= 1 / 3;
|
||||
let interpolationWidthSourceReadStop;
|
||||
|
||||
for (
|
||||
interpolationWidthSourceReadStop = this.widthOriginal - 1;
|
||||
weight < interpolationWidthSourceReadStop;
|
||||
targetPosition += channelsNum, weight += ratioWeight
|
||||
) {
|
||||
// Calculate weightings:
|
||||
secondWeight = weight % 1;
|
||||
firstWeight = 1 - secondWeight;
|
||||
// Interpolate:
|
||||
for (
|
||||
finalOffset = targetPosition,
|
||||
pixelOffset = Math.floor(weight) * channelsNum;
|
||||
finalOffset < this.widthPassResultSize;
|
||||
pixelOffset += this.originalWidthMultipliedByChannels,
|
||||
finalOffset += this.targetWidthMultipliedByChannels
|
||||
) {
|
||||
outputBuffer[finalOffset + 0] =
|
||||
buffer[pixelOffset + 0] * firstWeight +
|
||||
buffer[pixelOffset + channelsNum + 0] * secondWeight;
|
||||
outputBuffer[finalOffset + 1] =
|
||||
buffer[pixelOffset + 1] * firstWeight +
|
||||
buffer[pixelOffset + channelsNum + 1] * secondWeight;
|
||||
outputBuffer[finalOffset + 2] =
|
||||
buffer[pixelOffset + 2] * firstWeight +
|
||||
buffer[pixelOffset + channelsNum + 2] * secondWeight;
|
||||
if (fourthChannel)
|
||||
outputBuffer[finalOffset + 3] =
|
||||
buffer[pixelOffset + 3] * firstWeight +
|
||||
buffer[pixelOffset + channelsNum + 3] * secondWeight;
|
||||
}
|
||||
}
|
||||
|
||||
// Handle for only one interpolation input being valid for end calculation:
|
||||
for (
|
||||
interpolationWidthSourceReadStop =
|
||||
this.originalWidthMultipliedByChannels - channelsNum;
|
||||
targetPosition < this.targetWidthMultipliedByChannels;
|
||||
targetPosition += channelsNum
|
||||
) {
|
||||
for (
|
||||
finalOffset = targetPosition,
|
||||
pixelOffset = interpolationWidthSourceReadStop;
|
||||
finalOffset < this.widthPassResultSize;
|
||||
pixelOffset += this.originalWidthMultipliedByChannels,
|
||||
finalOffset += this.targetWidthMultipliedByChannels
|
||||
) {
|
||||
outputBuffer[finalOffset] = buffer[pixelOffset];
|
||||
outputBuffer[finalOffset + 1] = buffer[pixelOffset + 1];
|
||||
outputBuffer[finalOffset + 2] = buffer[pixelOffset + 2];
|
||||
if (fourthChannel)
|
||||
outputBuffer[finalOffset + 3] = buffer[pixelOffset + 3];
|
||||
}
|
||||
}
|
||||
|
||||
return outputBuffer;
|
||||
};
|
||||
|
||||
Resize.prototype._resizeWidthRGBChannels = function (buffer, fourthChannel) {
|
||||
const channelsNum = fourthChannel ? 4 : 3;
|
||||
const ratioWeight = this.ratioWeightWidthPass;
|
||||
const ratioWeightDivisor = 1 / ratioWeight;
|
||||
const nextLineOffsetOriginalWidth =
|
||||
this.originalWidthMultipliedByChannels - channelsNum + 1;
|
||||
const nextLineOffsetTargetWidth =
|
||||
this.targetWidthMultipliedByChannels - channelsNum + 1;
|
||||
const output = this.outputWidthWorkBench;
|
||||
const outputBuffer = this.widthBuffer;
|
||||
const trustworthyColorsCount = this.outputWidthWorkBenchOpaquePixelsCount;
|
||||
|
||||
let weight = 0;
|
||||
let amountToNext = 0;
|
||||
let actualPosition = 0;
|
||||
let currentPosition = 0;
|
||||
let line = 0;
|
||||
let pixelOffset = 0;
|
||||
let outputOffset = 0;
|
||||
let multiplier = 1;
|
||||
let r = 0;
|
||||
let g = 0;
|
||||
let b = 0;
|
||||
let a = 0;
|
||||
|
||||
do {
|
||||
for (line = 0; line < this.originalHeightMultipliedByChannels; ) {
|
||||
output[line++] = 0;
|
||||
output[line++] = 0;
|
||||
output[line++] = 0;
|
||||
if (fourthChannel) {
|
||||
output[line++] = 0;
|
||||
trustworthyColorsCount[line / channelsNum - 1] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
weight = ratioWeight;
|
||||
|
||||
do {
|
||||
amountToNext = 1 + actualPosition - currentPosition;
|
||||
multiplier = Math.min(weight, amountToNext);
|
||||
for (
|
||||
line = 0, pixelOffset = actualPosition;
|
||||
line < this.originalHeightMultipliedByChannels;
|
||||
pixelOffset += nextLineOffsetOriginalWidth
|
||||
) {
|
||||
r = buffer[pixelOffset];
|
||||
g = buffer[++pixelOffset];
|
||||
b = buffer[++pixelOffset];
|
||||
a = fourthChannel ? buffer[++pixelOffset] : 255;
|
||||
// Ignore RGB values if pixel is completely transparent
|
||||
output[line++] += (a ? r : 0) * multiplier;
|
||||
output[line++] += (a ? g : 0) * multiplier;
|
||||
output[line++] += (a ? b : 0) * multiplier;
|
||||
if (fourthChannel) {
|
||||
output[line++] += a * multiplier;
|
||||
trustworthyColorsCount[line / channelsNum - 1] += a ? multiplier : 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (weight >= amountToNext) {
|
||||
actualPosition += channelsNum;
|
||||
currentPosition = actualPosition;
|
||||
weight -= amountToNext;
|
||||
} else {
|
||||
currentPosition += weight;
|
||||
break;
|
||||
}
|
||||
} while (
|
||||
weight > 0 &&
|
||||
actualPosition < this.originalWidthMultipliedByChannels
|
||||
);
|
||||
|
||||
for (
|
||||
line = 0, pixelOffset = outputOffset;
|
||||
line < this.originalHeightMultipliedByChannels;
|
||||
pixelOffset += nextLineOffsetTargetWidth
|
||||
) {
|
||||
weight = fourthChannel ? trustworthyColorsCount[line / channelsNum] : 1;
|
||||
multiplier = fourthChannel
|
||||
? weight
|
||||
? 1 / weight
|
||||
: 0
|
||||
: ratioWeightDivisor;
|
||||
outputBuffer[pixelOffset] = output[line++] * multiplier;
|
||||
outputBuffer[++pixelOffset] = output[line++] * multiplier;
|
||||
outputBuffer[++pixelOffset] = output[line++] * multiplier;
|
||||
if (fourthChannel)
|
||||
outputBuffer[++pixelOffset] = output[line++] * ratioWeightDivisor;
|
||||
}
|
||||
|
||||
outputOffset += channelsNum;
|
||||
} while (outputOffset < this.targetWidthMultipliedByChannels);
|
||||
|
||||
return outputBuffer;
|
||||
};
|
||||
|
||||
Resize.prototype._resizeHeightRGBChannels = function (buffer, fourthChannel) {
|
||||
const ratioWeight = this.ratioWeightHeightPass;
|
||||
const ratioWeightDivisor = 1 / ratioWeight;
|
||||
const output = this.outputHeightWorkBench;
|
||||
const outputBuffer = this.heightBuffer;
|
||||
const trustworthyColorsCount = this.outputHeightWorkBenchOpaquePixelsCount;
|
||||
|
||||
let weight = 0;
|
||||
let amountToNext = 0;
|
||||
let actualPosition = 0;
|
||||
let currentPosition = 0;
|
||||
let pixelOffset = 0;
|
||||
let outputOffset = 0;
|
||||
let caret = 0;
|
||||
let multiplier = 1;
|
||||
let r = 0;
|
||||
let g = 0;
|
||||
let b = 0;
|
||||
let a = 0;
|
||||
|
||||
do {
|
||||
for (
|
||||
pixelOffset = 0;
|
||||
pixelOffset < this.targetWidthMultipliedByChannels;
|
||||
|
||||
) {
|
||||
output[pixelOffset++] = 0;
|
||||
output[pixelOffset++] = 0;
|
||||
output[pixelOffset++] = 0;
|
||||
|
||||
if (fourthChannel) {
|
||||
output[pixelOffset++] = 0;
|
||||
trustworthyColorsCount[pixelOffset / 4 - 1] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
weight = ratioWeight;
|
||||
|
||||
do {
|
||||
amountToNext = 1 + actualPosition - currentPosition;
|
||||
multiplier = Math.min(weight, amountToNext);
|
||||
caret = actualPosition;
|
||||
|
||||
for (
|
||||
pixelOffset = 0;
|
||||
pixelOffset < this.targetWidthMultipliedByChannels;
|
||||
|
||||
) {
|
||||
r = buffer[caret++];
|
||||
g = buffer[caret++];
|
||||
b = buffer[caret++];
|
||||
a = fourthChannel ? buffer[caret++] : 255;
|
||||
// Ignore RGB values if pixel is completely transparent
|
||||
output[pixelOffset++] += (a ? r : 0) * multiplier;
|
||||
output[pixelOffset++] += (a ? g : 0) * multiplier;
|
||||
output[pixelOffset++] += (a ? b : 0) * multiplier;
|
||||
|
||||
if (fourthChannel) {
|
||||
output[pixelOffset++] += a * multiplier;
|
||||
trustworthyColorsCount[pixelOffset / 4 - 1] += a ? multiplier : 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (weight >= amountToNext) {
|
||||
actualPosition = caret;
|
||||
currentPosition = actualPosition;
|
||||
weight -= amountToNext;
|
||||
} else {
|
||||
currentPosition += weight;
|
||||
break;
|
||||
}
|
||||
} while (weight > 0 && actualPosition < this.widthPassResultSize);
|
||||
|
||||
for (
|
||||
pixelOffset = 0;
|
||||
pixelOffset < this.targetWidthMultipliedByChannels;
|
||||
|
||||
) {
|
||||
weight = fourthChannel ? trustworthyColorsCount[pixelOffset / 4] : 1;
|
||||
multiplier = fourthChannel
|
||||
? weight
|
||||
? 1 / weight
|
||||
: 0
|
||||
: ratioWeightDivisor;
|
||||
outputBuffer[outputOffset++] = Math.round(
|
||||
output[pixelOffset++] * multiplier
|
||||
);
|
||||
outputBuffer[outputOffset++] = Math.round(
|
||||
output[pixelOffset++] * multiplier
|
||||
);
|
||||
outputBuffer[outputOffset++] = Math.round(
|
||||
output[pixelOffset++] * multiplier
|
||||
);
|
||||
|
||||
if (fourthChannel) {
|
||||
outputBuffer[outputOffset++] = Math.round(
|
||||
output[pixelOffset++] * ratioWeightDivisor
|
||||
);
|
||||
}
|
||||
}
|
||||
} while (outputOffset < this.finalResultSize);
|
||||
|
||||
return outputBuffer;
|
||||
};
|
||||
|
||||
Resize.prototype.resizeWidthInterpolatedRGB = function (buffer) {
|
||||
return this._resizeWidthInterpolatedRGBChannels(buffer, false);
|
||||
};
|
||||
|
||||
Resize.prototype.resizeWidthInterpolatedRGBA = function (buffer) {
|
||||
return this._resizeWidthInterpolatedRGBChannels(buffer, true);
|
||||
};
|
||||
|
||||
Resize.prototype.resizeWidthRGB = function (buffer) {
|
||||
return this._resizeWidthRGBChannels(buffer, false);
|
||||
};
|
||||
|
||||
Resize.prototype.resizeWidthRGBA = function (buffer) {
|
||||
return this._resizeWidthRGBChannels(buffer, true);
|
||||
};
|
||||
|
||||
Resize.prototype.resizeHeightInterpolated = function (buffer) {
|
||||
const ratioWeight = this.ratioWeightHeightPass;
|
||||
const outputBuffer = this.heightBuffer;
|
||||
|
||||
let weight = 0;
|
||||
let finalOffset = 0;
|
||||
let pixelOffset = 0;
|
||||
let pixelOffsetAccumulated = 0;
|
||||
let pixelOffsetAccumulated2 = 0;
|
||||
let firstWeight = 0;
|
||||
let secondWeight = 0;
|
||||
let interpolationHeightSourceReadStop;
|
||||
|
||||
// Handle for only one interpolation input being valid for start calculation:
|
||||
for (; weight < 1 / 3; weight += ratioWeight) {
|
||||
for (
|
||||
pixelOffset = 0;
|
||||
pixelOffset < this.targetWidthMultipliedByChannels;
|
||||
|
||||
) {
|
||||
outputBuffer[finalOffset++] = Math.round(buffer[pixelOffset++]);
|
||||
}
|
||||
}
|
||||
|
||||
// Adjust for overshoot of the last pass's counter:
|
||||
weight -= 1 / 3;
|
||||
|
||||
for (
|
||||
interpolationHeightSourceReadStop = this.heightOriginal - 1;
|
||||
weight < interpolationHeightSourceReadStop;
|
||||
weight += ratioWeight
|
||||
) {
|
||||
// Calculate weightings:
|
||||
secondWeight = weight % 1;
|
||||
firstWeight = 1 - secondWeight;
|
||||
// Interpolate:
|
||||
pixelOffsetAccumulated =
|
||||
Math.floor(weight) * this.targetWidthMultipliedByChannels;
|
||||
pixelOffsetAccumulated2 =
|
||||
pixelOffsetAccumulated + this.targetWidthMultipliedByChannels;
|
||||
for (
|
||||
pixelOffset = 0;
|
||||
pixelOffset < this.targetWidthMultipliedByChannels;
|
||||
++pixelOffset
|
||||
) {
|
||||
outputBuffer[finalOffset++] = Math.round(
|
||||
buffer[pixelOffsetAccumulated++] * firstWeight +
|
||||
buffer[pixelOffsetAccumulated2++] * secondWeight
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Handle for only one interpolation input being valid for end calculation:
|
||||
while (finalOffset < this.finalResultSize) {
|
||||
for (
|
||||
pixelOffset = 0,
|
||||
pixelOffsetAccumulated =
|
||||
interpolationHeightSourceReadStop *
|
||||
this.targetWidthMultipliedByChannels;
|
||||
pixelOffset < this.targetWidthMultipliedByChannels;
|
||||
++pixelOffset
|
||||
) {
|
||||
outputBuffer[finalOffset++] = Math.round(
|
||||
buffer[pixelOffsetAccumulated++]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return outputBuffer;
|
||||
};
|
||||
|
||||
Resize.prototype.resizeHeightRGB = function (buffer) {
|
||||
return this._resizeHeightRGBChannels(buffer, false);
|
||||
};
|
||||
|
||||
Resize.prototype.resizeHeightRGBA = function (buffer) {
|
||||
return this._resizeHeightRGBChannels(buffer, true);
|
||||
};
|
||||
|
||||
Resize.prototype.resize = function (buffer) {
|
||||
this.resizeCallback(this.resizeHeight(this.resizeWidth(buffer)));
|
||||
};
|
||||
|
||||
Resize.prototype.bypassResizer = function (buffer) {
|
||||
// Just return the buffer passed:
|
||||
return buffer;
|
||||
};
|
||||
|
||||
Resize.prototype.initializeFirstPassBuffers = function (BILINEARAlgo) {
|
||||
// Initialize the internal width pass buffers:
|
||||
this.widthBuffer = this.generateFloatBuffer(this.widthPassResultSize);
|
||||
|
||||
if (!BILINEARAlgo) {
|
||||
this.outputWidthWorkBench = this.generateFloatBuffer(
|
||||
this.originalHeightMultipliedByChannels
|
||||
);
|
||||
|
||||
if (this.colorChannels > 3) {
|
||||
this.outputWidthWorkBenchOpaquePixelsCount = this.generateFloat64Buffer(
|
||||
this.heightOriginal
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Resize.prototype.initializeSecondPassBuffers = function (BILINEARAlgo) {
|
||||
// Initialize the internal height pass buffers:
|
||||
this.heightBuffer = this.generateUint8Buffer(this.finalResultSize);
|
||||
|
||||
if (!BILINEARAlgo) {
|
||||
this.outputHeightWorkBench = this.generateFloatBuffer(
|
||||
this.targetWidthMultipliedByChannels
|
||||
);
|
||||
|
||||
if (this.colorChannels > 3) {
|
||||
this.outputHeightWorkBenchOpaquePixelsCount = this.generateFloat64Buffer(
|
||||
this.targetWidth
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Resize.prototype.generateFloatBuffer = function (bufferLength) {
|
||||
// Generate a float32 typed array buffer:
|
||||
try {
|
||||
return new Float32Array(bufferLength);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
return [];
|
||||
}
|
||||
};
|
||||
|
||||
Resize.prototype.generateFloat64Buffer = function (bufferLength) {
|
||||
// Generate a float64 typed array buffer:
|
||||
try {
|
||||
return new Float64Array(bufferLength);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
return [];
|
||||
}
|
||||
};
|
||||
|
||||
Resize.prototype.generateUint8Buffer = function (bufferLength) {
|
||||
// Generate a uint8 typed array buffer:
|
||||
try {
|
||||
return new Uint8Array(bufferLength);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
return [];
|
||||
}
|
||||
};
|
||||
|
||||
export default Resize;
|
||||
+327
@@ -0,0 +1,327 @@
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
/**
|
||||
* Copyright (c) 2015 Guyon Roche
|
||||
*
|
||||
* 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:</p>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
export const operations = {
|
||||
nearestNeighbor(src: any, dst: any) {
|
||||
const wSrc = src.width;
|
||||
const hSrc = src.height;
|
||||
|
||||
const wDst = dst.width;
|
||||
const hDst = dst.height;
|
||||
|
||||
const bufSrc = src.data;
|
||||
const bufDst = dst.data;
|
||||
|
||||
for (let i = 0; i < hDst; i++) {
|
||||
for (let j = 0; j < wDst; j++) {
|
||||
let posDst = (i * wDst + j) * 4;
|
||||
|
||||
const iSrc = Math.floor((i * hSrc) / hDst);
|
||||
const jSrc = Math.floor((j * wSrc) / wDst);
|
||||
let posSrc = (iSrc * wSrc + jSrc) * 4;
|
||||
|
||||
bufDst[posDst++] = bufSrc[posSrc++];
|
||||
bufDst[posDst++] = bufSrc[posSrc++];
|
||||
bufDst[posDst++] = bufSrc[posSrc++];
|
||||
bufDst[posDst++] = bufSrc[posSrc++];
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
bilinearInterpolation(src: any, dst: any) {
|
||||
const wSrc = src.width;
|
||||
const hSrc = src.height;
|
||||
|
||||
const wDst = dst.width;
|
||||
const hDst = dst.height;
|
||||
|
||||
const bufSrc = src.data;
|
||||
const bufDst = dst.data;
|
||||
|
||||
const interpolate = function (
|
||||
k: number,
|
||||
kMin: number,
|
||||
vMin: number,
|
||||
kMax: number,
|
||||
vMax: number,
|
||||
) {
|
||||
// special case - k is integer
|
||||
if (kMin === kMax) {
|
||||
return vMin;
|
||||
}
|
||||
|
||||
return Math.round((k - kMin) * vMax + (kMax - k) * vMin);
|
||||
};
|
||||
|
||||
const assign = function (
|
||||
pos: number,
|
||||
offset: number,
|
||||
x: number,
|
||||
xMin: number,
|
||||
xMax: number,
|
||||
y: number,
|
||||
yMin: number,
|
||||
yMax: number,
|
||||
) {
|
||||
let posMin = (yMin * wSrc + xMin) * 4 + offset;
|
||||
let posMax = (yMin * wSrc + xMax) * 4 + offset;
|
||||
const vMin = interpolate(x, xMin, bufSrc[posMin], xMax, bufSrc[posMax]);
|
||||
|
||||
// special case, y is integer
|
||||
if (yMax === yMin) {
|
||||
bufDst[pos + offset] = vMin;
|
||||
} else {
|
||||
posMin = (yMax * wSrc + xMin) * 4 + offset;
|
||||
posMax = (yMax * wSrc + xMax) * 4 + offset;
|
||||
const vMax = interpolate(x, xMin, bufSrc[posMin], xMax, bufSrc[posMax]);
|
||||
|
||||
bufDst[pos + offset] = interpolate(y, yMin, vMin, yMax, vMax);
|
||||
}
|
||||
};
|
||||
|
||||
for (let i = 0; i < hDst; i++) {
|
||||
for (let j = 0; j < wDst; j++) {
|
||||
const posDst = (i * wDst + j) * 4;
|
||||
// x & y in src coordinates
|
||||
const x = (j * wSrc) / wDst;
|
||||
const xMin = Math.floor(x);
|
||||
const xMax = Math.min(Math.ceil(x), wSrc - 1);
|
||||
|
||||
const y = (i * hSrc) / hDst;
|
||||
const yMin = Math.floor(y);
|
||||
const yMax = Math.min(Math.ceil(y), hSrc - 1);
|
||||
|
||||
assign(posDst, 0, x, xMin, xMax, y, yMin, yMax);
|
||||
assign(posDst, 1, x, xMin, xMax, y, yMin, yMax);
|
||||
assign(posDst, 2, x, xMin, xMax, y, yMin, yMax);
|
||||
assign(posDst, 3, x, xMin, xMax, y, yMin, yMax);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_interpolate2D(src: any, dst: any, options?: any, interpolate?: any) {
|
||||
const bufSrc = src.data;
|
||||
const bufDst = dst.data;
|
||||
|
||||
const wSrc = src.width;
|
||||
const hSrc = src.height;
|
||||
|
||||
const wDst = dst.width;
|
||||
const hDst = dst.height;
|
||||
|
||||
// when dst smaller than src/2, interpolate first to a multiple between 0.5 and 1.0 src, then sum squares
|
||||
const wM = Math.max(1, Math.floor(wSrc / wDst));
|
||||
const wDst2 = wDst * wM;
|
||||
const hM = Math.max(1, Math.floor(hSrc / hDst));
|
||||
const hDst2 = hDst * hM;
|
||||
|
||||
// ===========================================================
|
||||
// Pass 1 - interpolate rows
|
||||
// buf1 has width of dst2 and height of src
|
||||
const buf1 = Buffer.alloc(wDst2 * hSrc * 4);
|
||||
for (let i = 0; i < hSrc; i++) {
|
||||
for (let j = 0; j < wDst2; j++) {
|
||||
// i in src coords, j in dst coords
|
||||
|
||||
// calculate x in src coords
|
||||
// this interpolation requires 4 sample points and the two inner ones must be real
|
||||
// the outer points can be fudged for the edges.
|
||||
// therefore (wSrc-1)/wDst2
|
||||
const x = (j * (wSrc - 1)) / wDst2;
|
||||
const xPos = Math.floor(x);
|
||||
const t = x - xPos;
|
||||
const srcPos = (i * wSrc + xPos) * 4;
|
||||
const buf1Pos = (i * wDst2 + j) * 4;
|
||||
|
||||
for (let k = 0; k < 4; k++) {
|
||||
const kPos = srcPos + k;
|
||||
const x0 =
|
||||
xPos > 0 ? bufSrc[kPos - 4] : 2 * bufSrc[kPos] - bufSrc[kPos + 4];
|
||||
const x1 = bufSrc[kPos];
|
||||
const x2 = bufSrc[kPos + 4];
|
||||
const x3 =
|
||||
xPos < wSrc - 2
|
||||
? bufSrc[kPos + 8]
|
||||
: 2 * bufSrc[kPos + 4] - bufSrc[kPos];
|
||||
buf1[buf1Pos + k] = interpolate(x0, x1, x2, x3, t);
|
||||
}
|
||||
}
|
||||
}
|
||||
// this._writeFile(wDst2, hSrc, buf1, "out/buf1.jpg");
|
||||
|
||||
// ===========================================================
|
||||
// Pass 2 - interpolate columns
|
||||
// buf2 has width and height of dst2
|
||||
const buf2 = Buffer.alloc(wDst2 * hDst2 * 4);
|
||||
for (let i = 0; i < hDst2; i++) {
|
||||
for (let j = 0; j < wDst2; j++) {
|
||||
// i&j in dst2 coords
|
||||
|
||||
// calculate y in buf1 coords
|
||||
// this interpolation requires 4 sample points and the two inner ones must be real
|
||||
// the outer points can be fudged for the edges.
|
||||
// therefore (hSrc-1)/hDst2
|
||||
const y = (i * (hSrc - 1)) / hDst2;
|
||||
const yPos = Math.floor(y);
|
||||
const t = y - yPos;
|
||||
const buf1Pos = (yPos * wDst2 + j) * 4;
|
||||
const buf2Pos = (i * wDst2 + j) * 4;
|
||||
for (let k = 0; k < 4; k++) {
|
||||
const kPos = buf1Pos + k;
|
||||
const y0 =
|
||||
yPos > 0
|
||||
? buf1[kPos - wDst2 * 4]
|
||||
: 2 * buf1[kPos]! - buf1[kPos + wDst2 * 4]!;
|
||||
const y1 = buf1[kPos];
|
||||
const y2 = buf1[kPos + wDst2 * 4];
|
||||
const y3 =
|
||||
yPos < hSrc - 2
|
||||
? buf1[kPos + wDst2 * 8]
|
||||
: 2 * buf1[kPos + wDst2 * 4]! - buf1[kPos]!;
|
||||
|
||||
buf2[buf2Pos + k] = interpolate(y0, y1, y2, y3, t);
|
||||
}
|
||||
}
|
||||
}
|
||||
// this._writeFile(wDst2, hDst2, buf2, "out/buf2.jpg");
|
||||
|
||||
// ===========================================================
|
||||
// Pass 3 - scale to dst
|
||||
const m = wM * hM;
|
||||
if (m > 1) {
|
||||
for (let i = 0; i < hDst; i++) {
|
||||
for (let j = 0; j < wDst; j++) {
|
||||
// i&j in dst bounded coords
|
||||
let r = 0;
|
||||
let g = 0;
|
||||
let b = 0;
|
||||
let a = 0;
|
||||
let realColors = 0;
|
||||
|
||||
for (let y = 0; y < hM; y++) {
|
||||
const yPos = i * hM + y;
|
||||
|
||||
for (let x = 0; x < wM; x++) {
|
||||
const xPos = j * wM + x;
|
||||
const xyPos = (yPos * wDst2 + xPos) * 4;
|
||||
const pixelAlpha = buf2[xyPos + 3]!;
|
||||
|
||||
if (pixelAlpha) {
|
||||
r += buf2[xyPos]!;
|
||||
g += buf2[xyPos + 1]!;
|
||||
b += buf2[xyPos + 2]!;
|
||||
realColors++;
|
||||
}
|
||||
|
||||
a += pixelAlpha;
|
||||
}
|
||||
}
|
||||
|
||||
const pos = (i * wDst + j) * 4;
|
||||
bufDst[pos] = realColors ? Math.round(r / realColors) : 0;
|
||||
bufDst[pos + 1] = realColors ? Math.round(g / realColors) : 0;
|
||||
bufDst[pos + 2] = realColors ? Math.round(b / realColors) : 0;
|
||||
bufDst[pos + 3] = Math.round(a / m);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// replace dst buffer with buf2
|
||||
dst.data = buf2;
|
||||
}
|
||||
},
|
||||
|
||||
bicubicInterpolation(src: any, dst: any, options?: any) {
|
||||
const interpolateCubic = function (
|
||||
x0: number,
|
||||
x1: number,
|
||||
x2: number,
|
||||
x3: number,
|
||||
t: number,
|
||||
) {
|
||||
const a0 = x3 - x2 - x0 + x1;
|
||||
const a1 = x0 - x1 - a0;
|
||||
const a2 = x2 - x0;
|
||||
const a3 = x1;
|
||||
return Math.max(
|
||||
0,
|
||||
Math.min(255, a0 * (t * t * t) + a1 * (t * t) + a2 * t + a3),
|
||||
);
|
||||
};
|
||||
|
||||
return this._interpolate2D(src, dst, options, interpolateCubic);
|
||||
},
|
||||
|
||||
hermiteInterpolation(src: any, dst: any, options?: any) {
|
||||
const interpolateHermite = function (
|
||||
x0: number,
|
||||
x1: number,
|
||||
x2: number,
|
||||
x3: number,
|
||||
t: number,
|
||||
) {
|
||||
const c0 = x1;
|
||||
const c1 = 0.5 * (x2 - x0);
|
||||
const c2 = x0 - 2.5 * x1 + 2 * x2 - 0.5 * x3;
|
||||
const c3 = 0.5 * (x3 - x0) + 1.5 * (x1 - x2);
|
||||
return Math.max(
|
||||
0,
|
||||
Math.min(255, Math.round(((c3 * t + c2) * t + c1) * t + c0)),
|
||||
);
|
||||
};
|
||||
|
||||
return this._interpolate2D(src, dst, options, interpolateHermite);
|
||||
},
|
||||
|
||||
bezierInterpolation(src: any, dst: any, options?: any) {
|
||||
// between 2 points y(n), y(n+1), use next points out, y(n-1), y(n+2)
|
||||
// to predict control points (a & b) to be placed at n+0.5
|
||||
// ya(n) = y(n) + (y(n+1)-y(n-1))/4
|
||||
// yb(n) = y(n+1) - (y(n+2)-y(n))/4
|
||||
// then use std bezier to interpolate [n,n+1)
|
||||
// y(n+t) = y(n)*(1-t)^3 + 3 * ya(n)*(1-t)^2*t + 3 * yb(n)*(1-t)*t^2 + y(n+1)*t^3
|
||||
// note the 3* factor for the two control points
|
||||
// for edge cases, can choose:
|
||||
// y(-1) = y(0) - 2*(y(1)-y(0))
|
||||
// y(w) = y(w-1) + 2*(y(w-1)-y(w-2))
|
||||
// but can go with y(-1) = y(0) and y(w) = y(w-1)
|
||||
const interpolateBezier = function (
|
||||
x0: number,
|
||||
x1: number,
|
||||
x2: number,
|
||||
x3: number,
|
||||
t: number,
|
||||
) {
|
||||
// x1, x2 are the knots, use x0 and x3 to calculate control points
|
||||
const cp1 = x1 + (x2 - x0) / 4;
|
||||
const cp2 = x2 - (x3 - x1) / 4;
|
||||
const nt = 1 - t;
|
||||
const c0 = x1 * nt * nt * nt;
|
||||
const c1 = 3 * cp1 * nt * nt * t;
|
||||
const c2 = 3 * cp2 * nt * t * t;
|
||||
const c3 = x2 * t * t * t;
|
||||
return Math.max(0, Math.min(255, Math.round(c0 + c1 + c2 + c3)));
|
||||
};
|
||||
|
||||
return this._interpolate2D(src, dst, options, interpolateBezier);
|
||||
},
|
||||
};
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"extends": "@jimp/config-typescript/base.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "dist"
|
||||
}
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
import config from "@jimp/config-vitest/browser";
|
||||
|
||||
export default config;
|
||||
Reference in new issue
Block a user