diff --git a/lib/tools/weightChecker/imageOptimizer.js b/lib/tools/weightChecker/imageOptimizer.js index 542ee87..a14c434 100644 --- a/lib/tools/weightChecker/imageOptimizer.js +++ b/lib/tools/weightChecker/imageOptimizer.js @@ -75,6 +75,27 @@ var ImageOptimizer = function() { return entry; }); + } else if (isSVG(entry)) { + + debug('File is an SVG'); + + // Starting softly with a lossless compression + return compressSvgLosslessly(entry.weightCheck.body) + + .then(function(newFile) { + var newFileSize = newFile.contents.length; + + debug('SVG lossless compression complete for %s', entry.url); + + if (newFileSize < fileSize) { + entry.weightCheck.lossless = entry.weightCheck.optimized = newFileSize; + entry.weightCheck.isOptimized = false; + debug('Filesize is %d bytes smaller (-%d%)', fileSize - newFileSize, Math.round((fileSize - newFileSize) * 100 / fileSize)); + } + + return entry; + }); + } else { debug('File type is not an optimizable image'); deferred.resolve(entry); @@ -157,12 +178,39 @@ var ImageOptimizer = function() { return deferred.promise; } + function isSVG(entry) { + return entry.isImage && entry.contentType === 'image/svg+xml'; + } + + function compressSvgLosslessly(imageBody) { + var deferred = Q.defer(); + var startTime = Date.now(); + + debug('Starting SVG losslessly compression'); + + new Imagemin() + .src(imageBody) + .use(Imagemin.svgo()) + .run(function (err, files) { + if (err) { + deferred.reject(err); + } else { + deferred.resolve(files[0]); + var endTime = Date.now(); + debug('compressSvgLosslessly took %d ms', endTime - startTime); + } + }); + + return deferred.promise; + } + return { //recompressIfImage: recompressIfImage, optimizeImage: optimizeImage, compressJpegLosslessly: compressJpegLosslessly, compressJpegLossly: compressJpegLossly, - compressPngLosslessly: compressPngLosslessly + compressPngLosslessly: compressPngLosslessly, + compressSvgLosslessly: compressSvgLosslessly }; }; diff --git a/test/core/imageOptimizerTest.js b/test/core/imageOptimizerTest.js index ca05d40..4a26213 100644 --- a/test/core/imageOptimizerTest.js +++ b/test/core/imageOptimizerTest.js @@ -133,11 +133,61 @@ describe('imageOptimizer', function() { }); + it('should optimize an SVG image losslessly', function(done) { + var fileContent = fs.readFileSync(path.resolve(__dirname, '../fixtures/svg-image.svg')); + var fileSize = fileContent.length; + imageOptimizer.compressSvgLosslessly(fileContent).then(function(newFile) { + var newFileSize = newFile.contents.length; + newFileSize.should.be.below(fileSize); + done(); + }).fail(function(err) { + done(err); + }); + }); + it('should optimize an SVG', function(done) { + var fileContent = fs.readFileSync(path.resolve(__dirname, '../fixtures/svg-image.svg')); + var fileSize = fileContent.length; + var entry = { + method: 'GET', + url: 'http://localhost:8388/an-image.svg', + requestHeaders: { + 'User-Agent': 'something', + Referer: 'http://www.google.fr/', + Accept: '*/*', + 'Accept-Encoding': 'gzip, deflate' + }, + status: 200, + isImage: true, + type: 'image', + contentType: 'image/svg+xml', + contentLength: 999, + weightCheck: { + body: fileContent, + totalWeight: fileSize + 200, + headersSize: 200, + bodySize: fileSize, + isCompressed: false, + uncompressedSize: fileSize + } + }; + imageOptimizer.optimizeImage(entry) + + .then(function(newEntry) { + newEntry.weightCheck.should.have.a.property('isOptimized').that.equals(false); + newEntry.weightCheck.should.have.a.property('lossless').that.is.below(fileSize); + + done(); + }) + + .fail(function(err) { + done(err); + }); + }); it('shouldn\'t fail optimizing a corrupted jpeg', function(done) { diff --git a/test/fixtures/svg-image.svg b/test/fixtures/svg-image.svg new file mode 100644 index 0000000..701b2a7 --- /dev/null +++ b/test/fixtures/svg-image.svg @@ -0,0 +1,999 @@ + + + + + Tiger - coloured + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + Tiger - coloured + 2015-05-31 + + + Frank Tremmel + + + + + tiger + animal + cat + Tiger + Tier + Katze + line art + outline + + + coloured line art tiger + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +