mirror of
https://github.com/lovell/sharp.git
synced 2025-07-09 10:30:15 +02:00
Add raw, uncompressed image data output #136
This commit is contained in:
parent
464fb1726d
commit
a190ae6b08
12
README.md
12
README.md
@ -392,6 +392,18 @@ Use PNG format for the output image.
|
||||
|
||||
Use WebP format for the output image.
|
||||
|
||||
#### raw()
|
||||
|
||||
_Requires libvips 7.42.0+_
|
||||
|
||||
Provide raw, uncompressed uint8 (unsigned char) image data for Buffer and Stream based output.
|
||||
|
||||
The number of channels depends on the input image and selected options.
|
||||
|
||||
* 1 channel for images converted to `greyscale()`, with each byte representing one pixel.
|
||||
* 3 channels for colour images without alpha transparency, with bytes ordered \[red, green, blue, red, green, blue, etc.\]).
|
||||
* 4 channels for colour images with alpha transparency, with bytes ordered \[red, green, blue, alpha, red, green, blue, alpha, etc.\].
|
||||
|
||||
#### quality(quality)
|
||||
|
||||
The output quality to use for lossy JPEG, WebP and TIFF output formats. The default quality is `80`.
|
||||
|
13
index.js
13
index.js
@ -341,10 +341,10 @@ Sharp.prototype.compressionLevel = function(compressionLevel) {
|
||||
};
|
||||
|
||||
/*
|
||||
Disable the use of adaptive row filtering for PNG output - requires libvips 7.41.0+
|
||||
Disable the use of adaptive row filtering for PNG output - requires libvips 7.42.0+
|
||||
*/
|
||||
Sharp.prototype.withoutAdaptiveFiltering = function(withoutAdaptiveFiltering) {
|
||||
if (semver.gte(libvipsVersion, '7.41.0')) {
|
||||
if (semver.gte(libvipsVersion, '7.42.0')) {
|
||||
this.options.withoutAdaptiveFiltering = (typeof withoutAdaptiveFiltering === 'boolean') ? withoutAdaptiveFiltering : true;
|
||||
} else {
|
||||
console.error('withoutAdaptiveFiltering requires libvips 7.41.0+');
|
||||
@ -425,6 +425,15 @@ Sharp.prototype.webp = function() {
|
||||
return this;
|
||||
};
|
||||
|
||||
Sharp.prototype.raw = function() {
|
||||
if (semver.gte(libvipsVersion, '7.42.0')) {
|
||||
this.options.output = '__raw';
|
||||
} else {
|
||||
console.error('Raw output requires libvips 7.42.0+');
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
/*
|
||||
Used by a Writable Stream to notify that it is ready for data
|
||||
*/
|
||||
|
@ -635,6 +635,35 @@ class ResizeWorker : public NanAsyncWorker {
|
||||
return Error(baton, hook);
|
||||
}
|
||||
baton->outputFormat = "webp";
|
||||
#if (VIPS_MAJOR_VERSION >= 7 && VIPS_MINOR_VERSION >= 42)
|
||||
} else if (baton->output == "__raw") {
|
||||
// Write raw, uncompressed image data to buffer
|
||||
if (baton->greyscale) {
|
||||
// Extract first band for greyscale image
|
||||
VipsImage *grey;
|
||||
if (vips_extract_band(image, &grey, 1, NULL)) {
|
||||
return Error(baton, hook);
|
||||
}
|
||||
vips_object_local(hook, grey);
|
||||
image = grey;
|
||||
}
|
||||
if (image->BandFmt != VIPS_FORMAT_UCHAR) {
|
||||
// Cast pixels to uint8 (unsigned char)
|
||||
VipsImage *uchar;
|
||||
if (vips_cast(image, &uchar, VIPS_FORMAT_UCHAR, NULL)) {
|
||||
return Error(baton, hook);
|
||||
}
|
||||
vips_object_local(hook, uchar);
|
||||
image = uchar;
|
||||
}
|
||||
// Get raw image data
|
||||
baton->bufferOut = vips_image_write_to_memory(image, &baton->bufferOutLength);
|
||||
if (baton->bufferOut == NULL) {
|
||||
(baton->err).append("Could not allocate enough memory for raw output");
|
||||
return Error(baton, hook);
|
||||
}
|
||||
baton->outputFormat = "raw";
|
||||
#endif
|
||||
} else {
|
||||
bool outputJpeg = IsJpeg(baton->output);
|
||||
bool outputPng = IsPng(baton->output);
|
||||
@ -649,7 +678,7 @@ class ResizeWorker : public NanAsyncWorker {
|
||||
}
|
||||
baton->outputFormat = "jpeg";
|
||||
} else if (outputPng || (matchInput && inputImageType == ImageType::PNG)) {
|
||||
#if (VIPS_MAJOR_VERSION >= 7 && VIPS_MINOR_VERSION >= 41)
|
||||
#if (VIPS_MAJOR_VERSION >= 7 && VIPS_MINOR_VERSION >= 42)
|
||||
// Select PNG row filter
|
||||
int filter = baton->withoutAdaptiveFiltering ? VIPS_FOREIGN_PNG_FILTER_NONE : VIPS_FOREIGN_PNG_FILTER_ALL;
|
||||
// Write PNG to file
|
||||
|
@ -384,8 +384,8 @@ describe('Input/output', function() {
|
||||
done();
|
||||
});
|
||||
|
||||
if (semver.gte(sharp.libvipsVersion(), '7.41.0')) {
|
||||
it('withoutAdaptiveFiltering generates smaller file [libvips ' + sharp.libvipsVersion() + '>=7.41.0]', function(done) {
|
||||
if (semver.gte(sharp.libvipsVersion(), '7.42.0')) {
|
||||
it('withoutAdaptiveFiltering generates smaller file [libvips ' + sharp.libvipsVersion() + '>=7.42.0]', function(done) {
|
||||
// First generate with adaptive filtering
|
||||
sharp(fixtures.inputPng)
|
||||
.resize(320, 240)
|
||||
@ -463,4 +463,49 @@ describe('Input/output', function() {
|
||||
});
|
||||
}
|
||||
|
||||
if (semver.gte(sharp.libvipsVersion(), '7.42.0')) {
|
||||
describe('Ouput raw, uncompressed image data [libvips ' + sharp.libvipsVersion() + '>=7.42.0]', function() {
|
||||
it('1 channel greyscale image', function(done) {
|
||||
sharp(fixtures.inputJpg)
|
||||
.greyscale()
|
||||
.resize(32, 24)
|
||||
.raw()
|
||||
.toBuffer(function(err, data, info) {
|
||||
assert.strictEqual(32 * 24 * 1, info.size);
|
||||
assert.strictEqual(data.length, info.size);
|
||||
assert.strictEqual('raw', info.format);
|
||||
assert.strictEqual(32, info.width);
|
||||
assert.strictEqual(24, info.height);
|
||||
done();
|
||||
});
|
||||
});
|
||||
it('3 channel colour image without transparency', function(done) {
|
||||
sharp(fixtures.inputJpg)
|
||||
.resize(32, 24)
|
||||
.raw()
|
||||
.toBuffer(function(err, data, info) {
|
||||
assert.strictEqual(32 * 24 * 3, info.size);
|
||||
assert.strictEqual(data.length, info.size);
|
||||
assert.strictEqual('raw', info.format);
|
||||
assert.strictEqual(32, info.width);
|
||||
assert.strictEqual(24, info.height);
|
||||
done();
|
||||
});
|
||||
});
|
||||
it('4 channel colour image with transparency', function(done) {
|
||||
sharp(fixtures.inputPngWithTransparency)
|
||||
.resize(32, 24)
|
||||
.raw()
|
||||
.toBuffer(function(err, data, info) {
|
||||
assert.strictEqual(32 * 24 * 4, info.size);
|
||||
assert.strictEqual(data.length, info.size);
|
||||
assert.strictEqual('raw', info.format);
|
||||
assert.strictEqual(32, info.width);
|
||||
assert.strictEqual(24, info.height);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user