diff --git a/lib/getFilterInfosAndTargetContentTypeFromQueryString.js b/lib/getFilterInfosAndTargetContentTypeFromQueryString.js index 54a4983..08020f1 100644 --- a/lib/getFilterInfosAndTargetContentTypeFromQueryString.js +++ b/lib/getFilterInfosAndTargetContentTypeFromQueryString.js @@ -182,7 +182,15 @@ module.exports = function getFilterInfosAndTargetContentTypeFromQueryString(quer currentEngineName = undefined; } - queryString.split('&').forEach(function (keyValuePair) { + var keyValuePairs = queryString.split('&'); + + if (sourceMetadata.contentType === 'image/gif' && !keyValuePairs.some(function (keyValuePair) { + return keyValuePair === 'png' || keyValuePair === 'webp' || keyValuePair === 'jpeg'; + })) { + currentEngineName = 'gm'; + } + + keyValuePairs.forEach(function (keyValuePair) { var matchKeyValuePair = keyValuePair.match(/^([^=]+)(?:=(.*))?/); if (matchKeyValuePair) { var operationName = decodeURIComponent(matchKeyValuePair[1]), diff --git a/lib/processImage.js b/lib/processImage.js index 1624f26..98b2e27 100644 --- a/lib/processImage.js +++ b/lib/processImage.js @@ -94,6 +94,10 @@ module.exports = function (options) { if (targetContentType) { res.setHeader('Content-Type', targetContentType); } + if (options.debug) { + // Only used by the test suite to assert that the right engine is used to process gifs: + res.setHeader('X-Express-Processimage', filterInfosAndTargetFormat.operationNames.join(',')); + } res.removeHeader('Content-Length'); var oldETag = res.getHeader('ETag'), newETag; diff --git a/test/processImage.js b/test/processImage.js index 64ae322..74430bf 100644 --- a/test/processImage.js +++ b/test/processImage.js @@ -417,5 +417,62 @@ describe('express-processimage', function () { errorPassedToNext: /bad extract area/ }); }); + + it('should convert an animated gif to png', function () { + return expect('GET /animated.gif?png', 'to yield response', { + body: expect.it('to have metadata satisfying', { + format: 'PNG', + size: { + width: 23, + height: 20 + } + }) + }); + }); + + it('should resize an animated gif using gm', function () { + config.debug = true; + return expect('GET /animated.gif?resize=40', 'to yield response', { + headers: { + 'X-Express-Processimage': 'gm' + }, + body: expect.it('to have metadata satisfying', { + format: 'GIF', + size: { + width: 40 + } + }) + }); + }); + + it('should resize a non-animated gif using gm', function () { + config.debug = true; + return expect('GET /bulb.gif?resize=200,200', 'to yield response', { + headers: { + 'X-Express-Processimage': 'gm' + }, + body: expect.it('to have metadata satisfying', { + format: 'GIF', + size: { + width: 200 + } + }) + }); + }); + + it('should use sharp when a gif is converted to png', function () { + config.debug = true; + return expect('GET /animated.gif?resize=40&png', 'to yield response', { + headers: { + 'X-Express-Processimage': 'sharp' + }, + body: expect.it('to have metadata satisfying', { + format: 'PNG', + size: { + width: 40 + } + }) + }); + }); }); }); diff --git a/testdata/animated.gif b/testdata/animated.gif new file mode 100644 index 0000000..0358db2 Binary files /dev/null and b/testdata/animated.gif differ diff --git a/testdata/bulb.gif b/testdata/bulb.gif new file mode 100644 index 0000000..283c23e Binary files /dev/null and b/testdata/bulb.gif differ