Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

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.3 to 0.0.4

69

lib/bitmap.js

@@ -228,8 +228,9 @@ /**

var dst = that._data.data;
var srcPos = 0;
var dstPos = 0;
for (var i = 0; i < n; i++) {
var pos = i*4;
dst[pos] = 255 - src[pos];
dst[pos+1] = 255 - src[pos+1];
dst[pos+2] = 255 - src[pos+2];
dst[pos+3] = src[pos+3];
dst[dstPos++] = 255 - src[srcPos++];
dst[dstPos++] = 255 - src[srcPos++];
dst[dstPos++] = 255 - src[srcPos++];
dst[dstPos++] = src[srcPos++];
}

@@ -295,3 +296,61 @@ return that;

return that;
},
crop: function(options) {
var t = options.top;
var l = options.left;
var w = options.width;
var h = options.height;
var that = new Bitmap({width: w, height: h});
var src = this._data.data;
var dst = that._data.data;
var w4 = 2 * 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++];
}
}
return that;
},
blur: function(options) {
// todo: expand to own file with different blur algorithms
var that = new Bitmap({width: this.width, height: this.height});
var w = this.width;
var h = this.height;
var W = w-1;
var H = h-1;
var V = w*4; // used for i offsets
var src = this._data.data;
var dst = that._data.data;
for (var i = 0; i < h; i++) {
for (var j = 0; j < w; j++) {
for (var k = 0; k < 4; k++) {
var pos = (i*w + j) * 4 + k;
var t = src[pos -(i>0?V:0) - (j>0?4:0)] * 1 + // 1/16
src[pos -(i>0?V:0) ] * 2 + // 2/16
src[pos -(i>0?V:0) + (j<W?4:0)] * 1 + // 1/16
src[pos - (j>0?4:0)] * 2 + // 2/16
src[pos ] * 4 + // 4/16
src[pos + (j<W?4:0)] * 2 + // 2/16
src[pos +(i<H?V:0) - (j>0?4:0)] * 1 + // 1/16
src[pos +(i<H?V:0) ] * 2 + // 2/16
src[pos +(i<H?V:0) + (j<W?4:0)] * 1; // 1/16
dst[pos] = Math.round(t/16);
}
}
}
return that;
}
}

176

lib/resize.js

@@ -28,4 +28,14 @@ /**

module.exports = {
_writeFile: function(width, height, data, filename) {
// for debugging
var Bitmap = require("./bitmap");
var bmp = new Bitmap({
width: width, height: height,
data: data
});
bmp.writeFile(filename);
},
_pad: function(dst, options) {

@@ -208,4 +218,5 @@ var top = options.bounds.top;

},
bicubicInterpolation: function(src, dst, options) {
_interpolate2D: function(src, dst, options, interpolate) {
this._pad(dst, options);

@@ -234,24 +245,22 @@

// when dst smaller than src/2, interpolate first to a multiple between 0.5 and 1.0 src, then sum squares
var wM = Math.floor(wSrc / wDst);
var wDst2 = wDst * wM;
var hM = Math.floor(hSrc / hDst);
var hDst2 = hDst * hM;
//console.log("wM="+wM + ", wDst2="+wDst2 + ", hM="+hM + ", hDst2="+hDst2);
var bufSrc = src._data.data;
var bufDst = dst._data.data;
var interpolateCubic = function(x0, x1, x2, x3, t) {
var a0 = x3 - x2 - x0 + x1;
var a1 = x0 - x1 - a0;
var a2 = x2 - x0;
var a3 = x1;
return Math.max(0,Math.min(255,(a0 * (t * t * t)) + (a1 * (t * t)) + (a2 * t) + (a3)));
}
// ===========================================================
// Pass 1 - interpolate scanlines
// buf1 has width of dst and height of src
var buf1 = new Buffer(wDst * hSrc * 4);
// Pass 1 - interpolate rows
// buf1 has width of dst2 and height of src
var buf1 = new Buffer(wDst2 * hSrc * 4);
for (var i = 0; i < hSrc; i++) {
for (var j = 0; j < wDst; j++) {
for (var j = 0; j < wDst2; j++) {
// i in src coords, j in dst coords
// calculate x in src crop coords
var x = j * wSrc / wDst;
var x = j * wSrc / wDst2;
var xPos = Math.floor(x);

@@ -261,45 +270,136 @@ var t = x - xPos;

var buf1Pos = (i * wDst + j) * 4;
var buf1Pos = (i * wDst2 + j) * 4;
for (var k = 0; k < 4; k++) {
var kPos = srcPos + k;
var x0 = (xPos + lSrc > 0) ? bufSrc[kPos - 4] : bufSrc[kPos];
var x0 = (xPos + lSrc > 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] : bufSrc[kPos + 4];
buf1[buf1Pos+k] = interpolateCubic(x0,x1,x2,x3,t);
var x3 = (xPos + lSrc < srcWidth - 1) ? bufSrc[kPos + 8] : 2*bufSrc[kPos + 4]-bufSrc[kPos];
buf1[buf1Pos+k] = interpolate(x0,x1,x2,x3,t);
}
}
}
//var Bitmap = require("./bitmap");
//var tmp = new Bitmap({
// width: wDst, height: hSrc,
// data: buf1
//});
//tmp.writeFile("out/tmp.jpg");
//this._writeFile(wDst2, hSrc, buf1, "out/bc/buf1.jpg");
// ===========================================================
// Pass 2 - interpolate columns
for (var i = 0; i < hDst; i++) {
for (var j = 0; j < wDst; j++) {
// i&j in dst coords
// buf2 has width and height of dst2
var buf2 = new Buffer(wDst2 * hDst2 * 4);
for (var i = 0; i < hDst2; i++) {
for (var j = 0; j < wDst2; j++) {
// i&j in dst2 coords
// calculate y in buf1 coords
var y = i * hSrc / hDst;
var y = i * hSrc / hDst2;
var yPos = Math.floor(y);
var t = y - yPos;
var buf1Pos = (yPos * wDst + j) * 4;
var dstPos = ((i+tDst) * dstWidth + j + lDst) * 4;
var buf1Pos = (yPos * wDst2 + j) * 4;
var buf2Pos = (i * wDst2 + j) * 4;
for (var k = 0; k < 4; k++) {
var kPos = buf1Pos + k;
var y0 = (yPos > 0) ? buf1[kPos - wDst*4] : buf1[kPos];
var y0 = (yPos > 0) ? buf1[kPos - wDst2*4] : 2*buf1[kPos]-buf1[kPos + wDst2*4];
var y1 = buf1[kPos];
var y2 = buf1[kPos + wDst*4];
var y3 = (yPos < hSrc) ? buf1[kPos + wDst*8] : buf1[kPos + wDst*4];
var y2 = buf1[kPos + wDst2*4];
var y3 = (yPos < hSrc) ? buf1[kPos + wDst2*8] : 2*buf1[kPos + wDst2*4]-buf1[kPos];
bufDst[dstPos + k] = interpolateCubic(y0,y1,y2,y3,t);
buf2[buf2Pos + k] = interpolate(y0,y1,y2,y3,t);
}
}
}
//this._writeFile(wDst2, hDst2, buf2, "out/bc/buf2.jpg");
// ===========================================================
// Pass 3 - scale to dst
var m = wM * hM;
if (m > 1) {
for (var i = 0; i < hDst; i++) {
for (var j = 0; j < wDst; j++) {
// i&j in dst bounded coords
var r = 0;
var g = 0;
var b = 0;
var a = 0;
for (var y = 0; y < hM; y++) {
var yPos = i * hM + y;
for (var x = 0; x < wM; x++) {
var xPos = j * wM + x;
var xyPos = (yPos * wDst2 + xPos) * 4;
r += buf2[xyPos];
g += buf2[xyPos+1];
b += buf2[xyPos+2];
a += buf2[xyPos+3];
}
}
var pos = ((i+tDst)*dstWidth + j + lDst) * 4;
bufDst[pos] = Math.round(r / m);
bufDst[pos+1] = Math.round(g / m);
bufDst[pos+2] = Math.round(b / m);
bufDst[pos+3] = Math.round(a / 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++];
}
}
}
},
bicubicInterpolation: function(src, dst, options) {
var interpolateCubic = function(x0, x1, x2, x3, t) {
var a0 = x3 - x2 - x0 + x1;
var a1 = x0 - x1 - a0;
var a2 = x2 - x0;
var 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: function(src, dst, options) {
var interpolateHermite = function(x0, x1, x2, x3, t)
{
var c0 = x1;
var c1 = 0.5 * (x2 - x0);
var c2 = x0 - (2.5 * x1) + (2 * x2) - (0.5 * x3);
var 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: function(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)
var interpolateBezier = function(x0, x1, x2, x3, t) {
// x1, x2 are the knots, use x0 and x3 to calculate control points
var cp1 = x1 + (x2-x0)/4;
var cp2 = x2 - (x3-x1)/4;
var nt = 1-t;
var c0 = x1 * nt * nt * nt;
var c1 = 3 * cp1 * nt * nt * t;
var c2 = 3 * cp2 * nt * t * t;
var 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);
}
}
{
"name": "imagejs",
"version": "0.0.3",
"version": "0.0.4",
"description": "Image Processor",

@@ -5,0 +5,0 @@ "private": false,

@@ -7,3 +7,4 @@ # ImageJS

This is an early release supporting only jpeg files and only the simplest resize algorithm but there will be more to come.
This is an early release supporting only jpeg and png files and only the simplest resize algorithms
but there will be more to come.

@@ -18,17 +19,12 @@ # Installation

<li>
<a href="#image-resize">Enhanced Resize</a>
<a href="#resize">Enhanced Resize</a>
<ul>
<li>New Resize Algorithm: Bicubic Interpolation</li>
<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>
# Coming Soon
<ul>
<li>Bicubic Interpolation</li>
<li>Crop</li>
<li>Pad</li>
</ul>
# Contents

@@ -45,2 +41,6 @@

<li><a href="set-pixel">Set Pixel</a></li>
<li><a href="negative">Negative</a></li>
<li><a href="blur">Blur</a></li>
<li><a href="crop">Crop</a></li>
<li><a href="resize">Resize</a></li>
</ul>

@@ -85,2 +85,3 @@ </li>

### Set Pixel
```javascript

@@ -90,8 +91,24 @@ // Set a pixel

bitmap.setPixel(x,y, a,r,g,b);
```
### Negative
```javascript
// Create a new bitmap that is a negative of the original
var negative = bitmap.negative();
```
// Create a new bitmap resized from an original
### Blur
```javascript
// blur with simple gaussian filter
var blurred = bitmap.blur();
```
### Crop
```javascript
// create a new bitmap from a portion of another
var cropped = bitmap.crop({top: 50, left: 30, width: 100, height: 100});
```
### Resize
```javascript
// resize to 64x64 icon sized bitmap using nearest neighbor algorithm & stretch to fit

@@ -125,2 +142,3 @@ var thumbnail = bitmap.resize({

* bicubicInterpolation
* bezierInterpolation

@@ -172,1 +190,2 @@ ## Reading Images

| 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> |
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