mirror of
https://github.com/lovell/sharp.git
synced 2025-07-09 10:30:15 +02:00
Skip normalise operation for images with one colour
It didn't play nicely with premultiplication
This commit is contained in:
parent
d2a2654ace
commit
f19b6c48ca
@ -128,11 +128,6 @@ int Composite(VipsObject *context, VipsImage *srcPremultiplied, VipsImage *dstPr
|
|||||||
int Premultiply(VipsObject *context, VipsImage *image, VipsImage **out) {
|
int Premultiply(VipsObject *context, VipsImage *image, VipsImage **out) {
|
||||||
VipsImage *imagePremultiplied;
|
VipsImage *imagePremultiplied;
|
||||||
|
|
||||||
// Trivial case: Copy images without alpha channel:
|
|
||||||
if (!HasAlpha(image)) {
|
|
||||||
return vips_image_write(image, *out);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if (VIPS_MAJOR_VERSION >= 9 || (VIPS_MAJOR_VERSION >= 8 && VIPS_MINOR_VERSION >= 1))
|
#if (VIPS_MAJOR_VERSION >= 9 || (VIPS_MAJOR_VERSION >= 8 && VIPS_MINOR_VERSION >= 1))
|
||||||
|
|
||||||
if (vips_premultiply(image, &imagePremultiplied, NULL))
|
if (vips_premultiply(image, &imagePremultiplied, NULL))
|
||||||
@ -140,9 +135,6 @@ int Premultiply(VipsObject *context, VipsImage *image, VipsImage **out) {
|
|||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
if (image->Bands != 4)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
VipsImage *imageRGB;
|
VipsImage *imageRGB;
|
||||||
if (vips_extract_band(image, &imageRGB, 0, "n", NUM_COLOR_BANDS, NULL))
|
if (vips_extract_band(image, &imageRGB, 0, "n", NUM_COLOR_BANDS, NULL))
|
||||||
return -1;
|
return -1;
|
||||||
@ -181,11 +173,6 @@ int Premultiply(VipsObject *context, VipsImage *image, VipsImage **out) {
|
|||||||
int Unpremultiply(VipsObject *context, VipsImage *image, VipsImage **out) {
|
int Unpremultiply(VipsObject *context, VipsImage *image, VipsImage **out) {
|
||||||
VipsImage *imageUnpremultiplied;
|
VipsImage *imageUnpremultiplied;
|
||||||
|
|
||||||
// Trivial case: Copy images without alpha channel:
|
|
||||||
if (!HasAlpha(image)) {
|
|
||||||
return vips_image_write(image, *out);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if (VIPS_MAJOR_VERSION >= 9 || (VIPS_MAJOR_VERSION >= 8 && VIPS_MINOR_VERSION >= 1))
|
#if (VIPS_MAJOR_VERSION >= 9 || (VIPS_MAJOR_VERSION >= 8 && VIPS_MINOR_VERSION >= 1))
|
||||||
|
|
||||||
if (vips_unpremultiply(image, &imageUnpremultiplied, NULL))
|
if (vips_unpremultiply(image, &imageUnpremultiplied, NULL))
|
||||||
@ -193,9 +180,6 @@ int Unpremultiply(VipsObject *context, VipsImage *image, VipsImage **out) {
|
|||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
if (image->Bands != 4)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
VipsImage *imageRGBPremultipliedTransformed;
|
VipsImage *imageRGBPremultipliedTransformed;
|
||||||
if (vips_extract_band(image, &imageRGBPremultipliedTransformed, 0, "n", NUM_COLOR_BANDS, NULL))
|
if (vips_extract_band(image, &imageRGBPremultipliedTransformed, 0, "n", NUM_COLOR_BANDS, NULL))
|
||||||
return -1;
|
return -1;
|
||||||
@ -219,7 +203,6 @@ int Unpremultiply(VipsObject *context, VipsImage *image, VipsImage **out) {
|
|||||||
if (vips_bandjoin2(imageRGBUnpremultipliedTransformed, imageAlphaTransformed, &imageUnpremultiplied, NULL))
|
if (vips_bandjoin2(imageRGBUnpremultipliedTransformed, imageAlphaTransformed, &imageUnpremultiplied, NULL))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Return a reference to the unpremultiplied output image:
|
// Return a reference to the unpremultiplied output image:
|
||||||
|
@ -763,17 +763,10 @@ class ResizeWorker : public NanAsyncWorker {
|
|||||||
return Error();
|
return Error();
|
||||||
}
|
}
|
||||||
vips_object_local(hook, stats);
|
vips_object_local(hook, stats);
|
||||||
|
|
||||||
double min = *VIPS_MATRIX(stats, 0, 0);
|
double min = *VIPS_MATRIX(stats, 0, 0);
|
||||||
double max = *VIPS_MATRIX(stats, 1, 0);
|
double max = *VIPS_MATRIX(stats, 1, 0);
|
||||||
|
if (min != max) {
|
||||||
VipsImage *normalized;
|
|
||||||
if (min == max) {
|
|
||||||
// Range of zero: create black image
|
|
||||||
if (vips_black(&normalized, image->Xsize, image->Ysize, "bands", 1, NULL )) {
|
|
||||||
return Error();
|
|
||||||
}
|
|
||||||
vips_object_local(hook, normalized);
|
|
||||||
} else {
|
|
||||||
double f = 100.0 / (max - min);
|
double f = 100.0 / (max - min);
|
||||||
double a = -(min * f);
|
double a = -(min * f);
|
||||||
|
|
||||||
@ -788,27 +781,29 @@ class ResizeWorker : public NanAsyncWorker {
|
|||||||
return Error();
|
return Error();
|
||||||
}
|
}
|
||||||
vips_object_local(hook, normalizedLab);
|
vips_object_local(hook, normalizedLab);
|
||||||
|
|
||||||
|
VipsImage *normalized;
|
||||||
if (vips_colourspace(normalizedLab, &normalized, typeBeforeNormalize, NULL)) {
|
if (vips_colourspace(normalizedLab, &normalized, typeBeforeNormalize, NULL)) {
|
||||||
return Error();
|
return Error();
|
||||||
}
|
}
|
||||||
vips_object_local(hook, normalized);
|
vips_object_local(hook, normalized);
|
||||||
}
|
|
||||||
|
|
||||||
if (HasAlpha(image)) {
|
if (HasAlpha(image)) {
|
||||||
VipsImage *alpha;
|
VipsImage *alpha;
|
||||||
if (vips_extract_band(image, &alpha, image->Bands - 1, "n", 1, NULL)) {
|
if (vips_extract_band(image, &alpha, image->Bands - 1, "n", 1, NULL)) {
|
||||||
return Error();
|
return Error();
|
||||||
}
|
}
|
||||||
vips_object_local(hook, alpha);
|
vips_object_local(hook, alpha);
|
||||||
|
|
||||||
VipsImage *normalizedAlpha;
|
VipsImage *normalizedAlpha;
|
||||||
if (vips_bandjoin2(normalized, alpha, &normalizedAlpha, NULL)) {
|
if (vips_bandjoin2(normalized, alpha, &normalizedAlpha, NULL)) {
|
||||||
return Error();
|
return Error();
|
||||||
|
}
|
||||||
|
vips_object_local(hook, normalizedAlpha);
|
||||||
|
image = normalizedAlpha;
|
||||||
|
} else {
|
||||||
|
image = normalized;
|
||||||
}
|
}
|
||||||
vips_object_local(hook, normalizedAlpha);
|
|
||||||
image = normalizedAlpha;
|
|
||||||
} else {
|
|
||||||
image = normalized;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -98,31 +98,15 @@ describe('Normalization', function () {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns a black image for images with only one color', function (done) {
|
it('does not alter images with only one color', function (done) {
|
||||||
|
var output = fixtures.path('output.unmodified-png-with-one-color.png');
|
||||||
sharp(fixtures.inputPngWithOneColor)
|
sharp(fixtures.inputPngWithOneColor)
|
||||||
.normalize()
|
.normalize()
|
||||||
.toBuffer()
|
.toFile(output, function(err, info) {
|
||||||
.bind({})
|
if (err) done(err);
|
||||||
.then(function (imageData) {
|
fixtures.assertMaxColourDistance(output, fixtures.inputPngWithOneColor, 0);
|
||||||
this.imageData = imageData;
|
done();
|
||||||
return sharp(imageData)
|
});
|
||||||
.metadata();
|
|
||||||
})
|
|
||||||
.then(function (metadata) {
|
|
||||||
assert.strictEqual(false, metadata.hasAlpha);
|
|
||||||
assert.strictEqual(3, metadata.channels);
|
|
||||||
assert.strictEqual('srgb', metadata.space);
|
|
||||||
})
|
|
||||||
.then(function () {
|
|
||||||
return sharp(this.imageData)
|
|
||||||
.raw()
|
|
||||||
.toBuffer();
|
|
||||||
})
|
|
||||||
.then(function (rawData) {
|
|
||||||
var blackBuffer = new Buffer([0,0,0, 0,0,0, 0,0,0, 0,0,0]);
|
|
||||||
assert.strictEqual(blackBuffer.toString(), rawData.toString());
|
|
||||||
})
|
|
||||||
.finally(done);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user