Socket
Socket
Sign inDemoInstall

imagejs

Package Overview
Dependencies
Maintainers
1
Versions
9
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

imagejs - npm Package Compare versions

Comparing version 0.0.5 to 0.0.6

lib/utils.js

175

lib/bitmap.js

@@ -28,3 +28,2 @@ /**

var Promise = require("bluebird");
var jpeg = require("jpeg-js");

@@ -35,3 +34,3 @@ //var png = require("png-js");

var Enums = require("./enums");
var Utils = require("./utils");
var Resize = require("./resize");

@@ -62,2 +61,7 @@

};
// optional colour
if (options.color) {
this._fill(options.color);
}
}

@@ -166,5 +170,12 @@ }

readFile: function(filename, options) {
options = this._parseOptions(options, filename);
var stream = fs.createReadStream(filename);
return this.read(stream, options);
return Utils.fs.exists(filename)
.then(function(exists) {
if (exists) {
options = this._parseOptions(options, filename);
var stream = fs.createReadStream(filename);
return this.read(stream, options);
} else {
throw new Error("File Not Found: " + filename);
}
});
},

@@ -217,10 +228,36 @@

clone: function() {
return new Bitmap({
width: this.width,
height: this.height,
data: new Buffer(this._data.data)
});
},
setPixel: function(x,y, r,g,b,a) {
if (g === undefined) {
var color = r;
r = color.r;
g = color.g;
b = color.b;
a = color.a;
}
if (a === undefined) a = 255;
var pos = 4 * (y * this.width + x);
this.buffer[pos++] = r;
this.buffer[pos++] = g;
this.buffer[pos++] = b;
this.buffer[pos++] = a;
var pos = (y * this.width + x) * 4;
var buffer = this._data.data;
buffer[pos++] = r;
buffer[pos++] = g;
buffer[pos++] = b;
buffer[pos++] = a;
},
getPixel: function(x,y, color) {
var pos = (y * this.width + x) * 4;
color = color || {};
var buffer = this._data.data;
color.r = buffer[pos++];
color.g = buffer[pos++];
color.b = buffer[pos++];
color.a = buffer[pos++];
return color;
},

@@ -246,32 +283,30 @@ negative: function() {

var that = new Bitmap(options);
// crop determines from where in src to fetch image data
options.crop = {
left: 0, top: 0,
width: this.width, height: this.height
};
// bounds determines where in dst to draw the scaled image
options.bounds = {
left: 0, top: 0,
width: options.width, height: options.height
};
var temp;
switch (options.fit) {
case "pad": // fit all of src in dst with optional pad colour
options.padColor = options.padColor || transparentBlack;
case "pad": // fit all of src in dst with aspect ratio preserved.
var padColor = options.padColor || transparentBlack;
var srcAr = this.width / this.height;
var dstAr = that.width / that.height;
var w2 = Math.round(srcAr * that.height);
var h2 = Math.round(that.width / srcAr);
var wMargin = 0;
var hMargin = 0;
if (w2 < that.width) {
// pad sides
var dw = that.width - w2;
options.bounds.left = Math.round(dw / 2);
options.bounds.width = w2;
temp = new Bitmap({width: w2, height: that.height});
wMargin = (that.width - w2) / 2;
that._fill(padColor, {left: 0, top: 0, width: Math.floor(wMargin), height: that.height});
that._fill(padColor, {left: that.width - Math.ceil(wMargin), top: 0, width: Math.ceil(wMargin), height: that.height});
} else if (h2 < that.height) {
// pad top & bottom
var dh = that.height - h2;
options.bounds.top = Math.round(dh / 2);
options.bounds.height = h2;
temp = new Bitmap({width: that.width, height: h2});
hMargin = (that.height - h2) / 2;
that._fill(padColor, {left: 0, top: 0, width: that.width, height: Math.floor(hMargin)});
that._fill(padColor, {left: 0, top: that.height - Math.ceil(hMargin), width: that.width, height: Math.ceil(hMargin)});
} else {
// stretch straight into that
}
Resize[options.algorithm](this, temp, options);
that._blt(temp, {left: Math.floor(wMargin), top: Math.floor(hMargin)});
break;
case "crop": // crop original to fit in dst with no pad
case "crop": // crop original to fit in dst with aspect ratio preserved
var gravity = options.gravity || {x: 0.5, y: 0.5};

@@ -284,18 +319,18 @@ var dstAr = that.width / that.height;

var dw = this.width - w2;
options.crop.left = Math.round(gravity.x * dw);
options.crop.width = w2;
temp = this.crop({left: Math.round(gravity.x * dw), top: 0, width: w2, height: this.height});
} else if (h2 < this.height) {
// crop src height
var dh = this.height - h2;
options.crop.top = Math.round(gravity.y * dh);
options.crop.height = h2;
temp = this.crop({left: 0, top: Math.round(gravity.y * dh), width: this.width, height: h2});
} else {
temp = this;
}
Resize[options.algorithm](temp, that, options);
break;
case "stretch":
default:
// default crop and bounds are set above
Resize[options.algorithm](this, that, options);
break;
}
Resize[options.algorithm](this, that, options);
return that;

@@ -309,15 +344,14 @@ },

var h = options.height;
//console.log("Crop: l="+l + ", t="+t + ", w="+w + ", h="+h);
var that = new Bitmap({width: w, height: h});
var src = this._data.data;
var dst = that._data.data;
var srcBuf = this._data.data;
var dstBuf = that._data.data;
var w4 = 2 * 4;
var w4 = w * 4;
for (var i = 0; i < h; i++) {
var srcPos = ((i+t)*w + l) * 4;
var dstPos = i * 4;
for (var j = 0; j < w4; j++) {
dst[dstPos++] = src[srcPos++];
}
var srcPos = ((i+t)*this.width + l) * 4;
var dstPos = i * w * 4;
srcBuf.copy(dstBuf, dstPos, srcPos, srcPos + w4);
}

@@ -361,3 +395,56 @@ return that;

return that;
},
_fill: function(color, options) {
options = options || {};
var t = options.top || 0;
var l = options.left || 0;
var w = options.width || this.width - l;
var h = options.height || this.height - t;
//console.log("Fill: l="+l + ", t="+t + ", w="+w + ", h="+h);
color = color || transparentBlack;
var r = color.r || 0;
var g = color.g || 0;
var b = color.b || 0;
var a = color.a || 0;
//console.log(" r="+r + ", g="+g + ", b="+b + ", a="+a);
var buf = this._data.data;
var bottom = t + h;
var right = l + w;
var width = this.width;
// step 1 - build first scanline
var pos1 = (t*width + l) * 4;
var pos = pos1;
for (var j = l; j < right; j++) {
buf[pos++] = r;
buf[pos++] = g;
buf[pos++] = b;
buf[pos++] = a;
}
// step 2 - copy first scanline to all the others
var pos1End = pos1 + w * 4;
for (var i = t; i < bottom; i++) {
var pos = (i*width + l) * 4;
buf.copy(buf, pos, pos1, pos1End);
}
},
_blt: function(that, options) {
var left = options.left;
var top = options.top;
var width = Math.min(this.width-left, that.width);
var height = Math.min(this.height-top, that.height);
//console.log("_blt: left="+left + ", top="+top + ", width="+width + ", height="+height)
var w4 = width * 4;
var srcBuf = that._data.data;
var dstBuf = this._data.data;
for (var i = 0; i < height; i++) {
var srcPos = i * that.width * 4;
var dstPos = ((i+top)*this.width + left) * 4;
srcBuf.copy(dstBuf, dstPos, srcPos, srcPos + w4);
}
}
}

@@ -40,100 +40,23 @@ /**

_pad: function(dst, options) {
var top = options.bounds.top;
var left = options.bounds.left;
var bottom = top + options.bounds.height;
var right = left + options.bounds.width;
// optimization - quit now if top and left are zero
if (!top && !left) {
return;
}
var width = dst.width;
var height = dst.height;
var data = dst._data.data;
var r = options.padColor.r;
var g = options.padColor.g;
var b = options.padColor.b;
var a = options.padColor.a;
var i, j, pos;
// top margin
for (i = 0; i < top; i++) {
for (j = 0; j < width; j++) {
pos = (i * width + j) * 4;
data[pos++] = r;
data[pos++] = g;
data[pos++] = b;
data[pos++] = a;
}
}
// bottom margin
for (i = bottom; i < height; i++) {
for (j = 0; j < width; j++) {
pos = (i * width + j) * 4;
data[pos++] = r;
data[pos++] = g;
data[pos++] = b;
data[pos++] = a;
}
}
// left margin
for (i = 0; i < height; i++) {
for (j = 0; j < left; j++) {
pos = (i * width + j) * 4;
data[pos++] = r;
data[pos++] = g;
data[pos++] = b;
data[pos++] = a;
}
}
// right margin
for (i = 0; i < height; i++) {
for (j = right; j < width; j++) {
pos = (i * width + j) * 4;
data[pos++] = r;
data[pos++] = g;
data[pos++] = b;
data[pos++] = a;
}
}
},
nearestNeighbor: function(src, dst, options) {
this._pad(dst, options);
var srcWidth = src.width;
var srcHeight = src.height;
var dstWidth = dst.width;
var dstHeight = dst.height;
var wSrc = src.width;
var hSrc = src.height;
//console.log("wSrc="+wSrc + ", hSrc="+hSrc);
var tSrc = options.crop.top;
var lSrc = options.crop.left;
var wSrc = options.crop.width;
var hSrc = options.crop.height;
var bSrc = tSrc + hSrc;
var rSrc = lSrc + wSrc;
//console.log("tSrc="+tSrc + ", lSrc="+lSrc + ", wSrc="+wSrc + ", hSrc="+hSrc + ", bSrc="+bSrc + ", rSrc="+rSrc);
var wDst = dst.width;
var hDst = dst.height;
//console.log("wDst="+wDst + ", hDst="+hDst);
var tDst = options.bounds.top;
var lDst = options.bounds.left;
var wDst = options.bounds.width;
var hDst = options.bounds.height;
var bDst = tDst + hDst;
var rDst = lDst + wDst;
//console.log("tDst="+tDst + ", lDst="+lDst + ", wDst="+wDst + ", hDst="+hDst + ", bDst="+bDst + ", rDst="+rDst);
var bufSrc = src._data.data;
var bufDst = dst._data.data;
for (var i = tDst; i < bDst; i++) {
for (var j = lDst; j < rDst; j++) {
var posDst = (i * dstWidth + j) * 4;
var iSrc = tSrc + Math.round((i-tDst) * hSrc / hDst);
var jSrc = lSrc + Math.round((j-lDst) * wSrc / wDst);
var posSrc = (iSrc * srcWidth + jSrc) * 4;
for (var i = 0; i < hDst; i++) {
for (var j = 0; j < wDst; j++) {
var posDst = (i * wDst + j) * 4;
var iSrc = Math.round(i * hSrc / hDst);
var jSrc = Math.round(j * wSrc / wDst);
var posSrc = (iSrc * wSrc + jSrc) * 4;
bufDst[posDst++] = bufSrc[posSrc++];

@@ -147,25 +70,11 @@ bufDst[posDst++] = bufSrc[posSrc++];

bilinearInterpolation: function(src, dst, options) {
this._pad(dst, options);
var srcWidth = src.width;
var srcHeight = src.height;
var dstWidth = dst.width;
var dstHeight = dst.height;
var wSrc = src.width;
var hSrc = src.height;
//console.log("wSrc="+wSrc + ", hSrc="+hSrc);
var tSrc = options.crop.top;
var lSrc = options.crop.left;
var wSrc = options.crop.width;
var hSrc = options.crop.height;
var bSrc = tSrc + hSrc;
var rSrc = lSrc + wSrc;
//console.log("tSrc="+tSrc + ", lSrc="+lSrc + ", wSrc="+wSrc + ", hSrc="+hSrc + ", bSrc="+bSrc + ", rSrc="+rSrc);
var wDst = dst.width;
var hDst = dst.height;
//console.log("wDst="+wDst + ", hDst="+hDst);
var tDst = options.bounds.top;
var lDst = options.bounds.left;
var wDst = options.bounds.width;
var hDst = options.bounds.height;
var bDst = tDst + hDst;
var rDst = lDst + wDst;
//console.log("tDst="+tDst + ", lDst="+lDst + ", wDst="+wDst + ", hDst="+hDst + ", bDst="+bDst + ", rDst="+rDst);
var bufSrc = src._data.data;

@@ -183,4 +92,4 @@ var bufDst = dst._data.data;

var assign = function(pos, offset, x, xMin, xMax, y, yMin, yMax) {
var posMin = (yMin * srcWidth + xMin) * 4 + offset;
var posMax = (yMin * srcWidth + xMax) * 4 + offset;
var posMin = (yMin * wSrc + xMin) * 4 + offset;
var posMax = (yMin * wSrc + xMax) * 4 + offset;
var vMin = interpolate(x, xMin, bufSrc[posMin], xMax, bufSrc[posMax]);

@@ -192,4 +101,4 @@

} else {
posMin = (yMax * srcWidth + xMin) * 4 + offset;
posMax = (yMax * srcWidth + xMax) * 4 + offset;
posMin = (yMax * wSrc + xMin) * 4 + offset;
posMax = (yMax * wSrc + xMax) * 4 + offset;
var vMax = interpolate(x, xMin, bufSrc[posMin], xMax, bufSrc[posMax]);

@@ -201,14 +110,14 @@

for (var i = tDst; i < bDst; i++) {
for (var j = lDst; j < rDst; j++) {
var posDst = (i * dstWidth + j) * 4;
for (var i = 0; i < hDst; i++) {
for (var j = 0; j < wDst; j++) {
var posDst = (i * wDst + j) * 4;
// x & y in src coordinates
var x = lSrc + (j-lDst) * wSrc / wDst;
var x = j * wSrc / wDst;
var xMin = Math.floor(x);
var xMax = Math.min(Math.ceil(x), rSrc-1);
var xMax = Math.min(Math.ceil(x), wSrc-1);
var y = tSrc + (i-tDst) * hSrc / hDst;
var y = i * hSrc / hDst;
var yMin = Math.floor(y);
var yMax = Math.min(Math.ceil(y), bSrc-1);
var yMax = Math.min(Math.ceil(y), hSrc-1);

@@ -225,25 +134,13 @@ assign(posDst, 0, x, xMin, xMax, y, yMin, yMax);

this._pad(dst, options);
var bufSrc = src._data.data;
var bufDst = dst._data.data;
var srcWidth = src.width;
var srcHeight = src.height;
var dstWidth = dst.width;
var dstHeight = dst.height;
var wSrc = src.width;
var hSrc = src.height;
//console.log("wSrc="+wSrc + ", hSrc="+hSrc + ", srcLen="+bufSrc.length);
var tSrc = options.crop.top;
var lSrc = options.crop.left;
var wSrc = options.crop.width;
var hSrc = options.crop.height;
var bSrc = tSrc + hSrc;
var rSrc = lSrc + wSrc;
//console.log("tSrc="+tSrc + ", lSrc="+lSrc + ", wSrc="+wSrc + ", hSrc="+hSrc + ", bSrc="+bSrc + ", rSrc="+rSrc);
var wDst = dst.width;
var hDst = dst.height;
//console.log("wDst="+wDst + ", hDst="+hDst + ", dstLen="+bufDst.length);
var tDst = options.bounds.top;
var lDst = options.bounds.left;
var wDst = options.bounds.width;
var hDst = options.bounds.height;
var bDst = tDst + hDst;
var rDst = lDst + wDst;
//console.log("tDst="+tDst + ", lDst="+lDst + ", wDst="+wDst + ", hDst="+hDst + ", bDst="+bDst + ", rDst="+rDst);
// when dst smaller than src/2, interpolate first to a multiple between 0.5 and 1.0 src, then sum squares

@@ -256,5 +153,2 @@ var wM = Math.max(1, Math.floor(wSrc / wDst));

var bufSrc = src._data.data;
var bufDst = dst._data.data;
// ===========================================================

@@ -268,7 +162,10 @@ // Pass 1 - interpolate rows

// calculate x in src crop coords
var x = j * wSrc / wDst2;
// 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
var x = j * (wSrc-1) / wDst2;
var xPos = Math.floor(x);
var t = x - xPos;
var srcPos = ((i + tSrc) * srcWidth + xPos + lSrc) * 4;
var srcPos = (i * wSrc + xPos) * 4;

@@ -278,6 +175,6 @@ var buf1Pos = (i * wDst2 + j) * 4;

var kPos = srcPos + k;
var x0 = (xPos + lSrc > 0) ? bufSrc[kPos - 4] : 2*bufSrc[kPos]-bufSrc[kPos+4];
var x0 = (xPos > 0) ? bufSrc[kPos - 4] : 2*bufSrc[kPos]-bufSrc[kPos+4];
var x1 = bufSrc[kPos];
var x2 = bufSrc[kPos + 4];
var x3 = (xPos + lSrc < srcWidth - 1) ? bufSrc[kPos + 8] : 2*bufSrc[kPos + 4]-bufSrc[kPos];
var x3 = (xPos < wSrc - 2) ? bufSrc[kPos + 8] : 2*bufSrc[kPos + 4]-bufSrc[kPos];
buf1[buf1Pos+k] = interpolate(x0,x1,x2,x3,t);

@@ -287,3 +184,3 @@ }

}
//this._writeFile(wDst2, hSrc, buf1, "out/bc/buf1.jpg");
//this._writeFile(wDst2, hSrc, buf1, "out/buf1.jpg");

@@ -299,3 +196,6 @@ // ===========================================================

// calculate y in buf1 coords
var y = i * hSrc / hDst2;
// 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
var y = i * (hSrc-1) / hDst2;
var yPos = Math.floor(y);

@@ -310,3 +210,3 @@ var t = y - yPos;

var y2 = buf1[kPos + wDst2*4];
var y3 = (yPos < hSrc) ? buf1[kPos + wDst2*8] : 2*buf1[kPos + wDst2*4]-buf1[kPos];
var y3 = (yPos < hSrc-2) ? buf1[kPos + wDst2*8] : 2*buf1[kPos + wDst2*4]-buf1[kPos];

@@ -317,3 +217,3 @@ buf2[buf2Pos + k] = interpolate(y0,y1,y2,y3,t);

}
//this._writeFile(wDst2, hDst2, buf2, "out/bc/buf2.jpg");
//this._writeFile(wDst2, hDst2, buf2, "out/buf2.jpg");

@@ -343,3 +243,3 @@ // ===========================================================

var pos = ((i+tDst)*dstWidth + j + lDst) * 4;
var pos = (i*wDst + j) * 4;
bufDst[pos] = Math.round(r / m);

@@ -352,14 +252,4 @@ bufDst[pos+1] = Math.round(g / m);

} else {
// 1 to 1 copy
for (var i = 0; i < hDst; i++) {
for (var j = 0; j < wDst; j++) {
var buf2Pos = (i*wDst + j) * 4;
var dstPos = ((i+tDst)*dstWidth + j + lDst) * 4;
bufDst[dstPos++] = buf2[buf2Pos++];
bufDst[dstPos++] = buf2[buf2Pos++];
bufDst[dstPos++] = buf2[buf2Pos++];
bufDst[dstPos++] = buf2[buf2Pos++];
}
}
// replace dst buffer with buf2
dst._data.data = buf2;
}

@@ -366,0 +256,0 @@ },

{
"name": "imagejs",
"version": "0.0.5",
"version": "0.0.6",
"description": "Image Processor",

@@ -17,3 +17,4 @@ "private": false,

"keywords": [
"image", "bitmap", "jpg", "jpeg", "resize", "negative"
"pure", "javascript", "image", "bitmap", "jpg", "jpeg", "resize", "negative", "crop",
"bilinear", "bicubic", "hermite", "bezier"
],

@@ -20,0 +21,0 @@ "dependencies": {

@@ -17,17 +17,6 @@ # ImageJS

<ul>
<li>
<a href="#resize">Enhanced Resize</a>
<ul>
<li>New Resize Algorithm: Bezier Interpolation</li>
<li>2 Pass algorithm to compensate for undersampling</li>
</ul>
</li>
<li><a href="blur">Blur Images</a></li>
<li><a href="crop">Crop Images</a></li>
<li>
Bug Fixes
<ul>
<li>Fixed enlargement bug</li>
</ul>
</li>
<li>Internal Restructuring</li>
<li>Corrected Documentation</li>
<li>Better Bitmap Construction</li>
<li>Performance Improvements</li>
</ul>

@@ -69,5 +58,9 @@

// Create a blank bitmap 320x200
var blankBitmap = new ImageJS.Bitmap({width: 320, height: 200});
// Create an uninitialized bitmap 320x200
// Note: the bitmap may be filled with random data
var bitmap = new ImageJS.Bitmap({width: 320, height: 200});
// Create a bitmap filled with green
var greenBitmap = new ImageJS.Bitmap({width: 100, height: 100, color: {r: 255, g: 255, b: 255, a: 255});
// Copy a bitmap

@@ -91,8 +84,24 @@ var copy = new ImageJS.Bitmap(otherBitmap);

### Set Pixel
```javascript
// Set a pixel
// where: 0 <= x < width, 0 <= y < height, 0 <= a,r,g,b < 256
bitmap.setPixel(x,y, a,r,g,b);
// where: 0 <= x < width, 0 <= y < height, 0 <= r,g,b,a < 256
bitmap.setPixel(x,y, r,g,b,a);
// Set a pixesl using a color object
var yellow = {r:255, g:255, b:0}; // alpha defaults to 255
bitmap.setPixel(x,y, yellow);
```
### Get Pixel
```javascript
// fetch the color of a pixel
var color = bitmap.getPixel(x,y);
// to improve performance you can supply the color object
var color = {};
color = bitmap.getPixel(x,y, color);
```
### Negative

@@ -146,2 +155,3 @@ ```javascript

* bicubicInterpolation
* hermiteInterpolation
* bezierInterpolation

@@ -194,2 +204,4 @@

| 0.0.3 | <ul><li><a href="#image-resize">Enhanced Resize</a><ul><li>New Resize Algorithm: Bicubic Interpolation</li></ul></li></ul> |
| 0.0.4 | <ul><li><a href="#resizing-bitmaps">Enhanced Resize</a><ul><li>New Resize Algorithm: Bezier Interpolation</li><li>2 Pass algorithm to compensate for undersampling</li></ul></li><li><a href="blur">Blur Images</a></li><li><a href="crop">Crop Images</a></li></ul> |
| 0.0.5 | <ul><li><a href="#resizing-bitmaps">Enhanced Resize</a><ul><li>New Resize Algorithm: Bezier Interpolation</li><li>2 Pass algorithm to compensate for undersampling</li></ul></li><li><a href="blur">Blur Images</a></li><li><a href="crop">Crop Images</a></li></ul> |
| 0.0.6 | <ul><li>Internal Restructuring</li><li>Corrected Documentation</li><li>Better Bitmap Construction</li><li>Performance Improvements</li></ul> |
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc