├── .gitignore ├── .jscsrc ├── .jshintrc ├── .travis.yml ├── CHANGELOG.md ├── README.md ├── UNLICENSE ├── lib ├── canvas.js └── engine.js ├── package.json └── test ├── expected-files ├── background.jpeg ├── multiple.gif ├── multiple.jpg └── single.gif ├── pixelsmith-test.js └── test-files ├── jpeg-wrong-extension.png └── sprite3.gif /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | -------------------------------------------------------------------------------- /.jscsrc: -------------------------------------------------------------------------------- 1 | { 2 | "requireCurlyBraces": [ 3 | "if", 4 | "else", 5 | "for", 6 | "while", 7 | "do", 8 | "try", 9 | "catch", 10 | "finally", 11 | "with" 12 | ], 13 | "requireSpaceAfterKeywords": true, 14 | "requireSpaceBeforeBlockStatements": true, 15 | "requireSpacesInConditionalExpression": true, 16 | "requireSpacesInFunctionExpression": { 17 | "beforeOpeningRoundBrace": true, 18 | "beforeOpeningCurlyBrace": true 19 | }, 20 | "requireSpacesInFunctionDeclaration": { 21 | "beforeOpeningCurlyBrace": true 22 | }, 23 | "disallowSpacesInFunctionDeclaration": { 24 | "beforeOpeningRoundBrace": true 25 | }, 26 | "disallowSpacesInCallExpression": true, 27 | "disallowMultipleVarDecl": true, 28 | "requireBlocksOnNewline": 1, 29 | "disallowPaddingNewlinesInBlocks": true, 30 | "disallowSpacesInsideObjectBrackets": "all", 31 | "disallowSpacesInsideArrayBrackets": "all", 32 | "disallowSpacesInsideParentheses": true, 33 | "disallowQuotedKeysInObjects": "allButReserved", 34 | "disallowSpaceAfterObjectKeys": true, 35 | "requireSpaceBeforeObjectValues": true, 36 | "requireCommaBeforeLineBreak": true, 37 | "requireOperatorBeforeLineBreak": true, 38 | "disallowSpaceAfterPrefixUnaryOperators": true, 39 | "disallowSpaceBeforePostfixUnaryOperators": true, 40 | "requireSpaceBeforeBinaryOperators": true, 41 | "requireSpaceAfterBinaryOperators": true, 42 | "requireCamelCaseOrUpperCaseIdentifiers": "ignoreProperties", 43 | "disallowKeywords": [ 44 | "with" 45 | ], 46 | "disallowMultipleLineStrings": true, 47 | "disallowMultipleLineBreaks": true, 48 | "disallowMixedSpacesAndTabs": true, 49 | "disallowTrailingWhitespace": true, 50 | "disallowTrailingComma": true, 51 | "disallowKeywordsOnNewLine": [ 52 | "else", 53 | "catch", 54 | "finally" 55 | ], 56 | "requireLineFeedAtFileEnd": true, 57 | "maximumLineLength": { 58 | "value": 120, 59 | "allowUrlComments": true 60 | }, 61 | "requireDotNotation": true, 62 | "disallowYodaConditions": true, 63 | "requireSpaceAfterLineComment": true, 64 | "disallowNewlineBeforeBlockStatements": true, 65 | "validateLineBreaks": "LF", 66 | "validateQuoteMarks": { 67 | "mark": "'", 68 | "escape": true 69 | }, 70 | "validateIndentation": 2, 71 | "validateParameterSeparator": ", ", 72 | "safeContextKeyword": [ 73 | "that" 74 | ] 75 | } 76 | -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "eqeqeq": true, 3 | "freeze": true, 4 | "immed": true, 5 | "latedef": true, 6 | "nonbsp": true, 7 | "undef": true, 8 | "strict": false, 9 | "node": true, 10 | "sub": false, 11 | "globals": { 12 | "exports": true, 13 | "describe": true, 14 | "before": true, 15 | "beforeEach": true, 16 | "after": true, 17 | "afterEach": true, 18 | "it": true 19 | }, 20 | "curly": true, 21 | "indent": 2, 22 | "newcap": true, 23 | "noarg": true, 24 | "quotmark": "single", 25 | "unused": "vars", 26 | "maxparams": 4, 27 | "maxdepth": 5 28 | } 29 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "16" 4 | - "14" 5 | - "12" 6 | 7 | notifications: 8 | email: 9 | recipients: 10 | - todd@twolfson.com 11 | on_success: change 12 | on_failure: change 13 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # pixelsmith changelog 2 | 2.6.0 - Upgraded `async` via @xfix in #21 and moved to Node.js>=12 to fix Travis CI 3 | 4 | 2.5.0 - Added support for `options.concurrentFileLimit`. Fixes #20 5 | 6 | 2.4.1 - Removed accidental double callback from `getPixels` 7 | 8 | 2.4.0 - Added filepath info to when invalid file extension loaded. Fixes #16 9 | 10 | 2.3.0 - Removed `ndarray-fill` to fix `npm audit` vulnerability via @dawidgarus in #17 11 | 12 | 2.2.2 - Moved to Node.js>=8 to fix Travis CI 13 | 14 | 2.2.1 - Moved to Node.js>=4 to fix Travis CI 15 | 16 | 2.2.0 - Added support for Vinyl@2 17 | 18 | 2.1.3 - Replaced Gratipay with support me page 19 | 20 | 2.1.2 - Added file size check. Fixes gulp.spritesmith#131 21 | 22 | 2.1.1 - Upgraded to `get-pixels@3.3.0` via @BS-Harou in #9 23 | 24 | 2.1.0 - Added `quality` support for JPEGs 25 | 26 | 2.0.1 - Upgraded to `save-pixels@2.3.0` to resolve `pngjs2` deprecation warning. Fixes #6 27 | 28 | 2.0.0 - Upgraded to `spritesmith-engine-spec@2.0.0` 29 | 30 | 1.3.4 - Added `specVersion` support and `spritesmith-engine` keyword 31 | 32 | 1.3.3 - Updated documentation to be a little cleaner and link to `spritesmith-engine-spec` 33 | 34 | 1.3.2 - Upgraded to `spritesmith-engine-test@3.0.0` to clean up technical debt 35 | 36 | 1.3.1 - Removed bad require 37 | 38 | 1.3.0 - Cleaned up technical debt (e.g. YAGNI on `exporters`) 39 | 40 | 1.2.2 - Updated supported node versions to `>= 0.10.0` 41 | 42 | 1.2.1 - Added `foundry` for release 43 | 44 | 1.2.0 - Upgraded to get-pixels@3.2.3 to add better PNG support 45 | 46 | 1.1.2 - Moved from deprecated `licenses` key to `license` in `package.json` 47 | 48 | 1.1.1 - Fixed example in README via @tmcw in #3 49 | 50 | 1.1.0 - Added support for custom background. Fixes twolfson/gulp.spritesmith#33 51 | 52 | 1.0.0 - Initial fork from `pngsmith@0.1.3` 53 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # pixelsmith [![Build Status](https://app.travis-ci.com/twolfson/pixelsmith.svg?branch=master)](https://app.travis-ci.com/twolfson/pixelsmith) 2 | 3 | Node based engine for [spritesmith][] built of top of [get-pixels][] and [save-pixels][]. 4 | 5 | [spritesmith]: https://github.com/Ensighten/spritesmith 6 | [get-pixels]: https://github.com/mikolalysenko/get-pixels 7 | [save-pixels]: https://github.com/mikolalysenko/save-pixels 8 | 9 | This can be used for constructing a canvas, placing images on it, and extracting the result image. 10 | 11 | ## Getting Started 12 | Install the module with: `npm install pixelsmith` 13 | 14 | ```js 15 | // Load in our dependencies 16 | var Pixelsmith = require('pixelsmith'); 17 | 18 | // Create a new engine 19 | var pixelsmith = new Pixelsmith(); 20 | 21 | // Interpret some images from disk 22 | pixelsmith.createImages(['img1.jpg', 'img2.png'], function handleImages (err, imgs) { 23 | // If there was an error, throw it 24 | if (err) { 25 | throw err; 26 | } 27 | 28 | // We recieve images in the same order they were given 29 | imgs[0].width; // 50 (pixels) 30 | imgs[0].height; // 100 (pixels) 31 | 32 | // Create a canvas that fits our images (200px wide, 300px tall) 33 | var canvas = pixelsmith.createCanvas(200, 300); 34 | 35 | // Add the images to our canvas (at x=0, y=0 and x=50, y=100 respectively) 36 | canvas.addImage(imgs[0], 0, 0); 37 | canvas.addImage(imgs[1], 50, 100); 38 | 39 | // Export canvas to image 40 | var resultStream = canvas['export']({format: 'png'}); 41 | resultStream; // Readable stream outputting PNG image of the canvas 42 | }); 43 | ``` 44 | 45 | ## Documentation 46 | This module was built to the specification for spritesmith engines. 47 | 48 | **Specification version:** 2.0.0 49 | 50 | https://github.com/twolfson/spritesmith-engine-spec/tree/2.0.0 51 | 52 | ### `Engine(options)` 53 | Our `engine` constructor supports the following options: 54 | 55 | - options `Object` - Optional container for various settings 56 | - concurrentFileLimit `Number` - Amount of files to load concurrently via `createImages` 57 | - May be useful if bumping into `EMFILE` (file descriptor limit) 58 | 59 | ### `engine.createImages(images, cb)` 60 | Our `createImages` methods supports the following types of images: 61 | 62 | - image `String` - Filepath to image 63 | - image `Object` - Vinyl object with buffer for image (uses buffer) 64 | - image `Object` - Vinyl object with stream for image (uses stream) 65 | - image `Object` - Vinyl object with `null` for image (reads buffer from provided filepath) 66 | 67 | ### `canvas.export(options)` 68 | Our `export` method provides support for the following options: 69 | 70 | - options `Object` 71 | - background `Number[]` - `rgba` array of value for background 72 | - By default, the background is `[0, 0, 0, 0]` (transparent black) 73 | - `[0]` - Red value for background 74 | - Can range from 0 to 255 75 | - `[1]` - Green value for background 76 | - Can range from 0 to 255 77 | - `[2]` - Blue value for background 78 | - Can range from 0 to 255 79 | - `[3]` - Alpha/transparency value for background 80 | - Can range from 0 to 255 81 | - quality `Number` - Optional quality percentage for JPEG images 82 | - This value can range from 0 to 100 83 | 84 | ## Contributing 85 | In lieu of a formal styleguide, take care to maintain the existing coding style. Add unit tests for any new or changed functionality. Lint via `npm run lint` and test via `npm test`. 86 | 87 | ## Donating 88 | Support this project and [others by twolfson][twolfson-projects] via [donations][twolfson-support-me]. 89 | 90 | 91 | 92 | [twolfson-projects]: http://twolfson.com/projects 93 | [twolfson-support-me]: http://twolfson.com/support-me 94 | 95 | ## Unlicense 96 | As of Nov 24 2014, Todd Wolfson has released this repository and its contents to the public domain. 97 | 98 | It has been released under the [UNLICENSE][]. 99 | 100 | [UNLICENSE]: UNLICENSE 101 | -------------------------------------------------------------------------------- /UNLICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | -------------------------------------------------------------------------------- /lib/canvas.js: -------------------------------------------------------------------------------- 1 | // Load in dependencies 2 | var assert = require('assert'); 3 | var ndarray = require('ndarray'); 4 | var savePixels = require('save-pixels'); 5 | 6 | // Define our canvas constructor 7 | function Canvas(width, height) { 8 | // Calculate and save dimensions/data for later 9 | var len = width * height * 4; 10 | this.width = width; 11 | this.height = height; 12 | this.data = new global.Uint8ClampedArray(len); 13 | this.ndarray = new ndarray(this.data, [width, height, 4]); 14 | 15 | // Create a store for images 16 | this.images = []; 17 | } 18 | Canvas.defaultFormat = 'png'; 19 | Canvas.supportedFormats = ['jpg', 'jpeg', 'png', 'gif']; 20 | Canvas.prototype = { 21 | addImage: function (img, x, y) { 22 | // Save the image for later 23 | this.images.push({ 24 | img: img, 25 | x: x, 26 | y: y 27 | }); 28 | }, 29 | 'export': function (options) { 30 | // Determine the export format 31 | var format = options.format || Canvas.defaultFormat; 32 | assert(Canvas.supportedFormats.indexOf(format) !== -1, 33 | '`pixelsmith` doesn\'t support exporting "' + format + '". Please use "jpeg", "png", or "gif"'); 34 | 35 | // If we have a custom background, fill it in (otherwise default is transparent black `rgba(0, 0, 0, 0)`) 36 | var ndarray = this.ndarray; 37 | var data = this.data; 38 | if (options.background) { 39 | for (var i = 0; i < data.length; ++i) { 40 | data[i] = options.background[i % 4]; 41 | } 42 | } 43 | 44 | // Add each image to the canvas 45 | var images = this.images; 46 | images.forEach(function getUrlPath (imageObj) { 47 | // Iterate over the image's data across its rows 48 | // setting the original data at that offset 49 | // [1, 2, 0, 0, 50 | // 3, 4, 0, 0, 51 | // 0, 0, 5, 0, 52 | // 0, 0, 0, 6] 53 | var img = imageObj.img; 54 | var xOffset = imageObj.x; 55 | var yOffset = imageObj.y; 56 | var colIndex = 0; 57 | var colCount = img.width; // DEV: Use `width` for padding 58 | for (; colIndex < colCount; colIndex += 1) { 59 | var rowIndex = 0; 60 | var rowCount = img.height; // DEV: Use `height` for padding 61 | for (; rowIndex < rowCount; rowIndex += 1) { 62 | var rgbaIndex = 0; 63 | var rgbaCount = 4; 64 | for (; rgbaIndex < rgbaCount; rgbaIndex += 1) { 65 | // If we are working with a 4 dimensional array, ignore the first dimension 66 | // DEV: This is a GIF; [frames, width, height, rgba] 67 | var val; 68 | if (img.shape.length === 4) { 69 | val = img.get(0, colIndex, rowIndex, rgbaIndex); 70 | // Otherwise, transfer data directly 71 | } else { 72 | val = img.get(colIndex, rowIndex, rgbaIndex); 73 | } 74 | ndarray.set(xOffset + colIndex, yOffset + rowIndex, rgbaIndex, val); 75 | } 76 | } 77 | } 78 | }); 79 | 80 | // Concatenate the ndarray into a png 81 | return savePixels(ndarray, format, options); 82 | } 83 | }; 84 | 85 | // Export Canvas 86 | module.exports = Canvas; 87 | -------------------------------------------------------------------------------- /lib/engine.js: -------------------------------------------------------------------------------- 1 | // Load in our dependencies 2 | var async = require('async'); 3 | var concat = require('concat-stream'); 4 | var getPixels = require('get-pixels'); 5 | var mime = require('mime-types'); 6 | var vinylFile = require('vinyl-file'); 7 | var Canvas = require('./canvas'); 8 | 9 | function Pixelsmith(options) { 10 | options = options || {}; 11 | this.concurrentFileLimit = options.concurrentFileLimit || Infinity; 12 | } 13 | Pixelsmith.specVersion = '2.0.0'; 14 | Pixelsmith.prototype = { 15 | createCanvas: function (width, height) { 16 | // Create and return a new canvas 17 | var canvas = new Canvas(width, height); 18 | return canvas; 19 | }, 20 | // Define our mass image population 21 | createImage: function (file, callback) { 22 | // In series 23 | async.waterfall([ 24 | // Load the images into memory 25 | function loadImage (cb) { 26 | // If the file is a string, upcast it to buffer-based vinyl 27 | // DEV: We don't use `Vinyl.isVinyl` since that was introduced in Sep 2015 28 | // We want some backwards compatibility with older setups 29 | if (typeof file === 'string') { 30 | vinylFile.read(file, cb); 31 | // Otherwise, callback with the existing vinyl object 32 | } else { 33 | cb(null, file); 34 | } 35 | }, 36 | function loadPixels (file, cb) { 37 | // If the vinyl object is null, then load from disk 38 | if (file.isNull()) { 39 | getPixels(file.path, cb); 40 | } else { 41 | var concatStream = concat(function handleFileBuffer (buff) { 42 | // https://github.com/scijs/get-pixels/blob/2e8766f62a9043d74a4b1047294a25fea5b2eacf/node-pixels.js#L179 43 | if (buff.length === 0) { 44 | return cb(new Error('Expected image "' + file.path + '" to not be empty but it was')); 45 | } 46 | getPixels(buff, mime.lookup(file.path), function handleGetPixels (err, contents) { 47 | if (err) { 48 | err.message += ' (' + file.path + ')'; 49 | } 50 | cb(err, contents); 51 | }); 52 | }); 53 | // https://github.com/gulpjs/vinyl/commit/d14ba4a7b51f0f3682f65f2aa4314d981eb1029d 54 | if (file.isStream()) { 55 | file.contents.pipe(concatStream); 56 | } else if (file.isBuffer()) { 57 | concatStream.end(file.contents); 58 | } else { 59 | throw new Error('Unrecognized Vinyl type'); 60 | } 61 | } 62 | }, 63 | function saveImgSize (image, cb) { 64 | // Save the width and height 65 | // If there are 4 dimensions, use the last 3 66 | // DEV: For gifs, the first dimension is frames 67 | if (image.shape.length === 4) { 68 | image.width = image.shape[1]; 69 | image.height = image.shape[2]; 70 | // Otherwise, use the normal [width, height, rgba] set 71 | } else { 72 | image.width = image.shape[0]; 73 | image.height = image.shape[1]; 74 | } 75 | cb(null, image); 76 | } 77 | ], callback); 78 | }, 79 | createImages: function (files, callback) { 80 | // In parallel, calculate each of our images 81 | // DEV: We use `mapLimit` to deal with file descriptor constraints, https://github.com/twolfson/pixelsmith/issues/20 82 | async.mapLimit(files, this.concurrentFileLimit, this.createImage.bind(this), callback); 83 | } 84 | }; 85 | 86 | // Export our engine 87 | module.exports = Pixelsmith; 88 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "pixelsmith", 3 | "description": "Node based engine for spritesmith", 4 | "version": "2.6.0", 5 | "homepage": "https://github.com/twolfson/pixelsmith", 6 | "author": { 7 | "name": "Todd Wolfson", 8 | "email": "todd@twolfson.com", 9 | "url": "http://twolfson.com/" 10 | }, 11 | "repository": { 12 | "type": "git", 13 | "url": "git://github.com/twolfson/pixelsmith.git" 14 | }, 15 | "bugs": { 16 | "url": "https://github.com/twolfson/pixelsmith/issues" 17 | }, 18 | "licenses": "Unlicense", 19 | "main": "lib/engine", 20 | "engines": { 21 | "node": ">= 12.0.0" 22 | }, 23 | "scripts": { 24 | "precheck": "twolfson-style precheck lib/ test/", 25 | "lint": "twolfson-style lint lib/ test/", 26 | "pretest": "twolfson-style install", 27 | "test": "npm run precheck && mocha --reporter dot && npm run lint" 28 | }, 29 | "dependencies": { 30 | "async": "^3.2.3", 31 | "concat-stream": "~1.5.1", 32 | "get-pixels": "~3.3.0", 33 | "mime-types": "~2.1.7", 34 | "ndarray": "~1.0.15", 35 | "obj-extend": "~0.1.0", 36 | "save-pixels": "~2.3.0", 37 | "vinyl-file": "~1.3.0" 38 | }, 39 | "devDependencies": { 40 | "foundry": "~4.3.2", 41 | "foundry-release-git": "~2.0.2", 42 | "foundry-release-npm": "~2.0.2", 43 | "jscs": "~3.0.7", 44 | "jshint": "~2.5.10", 45 | "mocha": "~9.1.1", 46 | "spritesmith-engine-test": "~5.0.0", 47 | "twolfson-style": "~1.6.0" 48 | }, 49 | "keywords": [ 50 | "spritesmith", 51 | "image", 52 | "spritesmith-engine" 53 | ], 54 | "foundry": { 55 | "releaseCommands": [ 56 | "foundry-release-git", 57 | "foundry-release-npm" 58 | ] 59 | } 60 | } -------------------------------------------------------------------------------- /test/expected-files/background.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/twolfson/pixelsmith/f2d7edbb25a0eae63befb326d16f0c11ca327756/test/expected-files/background.jpeg -------------------------------------------------------------------------------- /test/expected-files/multiple.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/twolfson/pixelsmith/f2d7edbb25a0eae63befb326d16f0c11ca327756/test/expected-files/multiple.gif -------------------------------------------------------------------------------- /test/expected-files/multiple.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/twolfson/pixelsmith/f2d7edbb25a0eae63befb326d16f0c11ca327756/test/expected-files/multiple.jpg -------------------------------------------------------------------------------- /test/expected-files/single.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/twolfson/pixelsmith/f2d7edbb25a0eae63befb326d16f0c11ca327756/test/expected-files/single.gif -------------------------------------------------------------------------------- /test/pixelsmith-test.js: -------------------------------------------------------------------------------- 1 | // Load our dependencies 2 | var assert = require('assert'); 3 | var fs = require('fs'); 4 | var spritesmithEngineTest = require('spritesmith-engine-test'); 5 | var Pixelsmith = require('../'); 6 | 7 | // Run our test 8 | // DEV: This covers png and jpeg inputs 9 | spritesmithEngineTest.run({ 10 | engine: Pixelsmith, 11 | engineName: 'pixelsmith' 12 | }); 13 | 14 | // Define custom tests 15 | var spritesmithUtils = spritesmithEngineTest.spritesmithUtils; 16 | describe('pixelsmith', function () { 17 | spritesmithUtils.createEngine(Pixelsmith); 18 | describe('outputting a spritesheet with a custom background', function () { 19 | var multiplePngImages = spritesmithEngineTest.config.multiplePngImages; 20 | spritesmithUtils.interpretStringImages(multiplePngImages.filepaths); 21 | 22 | describe('when rendered', function () { 23 | // Render a gif image 24 | spritesmithUtils.renderCanvas({ 25 | width: multiplePngImages.width, 26 | height: multiplePngImages.height, 27 | coordinateArr: multiplePngImages.coordinateArr, 28 | exportParams: { 29 | background: [255, 0, 255, 255], 30 | format: 'jpeg' 31 | } 32 | }); 33 | 34 | // Allow for debugging 35 | if (process.env.TEST_DEBUG) { 36 | spritesmithUtils.debugResult('debug-background.jpeg'); 37 | } 38 | 39 | it('used the expected background', function () { 40 | var actualImg = fs.readFileSync(__dirname + '/expected-files/background.jpeg'); 41 | assert.deepEqual(this.result, actualImg); 42 | }); 43 | }); 44 | }); 45 | 46 | // DEV: Written for https://github.com/twolfson/pixelsmith/issues/16 47 | describe('loading a JPEG with `.png` extension', function () { 48 | it('outputs a reasonable error', function (done) { 49 | this.engine.createImage(__dirname + '/test-files/jpeg-wrong-extension.png', 50 | function handleCreateImage (err, imgs) { 51 | assert(err.message.match('jpeg-wrong-extension.png')); 52 | assert(err.stack.match('jpeg-wrong-extension.png')); 53 | done(); 54 | }); 55 | }); 56 | }); 57 | }); 58 | -------------------------------------------------------------------------------- /test/test-files/jpeg-wrong-extension.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/twolfson/pixelsmith/f2d7edbb25a0eae63befb326d16f0c11ca327756/test/test-files/jpeg-wrong-extension.png -------------------------------------------------------------------------------- /test/test-files/sprite3.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/twolfson/pixelsmith/f2d7edbb25a0eae63befb326d16f0c11ca327756/test/test-files/sprite3.gif --------------------------------------------------------------------------------