Comparing version 0.0.2 to 0.0.3
@@ -84,2 +84,5 @@ /** | ||
_deduceFileType: function(filename) { | ||
if (!filename) { | ||
throw new Error("Can't determine image type"); | ||
} | ||
switch (filename.substr(-4).toLowerCase()) { | ||
@@ -129,6 +132,15 @@ case ".jpg": | ||
}, | ||
read: function(stream, type) { | ||
_parseOptions: function(options, filename) { | ||
options = options || {}; | ||
if (typeof options === "number") { | ||
options = { type: options }; | ||
} | ||
options.type = options.type || this._deduceFileType(filename); | ||
return options; | ||
}, | ||
read: function(stream, options) { | ||
var self = this; | ||
options = this._parseOptions(options); | ||
switch(type) { | ||
switch(options.type) { | ||
case Enums.ImageType.JPG: | ||
@@ -149,12 +161,13 @@ return this._readStream(stream) | ||
default: | ||
return Promise.reject(new Error("Not supported: ImageType " + type)); | ||
return Promise.reject(new Error("Not supported: ImageType " + options.type)); | ||
} | ||
}, | ||
readFile: function(filename, type) { | ||
type = type || this._deduceFileType(filename); | ||
readFile: function(filename, options) { | ||
options = this._parseOptions(options, filename); | ||
var stream = fs.createReadStream(filename); | ||
return this.read(stream, type); | ||
return this.read(stream, options); | ||
}, | ||
write: function(stream, type) { | ||
write: function(stream, options) { | ||
options = this._parseOptions(options); | ||
var deferred = Promise.defer(); | ||
@@ -169,5 +182,5 @@ try { | ||
switch(type) { | ||
switch(options.type) { | ||
case Enums.ImageType.JPG: | ||
var buffer = jpeg.encode(this._data, 50).data; | ||
var buffer = jpeg.encode(this._data, options.quality || 90).data; | ||
stream.write(buffer); | ||
@@ -190,3 +203,3 @@ stream.end(); | ||
default: | ||
throw new Error("Not supported: ImageType " + type); | ||
throw new Error("Not supported: ImageType " + options.type); | ||
} | ||
@@ -199,6 +212,6 @@ } | ||
}, | ||
writeFile: function(filename, type) { | ||
type = type || this._deduceFileType(filename); | ||
writeFile: function(filename, options) { | ||
options = this._parseOptions(options, filename); | ||
var stream = fs.createWriteStream(filename); | ||
return this.write(stream, type); | ||
return this.write(stream, options); | ||
}, | ||
@@ -205,0 +218,0 @@ |
@@ -206,3 +206,97 @@ /** | ||
} | ||
}, | ||
bicubicInterpolation: 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 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 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; | ||
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); | ||
for (var i = 0; i < hSrc; i++) { | ||
for (var j = 0; j < wDst; j++) { | ||
// i in src coords, j in dst coords | ||
// calculate x in src crop coords | ||
var x = j * wSrc / wDst; | ||
var xPos = Math.floor(x); | ||
var t = x - xPos; | ||
var srcPos = ((i + tSrc) * srcWidth + xPos + lSrc) * 4; | ||
var buf1Pos = (i * wDst + j) * 4; | ||
for (var k = 0; k < 4; k++) { | ||
var kPos = srcPos + k; | ||
var x0 = (xPos + lSrc > 0) ? bufSrc[kPos - 4] : bufSrc[kPos]; | ||
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 Bitmap = require("./bitmap"); | ||
//var tmp = new Bitmap({ | ||
// width: wDst, height: hSrc, | ||
// data: buf1 | ||
//}); | ||
//tmp.writeFile("out/tmp.jpg"); | ||
// =========================================================== | ||
// Pass 2 - interpolate columns | ||
for (var i = 0; i < hDst; i++) { | ||
for (var j = 0; j < wDst; j++) { | ||
// i&j in dst coords | ||
// calculate y in buf1 coords | ||
var y = i * hSrc / hDst; | ||
var yPos = Math.floor(y); | ||
var t = y - yPos; | ||
var buf1Pos = (yPos * wDst + j) * 4; | ||
var dstPos = ((i+tDst) * dstWidth + j + lDst) * 4; | ||
for (var k = 0; k < 4; k++) { | ||
var kPos = buf1Pos + k; | ||
var y0 = (yPos > 0) ? buf1[kPos - wDst*4] : buf1[kPos]; | ||
var y1 = buf1[kPos]; | ||
var y2 = buf1[kPos + wDst*4]; | ||
var y3 = (yPos < hSrc) ? buf1[kPos + wDst*8] : buf1[kPos + wDst*4]; | ||
bufDst[dstPos + k] = interpolateCubic(y0,y1,y2,y3,t); | ||
} | ||
} | ||
} | ||
} | ||
} |
{ | ||
"name": "imagejs", | ||
"version": "0.0.2", | ||
"version": "0.0.3", | ||
"description": "Image Processor", | ||
@@ -5,0 +5,0 @@ "private": false, |
@@ -19,7 +19,5 @@ # ImageJS | ||
<ul> | ||
<li>New Resize Algorithm: Bilinear Interpolation</li> | ||
<li>Stretch, Crop or Pad to Fit</li> | ||
<li>New Resize Algorithm: Bicubic Interpolation</li> | ||
</ul> | ||
</li> | ||
<li><a href="#reading-images">PNG Image files supported</a></li> | ||
</ul> | ||
@@ -109,6 +107,6 @@ | ||
// resize to 300x200 bitmap using bilinear interpolation and padding to fit, pad color solid red | ||
// resize to 300x200 bitmap using bicubic interpolation and padding to fit, pad color solid red | ||
var thumbnail = bitmap.resize({ | ||
width: 100, height: 150, | ||
algorithm: "bilinearInterpolation", | ||
width: 300, height: 200, | ||
algorithm: "bicubicInterpolation", | ||
fit: "pad", | ||
@@ -123,2 +121,3 @@ padColor: {r:255, g:0, b:0, a:255} | ||
* bilinearInterpolation | ||
* bicubicInterpolation | ||
@@ -138,3 +137,3 @@ ## Reading Images | ||
var bitmap = new Bitmap(); | ||
bitmap.read(stream, ImageJS.ImageType.JPG) | ||
bitmap.read(stream, { type: ImageJS.ImageType.JPG }) | ||
.then(function() { | ||
@@ -149,4 +148,4 @@ // bitmap is ready | ||
```javascript | ||
// write to a file | ||
return bitmap.writeFile(filename) | ||
// write to a jpg file, quality 75 (default is 90) | ||
return bitmap.writeFile("image.jpg", { quality:75 }) | ||
.then(function() { | ||
@@ -158,3 +157,3 @@ // bitmap has been saved | ||
var stream = createWriteStream(); | ||
return bitmap.write(stream, ImageJS.ImageType.PNG) | ||
return bitmap.write(stream, {type: ImageJS.ImageType.PNG}) | ||
.then(function() { | ||
@@ -164,3 +163,2 @@ // bitmap has been written and stream ended | ||
``` | ||
@@ -174,2 +172,2 @@ | ||
| 0.0.2 | <ul><li><a href="#image-resize">Enhanced Resize</a><ul><li>New Resize Algorithm: Bilinear Interpolation</li><li>Stretch, Crop or Pad to Fit</li></ul></li><li><a href="#reading-images">PNG Image files supported</a></li></ul> | | ||
| 0.0.3 | <ul><li><a href="#image-resize">Enhanced Resize</a><ul><li>New Resize Algorithm: Bicubic Interpolation</li></ul></li></ul> | |
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
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
30986
587
166