Comparing version 0.2.27 to 0.2.28
@@ -13,2 +13,2 @@ importScripts("../lib/jimp.min.js"); | ||
}); | ||
}); | ||
}); |
@@ -25,3 +25,3 @@ # Jimp ... in a browser # | ||
See the [main documentation](https://github.com/oliver-moran/jimp) for the fill API documenatinon. | ||
See the [main documentation](https://github.com/oliver-moran/jimp) for the full API documenatinon. | ||
@@ -67,3 +67,3 @@ ## WebWorkers ## | ||
```html | ||
<script src="https://cdn.rawgit.com/oliver-moran/jimp/v0.2.27/browser/lib/jimp.min.js"></script> | ||
<script src="https://cdn.rawgit.com/oliver-moran/jimp/v0.2.28/browser/lib/jimp.min.js"></script> | ||
``` | ||
@@ -70,0 +70,0 @@ |
{ | ||
"name": "jimp", | ||
"version": "0.2.27", | ||
"version": "0.2.28", | ||
"description": "An image processing library written entirely in JavaScript (i.e. zero external or native dependencies).", | ||
"main": "index.js", | ||
"types": "./jimp.d.ts", | ||
"scripts": { | ||
@@ -27,3 +28,3 @@ "test": "./test/tests.sh", | ||
"bignumber.js": "^2.1.0", | ||
"bmp-js": "0.0.1", | ||
"bmp-js": "0.0.3", | ||
"es6-promise": "^3.0.2", | ||
@@ -35,2 +36,3 @@ "exif-parser": "^0.1.9", | ||
"mime": "^1.3.4", | ||
"mkdirp": "0.5.1", | ||
"pixelmatch": "^4.0.0", | ||
@@ -49,3 +51,3 @@ "pngjs": "^3.0.0", | ||
"babel-preset-stage-0": "^6.0.14", | ||
"browserify": "^13.0.0", | ||
"browserify": "^14.3.0", | ||
"envify": "^3.4.0", | ||
@@ -63,3 +65,4 @@ "express": "^4.13.4", | ||
}, | ||
"tonicExampleFilename": "example.js" | ||
"tonicExampleFilename": "example.js", | ||
"browser": "browser/lib/jimp.js" | ||
} |
@@ -0,1 +1,9 @@ | ||
<hr> | ||
**Can you help maintain this project?** | ||
Collaborators wanted: https://github.com/oliver-moran/jimp/issues/219 | ||
<hr> | ||
# Jimp # | ||
@@ -37,4 +45,2 @@ | ||
Also available to use in web browsers and Electron applications. See [`browser/README.md`](https://github.com/oliver-moran/jimp/blob/master/browser/README.md). | ||
## Basic usage ## | ||
@@ -84,3 +90,3 @@ | ||
/* Crop */ | ||
image.autocrop(); // automatically crop same-color borders from image (if any) | ||
image.autocrop([tolerance, frames]); // automatically crop same-color borders from image (if any), frames must be a Boolean | ||
image.crop( x, y, w, h ); // crop to the given region | ||
@@ -92,3 +98,4 @@ | ||
image.composite( src, x, y ); // composites another Jimp image over this image at x, y | ||
image.mask( src, x, y ); // masks the image with another Jimp image at x, y using average pixel value image.rotate) and when writing formats that don't support alpha channels | ||
image.mask( src, x, y ); // masks the image with another Jimp image at x, y using average pixel value | ||
image.convolute( kernel ); // applies a convolution kernel matrix to the image or a region | ||
@@ -99,5 +106,4 @@ /* Flip and rotate */ | ||
image.rotate( deg[, mode] ); // rotate the image clockwise by a number of degrees. Optionally, a resize mode can be passed. If `false` is passed as the second parameter, the image width and height will not be resized. | ||
image.exifRotate(); // JPEG images with EXIF orientation data will be automatically re-orientated as appropriate. | ||
// JPEG images with EXIF orientation data will be automatically re-orientated as appropriate. | ||
/* Colour */ | ||
@@ -115,3 +121,3 @@ image.brightness( val ); // adjust the brighness by a value -1 to +1 | ||
image.opaque(); // set the alpha channel on every pixel to fully opaque | ||
image.background( hex ); // set the default new pixel colour (e.g. 0xFFFFFFFF or 0x00000000) for by some operations (e.g. image.contain and | ||
image.background( hex ); // set the default new pixel colour (e.g. 0xFFFFFFFF or 0x00000000) for by some operations (e.g. image.contain and | ||
@@ -125,2 +131,6 @@ /* Blurs */ | ||
image.sepia(); // apply a sepia wash to the image | ||
image.pixelate( size[, x, y, w, h ]); // apply a pixelation effect to the image or a region | ||
/* 3D */ | ||
image.displace( map, offset ); // displaces the image pixels based on the provided displacement map. Useful for making stereoscopic 3D images. | ||
``` | ||
@@ -138,3 +148,3 @@ | ||
The default rezing algorithm uses a bilinear method as follows: | ||
The default resizing algorithm uses a bilinear method as follows: | ||
@@ -238,2 +248,9 @@ ```js | ||
The original extension for an image (or "png") can accessed as using `image.getExtension()`. The following will save an image using its original format: | ||
```js | ||
var file = "new_name." + image.getExtension(); | ||
image.write(file) | ||
``` | ||
### Writing to Buffers ### | ||
@@ -255,3 +272,3 @@ | ||
If `Jimp.AUTO` is passed as the MIME type then the original MIME type for the image (or "image/png") will be used. | ||
If `Jimp.AUTO` is passed as the MIME type then the original MIME type for the image (or "image/png") will be used. Alernatively, `image.getMIME()` will return the original MIME type of the image (or "image/png"). | ||
@@ -328,2 +345,15 @@ ### Data URI ### | ||
### Convolution matrix ### | ||
Sum neighbor pixels weighted by the kernel matrix. You can find a nice explanation with examples at [GIMP's Convolution Matrix plugin](https://docs.gimp.org/en/plug-in-convmatrix.html) | ||
Implement emboss effect: | ||
```js | ||
image.convolution([ | ||
[-2,-1, 0], | ||
[-1, 1, 1], | ||
[ 0, 1, 2] | ||
]) | ||
``` | ||
### Low-level manipulation ### | ||
@@ -344,3 +374,3 @@ | ||
```js | ||
image.scan(x, y, w, h, cb); // scan a given region of the bitmap and call cb on every pixel | ||
image.scan(x, y, w, h, f); // scan a given region of the bitmap and call the function f on every pixel | ||
``` | ||
@@ -365,3 +395,16 @@ | ||
``` | ||
A helper to locate a particular pixel within the raw bitmap buffer: | ||
```js | ||
image.getPixelIndex(x, y); // returns the index within image.bitmap.data | ||
``` | ||
One of the following may be optionally passed as a third parameter to indicate a strategy for x, y positions that are outside of boundaries of the image: | ||
```js | ||
Jimp.EDGE_EXTEND = 1; | ||
Jimp.EDGE_WRAP = 2; | ||
Jimp.EDGE_CROP = 3; | ||
``` | ||
Alternatively, you can manipulate individual pixels using the following these functions: | ||
@@ -368,0 +411,0 @@ |
305
resize.js
@@ -60,56 +60,6 @@ // JavaScript Image Resizer (c) 2012 - Grant Galitz | ||
Resize.prototype.resizeWidthRGB = function (buffer) { | ||
Resize.prototype._resizeWidthInterpolatedRGBChannels = function (buffer, fourthChannel) { | ||
var channelsNum = fourthChannel ? 4 : 3; | ||
var ratioWeight = this.ratioWeightWidthPass; | ||
var ratioWeightDivisor = 1 / ratioWeight; | ||
var weight = 0; | ||
var amountToNext = 0; | ||
var actualPosition = 0; | ||
var currentPosition = 0; | ||
var line = 0; | ||
var pixelOffset = 0; | ||
var outputOffset = 0; | ||
var nextLineOffsetOriginalWidth = this.originalWidthMultipliedByChannels - 2; | ||
var nextLineOffsetTargetWidth = this.targetWidthMultipliedByChannels - 2; | ||
var output = this.outputWidthWorkBench; | ||
var outputBuffer = this.widthBuffer; | ||
do { | ||
for (line = 0; line < this.originalHeightMultipliedByChannels;) { | ||
output[line++] = 0; | ||
output[line++] = 0; | ||
output[line++] = 0; | ||
} | ||
weight = ratioWeight; | ||
do { | ||
amountToNext = 1 + actualPosition - currentPosition; | ||
if (weight >= amountToNext) { | ||
for (line = 0, pixelOffset = actualPosition; line < this.originalHeightMultipliedByChannels; pixelOffset += nextLineOffsetOriginalWidth) { | ||
output[line++] += buffer[pixelOffset++] * amountToNext; | ||
output[line++] += buffer[pixelOffset++] * amountToNext; | ||
output[line++] += buffer[pixelOffset] * amountToNext; | ||
} | ||
currentPosition = actualPosition = actualPosition + 3; | ||
weight -= amountToNext; | ||
} else { | ||
for (line = 0, pixelOffset = actualPosition; line < this.originalHeightMultipliedByChannels; pixelOffset += nextLineOffsetOriginalWidth) { | ||
output[line++] += buffer[pixelOffset++] * weight; | ||
output[line++] += buffer[pixelOffset++] * weight; | ||
output[line++] += buffer[pixelOffset] * weight; | ||
} | ||
currentPosition += weight; | ||
break; | ||
} | ||
} while (weight > 0 && actualPosition < this.originalWidthMultipliedByChannels); | ||
for (line = 0, pixelOffset = outputOffset; line < this.originalHeightMultipliedByChannels; pixelOffset += nextLineOffsetTargetWidth) { | ||
outputBuffer[pixelOffset++] = output[line++] * ratioWeightDivisor; | ||
outputBuffer[pixelOffset++] = output[line++] * ratioWeightDivisor; | ||
outputBuffer[pixelOffset] = output[line++] * ratioWeightDivisor; | ||
} | ||
outputOffset += 3; | ||
} while (outputOffset < this.targetWidthMultipliedByChannels); | ||
return outputBuffer; | ||
} | ||
Resize.prototype.resizeWidthInterpolatedRGB = function (buffer) { | ||
var ratioWeight = this.ratioWeightWidthPass; | ||
var weight = 0; | ||
var finalOffset = 0; | ||
@@ -121,3 +71,3 @@ var pixelOffset = 0; | ||
//Handle for only one interpolation input being valid for start calculation: | ||
for (var targetPosition = 0; weight < 1 / 3; targetPosition += 3, weight += ratioWeight) { | ||
for (var targetPosition = 0; weight < 1 / 3; targetPosition += channelsNum, weight += ratioWeight) { | ||
for (finalOffset = targetPosition, pixelOffset = 0; finalOffset < this.widthPassResultSize; pixelOffset += this.originalWidthMultipliedByChannels, finalOffset += this.targetWidthMultipliedByChannels) { | ||
@@ -127,2 +77,4 @@ outputBuffer[finalOffset] = buffer[pixelOffset]; | ||
outputBuffer[finalOffset + 2] = buffer[pixelOffset + 2]; | ||
if (!fourthChannel) continue; | ||
outputBuffer[finalOffset + 3] = buffer[pixelOffset + 3]; | ||
} | ||
@@ -132,3 +84,3 @@ } | ||
weight -= 1 / 3; | ||
for (var interpolationWidthSourceReadStop = this.widthOriginal - 1; weight < interpolationWidthSourceReadStop; targetPosition += 3, weight += ratioWeight) { | ||
for (var interpolationWidthSourceReadStop = this.widthOriginal - 1; weight < interpolationWidthSourceReadStop; targetPosition += channelsNum, weight += ratioWeight) { | ||
//Calculate weightings: | ||
@@ -138,10 +90,12 @@ secondWeight = weight % 1; | ||
//Interpolate: | ||
for (finalOffset = targetPosition, pixelOffset = Math.floor(weight) * 3; finalOffset < this.widthPassResultSize; pixelOffset += this.originalWidthMultipliedByChannels, finalOffset += this.targetWidthMultipliedByChannels) { | ||
outputBuffer[finalOffset] = (buffer[pixelOffset] * firstWeight) + (buffer[pixelOffset + 3] * secondWeight); | ||
outputBuffer[finalOffset + 1] = (buffer[pixelOffset + 1] * firstWeight) + (buffer[pixelOffset + 4] * secondWeight); | ||
outputBuffer[finalOffset + 2] = (buffer[pixelOffset + 2] * firstWeight) + (buffer[pixelOffset + 5] * secondWeight); | ||
for (finalOffset = targetPosition, pixelOffset = Math.floor(weight) * channelsNum; finalOffset < this.widthPassResultSize; pixelOffset += this.originalWidthMultipliedByChannels, finalOffset += this.targetWidthMultipliedByChannels) { | ||
outputBuffer[finalOffset] = (buffer[pixelOffset] * firstWeight) + (buffer[pixelOffset + channelsNum] * 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) continue; | ||
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 - 3; targetPosition < this.targetWidthMultipliedByChannels; targetPosition += 3) { | ||
for (interpolationWidthSourceReadStop = this.originalWidthMultipliedByChannels - channelsNum; targetPosition < this.targetWidthMultipliedByChannels; targetPosition += channelsNum) { | ||
for (finalOffset = targetPosition, pixelOffset = interpolationWidthSourceReadStop; finalOffset < this.widthPassResultSize; pixelOffset += this.originalWidthMultipliedByChannels, finalOffset += this.targetWidthMultipliedByChannels) { | ||
@@ -151,2 +105,4 @@ outputBuffer[finalOffset] = buffer[pixelOffset]; | ||
outputBuffer[finalOffset + 2] = buffer[pixelOffset + 2]; | ||
if (!fourthChannel) continue; | ||
outputBuffer[finalOffset + 3] = buffer[pixelOffset + 3]; | ||
} | ||
@@ -157,3 +113,4 @@ } | ||
Resize.prototype.resizeWidthRGBA = function (buffer) { | ||
Resize.prototype._resizeWidthRGBChannels = function (buffer, fourthChannel) { | ||
var channelsNum = fourthChannel ? 4 : 3; | ||
var ratioWeight = this.ratioWeightWidthPass; | ||
@@ -168,6 +125,12 @@ var ratioWeightDivisor = 1 / ratioWeight; | ||
var outputOffset = 0; | ||
var nextLineOffsetOriginalWidth = this.originalWidthMultipliedByChannels - 3; | ||
var nextLineOffsetTargetWidth = this.targetWidthMultipliedByChannels - 3; | ||
var nextLineOffsetOriginalWidth = this.originalWidthMultipliedByChannels - channelsNum + 1; | ||
var nextLineOffsetTargetWidth = this.targetWidthMultipliedByChannels - channelsNum + 1; | ||
var output = this.outputWidthWorkBench; | ||
var outputBuffer = this.widthBuffer; | ||
var trustworthyColorsCount = this.outputWidthWorkBenchOpaquePixelsCount; | ||
var multiplier = 1; | ||
var r = 0; | ||
var g = 0; | ||
var b = 0; | ||
var a = 0; | ||
do { | ||
@@ -178,3 +141,5 @@ for (line = 0; line < this.originalHeightMultipliedByChannels;) { | ||
output[line++] = 0; | ||
if (!fourthChannel) continue; | ||
output[line++] = 0; | ||
trustworthyColorsCount[line / channelsNum - 1] = 0; | ||
} | ||
@@ -184,18 +149,20 @@ weight = ratioWeight; | ||
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) continue; | ||
output[line++] += a * multiplier; | ||
trustworthyColorsCount[line / channelsNum - 1] += (a ? multiplier : 0); | ||
} | ||
if (weight >= amountToNext) { | ||
for (line = 0, pixelOffset = actualPosition; line < this.originalHeightMultipliedByChannels; pixelOffset += nextLineOffsetOriginalWidth) { | ||
output[line++] += buffer[pixelOffset++] * amountToNext; | ||
output[line++] += buffer[pixelOffset++] * amountToNext; | ||
output[line++] += buffer[pixelOffset++] * amountToNext; | ||
output[line++] += buffer[pixelOffset] * amountToNext; | ||
} | ||
currentPosition = actualPosition = actualPosition + 4; | ||
currentPosition = actualPosition = actualPosition + channelsNum; | ||
weight -= amountToNext; | ||
} else { | ||
for (line = 0, pixelOffset = actualPosition; line < this.originalHeightMultipliedByChannels; pixelOffset += nextLineOffsetOriginalWidth) { | ||
output[line++] += buffer[pixelOffset++] * weight; | ||
output[line++] += buffer[pixelOffset++] * weight; | ||
output[line++] += buffer[pixelOffset++] * weight; | ||
output[line++] += buffer[pixelOffset] * weight; | ||
} | ||
currentPosition += weight; | ||
@@ -206,8 +173,11 @@ break; | ||
for (line = 0, pixelOffset = outputOffset; line < this.originalHeightMultipliedByChannels; pixelOffset += nextLineOffsetTargetWidth) { | ||
outputBuffer[pixelOffset++] = output[line++] * ratioWeightDivisor; | ||
outputBuffer[pixelOffset++] = output[line++] * ratioWeightDivisor; | ||
outputBuffer[pixelOffset++] = output[line++] * ratioWeightDivisor; | ||
outputBuffer[pixelOffset] = output[line++] * ratioWeightDivisor; | ||
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) continue; | ||
outputBuffer[++pixelOffset] = output[line++] * ratioWeightDivisor; | ||
} | ||
outputOffset += 4; | ||
outputOffset += channelsNum; | ||
} while (outputOffset < this.targetWidthMultipliedByChannels); | ||
@@ -217,46 +187,3 @@ return outputBuffer; | ||
Resize.prototype.resizeWidthInterpolatedRGBA = function (buffer) { | ||
var ratioWeight = this.ratioWeightWidthPass; | ||
var weight = 0; | ||
var finalOffset = 0; | ||
var pixelOffset = 0; | ||
var firstWeight = 0; | ||
var secondWeight = 0; | ||
var outputBuffer = this.widthBuffer; | ||
//Handle for only one interpolation input being valid for start calculation: | ||
for (var targetPosition = 0; weight < 1 / 3; targetPosition += 4, 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]; | ||
outputBuffer[finalOffset + 3] = buffer[pixelOffset + 3]; | ||
} | ||
} | ||
//Adjust for overshoot of the last pass's counter: | ||
weight -= 1 / 3; | ||
for (var interpolationWidthSourceReadStop = this.widthOriginal - 1; weight < interpolationWidthSourceReadStop; targetPosition += 4, weight += ratioWeight) { | ||
//Calculate weightings: | ||
secondWeight = weight % 1; | ||
firstWeight = 1 - secondWeight; | ||
//Interpolate: | ||
for (finalOffset = targetPosition, pixelOffset = Math.floor(weight) * 4; finalOffset < this.widthPassResultSize; pixelOffset += this.originalWidthMultipliedByChannels, finalOffset += this.targetWidthMultipliedByChannels) { | ||
outputBuffer[finalOffset] = (buffer[pixelOffset] * firstWeight) + (buffer[pixelOffset + 4] * secondWeight); | ||
outputBuffer[finalOffset + 1] = (buffer[pixelOffset + 1] * firstWeight) + (buffer[pixelOffset + 5] * secondWeight); | ||
outputBuffer[finalOffset + 2] = (buffer[pixelOffset + 2] * firstWeight) + (buffer[pixelOffset + 6] * secondWeight); | ||
outputBuffer[finalOffset + 3] = (buffer[pixelOffset + 3] * firstWeight) + (buffer[pixelOffset + 7] * secondWeight); | ||
} | ||
} | ||
//Handle for only one interpolation input being valid for end calculation: | ||
for (interpolationWidthSourceReadStop = this.originalWidthMultipliedByChannels - 4; targetPosition < this.targetWidthMultipliedByChannels; targetPosition += 4) { | ||
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]; | ||
outputBuffer[finalOffset + 3] = buffer[pixelOffset + 3]; | ||
} | ||
} | ||
return outputBuffer; | ||
} | ||
Resize.prototype.resizeHeightRGB = function (buffer) { | ||
Resize.prototype._resizeHeightRGBChannels = function(buffer, fourthChannel) { | ||
var ratioWeight = this.ratioWeightHeightPass; | ||
@@ -272,2 +199,9 @@ var ratioWeightDivisor = 1 / ratioWeight; | ||
var outputBuffer = this.heightBuffer; | ||
var trustworthyColorsCount = this.outputHeightWorkBenchOpaquePixelsCount; | ||
var caret = 0; | ||
var multiplier = 1; | ||
var r = 0; | ||
var g = 0; | ||
var b = 0; | ||
var a = 0; | ||
do { | ||
@@ -278,2 +212,5 @@ for (pixelOffset = 0; pixelOffset < this.targetWidthMultipliedByChannels;) { | ||
output[pixelOffset++] = 0; | ||
if (!fourthChannel) continue; | ||
output[pixelOffset++] = 0; | ||
trustworthyColorsCount[pixelOffset / 4 - 1] = 0; | ||
} | ||
@@ -283,16 +220,21 @@ weight = ratioWeight; | ||
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) continue; | ||
output[pixelOffset++] += a * multiplier; | ||
trustworthyColorsCount[pixelOffset / 4 - 1] += (a ? multiplier : 0); | ||
} | ||
if (weight >= amountToNext) { | ||
for (pixelOffset = 0; pixelOffset < this.targetWidthMultipliedByChannels;) { | ||
output[pixelOffset++] += buffer[actualPosition++] * amountToNext; | ||
output[pixelOffset++] += buffer[actualPosition++] * amountToNext; | ||
output[pixelOffset++] += buffer[actualPosition++] * amountToNext; | ||
} | ||
currentPosition = actualPosition; | ||
currentPosition = actualPosition = caret; | ||
weight -= amountToNext; | ||
} else { | ||
for (pixelOffset = 0, amountToNext = actualPosition; pixelOffset < this.targetWidthMultipliedByChannels;) { | ||
output[pixelOffset++] += buffer[amountToNext++] * weight; | ||
output[pixelOffset++] += buffer[amountToNext++] * weight; | ||
output[pixelOffset++] += buffer[amountToNext++] * weight; | ||
} | ||
currentPosition += weight; | ||
@@ -303,10 +245,31 @@ break; | ||
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) continue; | ||
outputBuffer[outputOffset++] = Math.round(output[pixelOffset++] * ratioWeightDivisor); | ||
outputBuffer[outputOffset++] = Math.round(output[pixelOffset++] * ratioWeightDivisor); | ||
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) { | ||
@@ -350,51 +313,8 @@ var ratioWeight = this.ratioWeightHeightPass; | ||
Resize.prototype.resizeHeightRGB = function (buffer) { | ||
return this._resizeHeightRGBChannels(buffer, false); | ||
} | ||
Resize.prototype.resizeHeightRGBA = function (buffer) { | ||
var ratioWeight = this.ratioWeightHeightPass; | ||
var ratioWeightDivisor = 1 / ratioWeight; | ||
var weight = 0; | ||
var amountToNext = 0; | ||
var actualPosition = 0; | ||
var currentPosition = 0; | ||
var pixelOffset = 0; | ||
var outputOffset = 0; | ||
var output = this.outputHeightWorkBench; | ||
var outputBuffer = this.heightBuffer; | ||
do { | ||
for (pixelOffset = 0; pixelOffset < this.targetWidthMultipliedByChannels;) { | ||
output[pixelOffset++] = 0; | ||
output[pixelOffset++] = 0; | ||
output[pixelOffset++] = 0; | ||
output[pixelOffset++] = 0; | ||
} | ||
weight = ratioWeight; | ||
do { | ||
amountToNext = 1 + actualPosition - currentPosition; | ||
if (weight >= amountToNext) { | ||
for (pixelOffset = 0; pixelOffset < this.targetWidthMultipliedByChannels;) { | ||
output[pixelOffset++] += buffer[actualPosition++] * amountToNext; | ||
output[pixelOffset++] += buffer[actualPosition++] * amountToNext; | ||
output[pixelOffset++] += buffer[actualPosition++] * amountToNext; | ||
output[pixelOffset++] += buffer[actualPosition++] * amountToNext; | ||
} | ||
currentPosition = actualPosition; | ||
weight -= amountToNext; | ||
} else { | ||
for (pixelOffset = 0, amountToNext = actualPosition; pixelOffset < this.targetWidthMultipliedByChannels;) { | ||
output[pixelOffset++] += buffer[amountToNext++] * weight; | ||
output[pixelOffset++] += buffer[amountToNext++] * weight; | ||
output[pixelOffset++] += buffer[amountToNext++] * weight; | ||
output[pixelOffset++] += buffer[amountToNext++] * weight; | ||
} | ||
currentPosition += weight; | ||
break; | ||
} | ||
} while (weight > 0 && actualPosition < this.widthPassResultSize); | ||
for (pixelOffset = 0; pixelOffset < this.targetWidthMultipliedByChannels;) { | ||
outputBuffer[outputOffset++] = Math.round(output[pixelOffset++] * ratioWeightDivisor); | ||
outputBuffer[outputOffset++] = Math.round(output[pixelOffset++] * ratioWeightDivisor); | ||
outputBuffer[outputOffset++] = Math.round(output[pixelOffset++] * ratioWeightDivisor); | ||
outputBuffer[outputOffset++] = Math.round(output[pixelOffset++] * ratioWeightDivisor); | ||
} | ||
} while (outputOffset < this.finalResultSize); | ||
return outputBuffer; | ||
return this._resizeHeightRGBChannels(buffer, true); | ||
} | ||
@@ -416,2 +336,5 @@ | ||
this.outputWidthWorkBench = this.generateFloatBuffer(this.originalHeightMultipliedByChannels); | ||
if (this.colorChannels > 3) { | ||
this.outputWidthWorkBenchOpaquePixelsCount = this.generateFloat64Buffer(this.heightOriginal); | ||
} | ||
} | ||
@@ -425,2 +348,5 @@ } | ||
this.outputHeightWorkBench = this.generateFloatBuffer(this.targetWidthMultipliedByChannels); | ||
if (this.colorChannels > 3) { | ||
this.outputHeightWorkBenchOpaquePixelsCount = this.generateFloat64Buffer(this.targetWidth); | ||
} | ||
} | ||
@@ -438,2 +364,11 @@ } | ||
Resize.prototype.generateFloat64Buffer = function (bufferLength) { | ||
//Generate a float64 typed array buffer: | ||
try { | ||
return new Float64Array(bufferLength); | ||
} catch (error) { | ||
return []; | ||
} | ||
} | ||
Resize.prototype.generateUint8Buffer = function (bufferLength) { | ||
@@ -440,0 +375,0 @@ //Generate a uint8 typed array buffer: |
@@ -204,2 +204,3 @@ /** | ||
var a = 0; | ||
var realColors = 0; | ||
for (var y = 0; y < hM; y++) { | ||
@@ -210,6 +211,12 @@ var yPos = i * hM + y; | ||
var xyPos = (yPos * wDst2 + xPos) * 4; | ||
r += buf2[xyPos]; | ||
g += buf2[xyPos+1]; | ||
b += buf2[xyPos+2]; | ||
a += buf2[xyPos+3]; | ||
var pixelAplha = buf2[xyPos+3]; | ||
if (pixelAplha) { | ||
r += buf2[xyPos]; | ||
g += buf2[xyPos+1]; | ||
b += buf2[xyPos+2]; | ||
realColors++; | ||
} | ||
a += pixelAplha; | ||
} | ||
@@ -219,5 +226,5 @@ } | ||
var pos = (i*wDst + j) * 4; | ||
bufDst[pos] = Math.round(r / m); | ||
bufDst[pos+1] = Math.round(g / m); | ||
bufDst[pos+2] = Math.round(b / m); | ||
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); | ||
@@ -280,2 +287,2 @@ } | ||
} | ||
} | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 3 instances in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
Found 1 instance in 1 package
47
2
500
4
1
1581341
16
3964
+ Addedmkdirp@0.5.1
+ Addedbmp-js@0.0.3(transitive)
+ Addedminimist@0.0.8(transitive)
+ Addedmkdirp@0.5.1(transitive)
- Removedbmp-js@0.0.1(transitive)
Updatedbmp-js@0.0.3