mirror of
https://github.com/danbulant/pngjs
synced 2026-07-09 13:10:46 +00:00
Better scanline filter selection
This commit is contained in:
parent
207c02d323
commit
eedc329b9a
5 changed files with 29 additions and 23 deletions
28
README.md
28
README.md
|
|
@ -15,10 +15,8 @@ var fs = require('fs'),
|
||||||
PNG = require('pngjs').PNG;
|
PNG = require('pngjs').PNG;
|
||||||
|
|
||||||
var png = new PNG({
|
var png = new PNG({
|
||||||
filterType: 4
|
filterType: 4
|
||||||
}),
|
});
|
||||||
src = fs.createReadStream(process.argv[2]),
|
|
||||||
dst = fs.createWriteStream(process.argv[3]);
|
|
||||||
|
|
||||||
png.on('parsed', function() {
|
png.on('parsed', function() {
|
||||||
|
|
||||||
|
|
@ -36,21 +34,27 @@ png.on('parsed', function() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
png.pipe(fs.createWriteStream('out.png'));
|
||||||
|
|
||||||
png.pack();
|
png.pack();
|
||||||
});
|
});
|
||||||
|
|
||||||
src.pipe(png).pipe(dst);
|
fs.createReadStream('in.png').pipe(png);
|
||||||
```
|
```
|
||||||
For more examples see `examples` folder.
|
For more examples see `examples` folder.
|
||||||
|
|
||||||
Documentation
|
Documentation
|
||||||
================
|
================
|
||||||
|
|
||||||
Currently only true color mode with 8-bit color depth (per color) with alpha
|
As input any color type is accepted (grayscale, rgb, palette, grayscale with alpha, rgb with alpha) but 8 bit per sample (channel) is the only supported bit depth. Interlaced mode is not supported.
|
||||||
is supported. PNG cannot parse and create images with palette of colors.
|
|
||||||
Interlaced mode is not supported either.
|
|
||||||
|
|
||||||
## PNG
|
Supported ancillary chunks
|
||||||
|
------------------
|
||||||
|
- `gAMA` - gamma,
|
||||||
|
- `tRNS` - transparency (but only for paletted image)
|
||||||
|
|
||||||
|
|
||||||
|
## Class: PNG
|
||||||
`PNG` is readable and writeable `Stream`.
|
`PNG` is readable and writeable `Stream`.
|
||||||
|
|
||||||
### Options
|
### Options
|
||||||
|
|
@ -80,9 +84,15 @@ two arguments `(err, data)`.
|
||||||
### Property: data
|
### Property: data
|
||||||
Buffer of image pixel data. Every pixel consists 4 bytes: R, G, B, A (opacity).
|
Buffer of image pixel data. Every pixel consists 4 bytes: R, G, B, A (opacity).
|
||||||
|
|
||||||
|
### Property: gamma
|
||||||
|
|
||||||
Changelog
|
Changelog
|
||||||
============
|
============
|
||||||
|
|
||||||
|
### 0.2.0-alpha - 21 Aug 2012
|
||||||
|
- Input added palette, grayscale, no alpha support
|
||||||
|
- Better scanline filter selection
|
||||||
|
|
||||||
### 0.1.0-alpha - 19 Aug 2012
|
### 0.1.0-alpha - 19 Aug 2012
|
||||||
- First version
|
- First version
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,8 +22,7 @@ fs.readdir(__dirname + '/img/', function(err, files) {
|
||||||
|
|
||||||
for (var i = 0; i < 3; i++) {
|
for (var i = 0; i < 3; i++) {
|
||||||
var sample = this.data[idx + i] / 255;
|
var sample = this.data[idx + i] / 255;
|
||||||
sample = Math.pow(sample, 1 / this.gamma);
|
sample = Math.pow(sample, 1 / 2.2 / this.gamma);
|
||||||
sample = Math.pow(sample, 1 / 2.2);
|
|
||||||
this.data[idx + i] = Math.round(sample * 255);
|
this.data[idx + i] = Math.round(sample * 255);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,13 +17,10 @@ png.on('parsed', function() {
|
||||||
for (var x = 0; x < png.width; x++) {
|
for (var x = 0; x < png.width; x++) {
|
||||||
var idx = (png.width * y + x) << 2;
|
var idx = (png.width * y + x) << 2;
|
||||||
|
|
||||||
// invert color
|
if (Math.abs(png.data[idx] - png.data[idx+1]) <= 1
|
||||||
png.data[idx] = 255 - png.data[idx];
|
&& Math.abs(png.data[idx+1] - png.data[idx+2]) <= 1)
|
||||||
png.data[idx+1] = 255 - png.data[idx+1];
|
png.data[idx] = png.data[idx+1] = png.data[idx+2];
|
||||||
png.data[idx+2] = 255 - png.data[idx+2];
|
|
||||||
|
|
||||||
// and reduce opacity
|
|
||||||
png.data[idx+3] = png.data[idx+3] >> 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -200,7 +200,7 @@ Filter.prototype._filterNone = function(pxData, y, width, height, rawData) {
|
||||||
|
|
||||||
if (!rawData) {
|
if (!rawData) {
|
||||||
for (var x = 0; x < pxRowLength; x++)
|
for (var x = 0; x < pxRowLength; x++)
|
||||||
sum += pxData[y * pxRowLength + x];
|
sum += Math.abs(pxData[y * pxRowLength + x]);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
rawData[y * rawRowLength] = 0;
|
rawData[y * rawRowLength] = 0;
|
||||||
|
|
@ -224,7 +224,7 @@ Filter.prototype._filterSub = function(pxData, y, width, height, rawData) {
|
||||||
var left = x >= 4 ? pxData[y * pxRowLength + x - 4] : 0,
|
var left = x >= 4 ? pxData[y * pxRowLength + x - 4] : 0,
|
||||||
val = pxData[y * pxRowLength + x] - left;
|
val = pxData[y * pxRowLength + x] - left;
|
||||||
|
|
||||||
if (!rawData) sum += val;
|
if (!rawData) sum += Math.abs(val);
|
||||||
else rawData[y * rawRowLength + 1 + x] = val;
|
else rawData[y * rawRowLength + 1 + x] = val;
|
||||||
}
|
}
|
||||||
return sum;
|
return sum;
|
||||||
|
|
@ -244,7 +244,7 @@ Filter.prototype._filterUp = function(pxData, y, width, height, rawData) {
|
||||||
var up = y > 0 ? pxData[(y - 1) * pxRowLength + x] : 0,
|
var up = y > 0 ? pxData[(y - 1) * pxRowLength + x] : 0,
|
||||||
val = pxData[y * pxRowLength + x] - up;
|
val = pxData[y * pxRowLength + x] - up;
|
||||||
|
|
||||||
if (!rawData) sum += val;
|
if (!rawData) sum += Math.abs(val);
|
||||||
else rawData[y * rawRowLength + 1 + x] = val;
|
else rawData[y * rawRowLength + 1 + x] = val;
|
||||||
}
|
}
|
||||||
return sum;
|
return sum;
|
||||||
|
|
@ -265,7 +265,7 @@ Filter.prototype._filterAvg = function(pxData, y, width, height, rawData) {
|
||||||
up = y > 0 ? pxData[(y - 1) * pxRowLength + x] : 0,
|
up = y > 0 ? pxData[(y - 1) * pxRowLength + x] : 0,
|
||||||
val = pxData[y * pxRowLength + x] - ((left + up) >> 1);
|
val = pxData[y * pxRowLength + x] - ((left + up) >> 1);
|
||||||
|
|
||||||
if (!rawData) sum += val;
|
if (!rawData) sum += Math.abs(val);
|
||||||
else rawData[y * rawRowLength + 1 + x] = val;
|
else rawData[y * rawRowLength + 1 + x] = val;
|
||||||
}
|
}
|
||||||
return sum;
|
return sum;
|
||||||
|
|
@ -287,7 +287,7 @@ Filter.prototype._filterPaeth = function(pxData, y, width, height, rawData) {
|
||||||
upLeft = x >= 4 && y > 0 ? pxData[(y - 1) * pxRowLength + x - 4] : 0,
|
upLeft = x >= 4 && y > 0 ? pxData[(y - 1) * pxRowLength + x - 4] : 0,
|
||||||
val = pxData[y * pxRowLength + x] - PaethPredictor(left, up, upLeft);
|
val = pxData[y * pxRowLength + x] - PaethPredictor(left, up, upLeft);
|
||||||
|
|
||||||
if (!rawData) sum += val;
|
if (!rawData) sum += Math.abs(val);
|
||||||
else rawData[y * rawRowLength + 1 + x] = val;
|
else rawData[y * rawRowLength + 1 + x] = val;
|
||||||
}
|
}
|
||||||
return sum;
|
return sum;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "pngjs",
|
"name": "pngjs",
|
||||||
"version": "0.1.0-alpha",
|
"version": "0.2.0-alpha",
|
||||||
"description": "Simple PNG encoder/decoder",
|
"description": "Simple PNG encoder/decoder",
|
||||||
"author": "Kuba Niegowski",
|
"author": "Kuba Niegowski",
|
||||||
"contributors": [],
|
"contributors": [],
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue