{"id":13447005,"url":"https://github.com/yahoo/blink-diff","last_synced_at":"2025-03-21T17:30:41.253Z","repository":{"id":22792961,"uuid":"26139258","full_name":"yahoo/blink-diff","owner":"yahoo","description":"A lightweight image comparison tool.","archived":true,"fork":false,"pushed_at":"2020-02-14T10:25:30.000Z","size":31786,"stargazers_count":1207,"open_issues_count":28,"forks_count":90,"subscribers_count":37,"default_branch":"master","last_synced_at":"2024-12-31T07:28:10.287Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"http://yahoo.github.io/blink-diff/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/yahoo.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-11-03T21:20:26.000Z","updated_at":"2024-11-12T06:08:48.000Z","dependencies_parsed_at":"2022-09-13T02:52:27.324Z","dependency_job_id":null,"html_url":"https://github.com/yahoo/blink-diff","commit_stats":null,"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yahoo%2Fblink-diff","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yahoo%2Fblink-diff/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yahoo%2Fblink-diff/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yahoo%2Fblink-diff/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/yahoo","download_url":"https://codeload.github.com/yahoo/blink-diff/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244838016,"owners_count":20518766,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-07-31T05:01:05.565Z","updated_at":"2025-03-21T17:30:39.904Z","avatar_url":"https://github.com/yahoo.png","language":"JavaScript","funding_links":[],"categories":["JavaScript","others"],"sub_categories":[],"readme":"Blink-Diff\n==========\n\nA lightweight image comparison tool\n\n[![Build Status](https://img.shields.io/travis/yahoo/blink-diff.svg)](http://travis-ci.org/yahoo/blink-diff)\n[![Coveralls Coverage](https://img.shields.io/coveralls/yahoo/blink-diff.svg)](https://coveralls.io/r/yahoo/blink-diff)\n[![Code Climate Grade](https://img.shields.io/codeclimate/github/yahoo/blink-diff.svg)](https://codeclimate.com/github/yahoo/blink-diff)\n\n[![NPM version](https://badge.fury.io/js/blink-diff.svg)](https://www.npmjs.com/package/blink-diff)\n[![NPM License](https://img.shields.io/npm/l/blink-diff.svg)](https://www.npmjs.com/package/blink-diff)\n\n[![NPM](https://nodei.co/npm/blink-diff.png?downloads=true\u0026stars=true)](https://www.npmjs.com/package/blink-diff)\n[![NPM](https://nodei.co/npm-dl/blink-diff.png?months=3\u0026height=2)](https://www.npmjs.com/package/blink-diff)\n\n[![Coverage Report](https://img.shields.io/badge/Coverage_Report-Available-blue.svg)](http://yahoo.github.io/blink-diff/coverage/lcov-report/)\n[![API Documentation](https://img.shields.io/badge/API_Documentation-Available-blue.svg)](http://yahoo.github.io/blink-diff/docs/)\n\n[![Gitter Support](https://img.shields.io/badge/Support-Gitter_IM-yellow.svg)](https://gitter.im/preceptorjs/support)\n\n**Table of Contents**\n* [Installation](#installation)\n* [Usage](#usage)\n    * [Command-Line Usage](#command-line-usage)\n    * [Object Usage](#object-usage)\n    * [Cropping](#cropping)\n    * [Perceptual Comparison](#perceptual-comparison)\n    * [Logging](#logging)\n    * [Block-Out](#block-out)\n* [Examples](#examples)\n* [API-Documentation](#api-documentation)\n* [Tests](#tests)\n* [Project Focus](#project-focus)\n* [Project Naming](#project-naming)\n* [Contributions](#contributions)\n* [Contributors](#contributers)\n* [Third-party libraries](#third-party-libraries)\n* [License](#license)\n\n\n##Image Comparison and Result\n![Composition](https://raw.githubusercontent.com/yahoo/blink-diff/master/images/composition.png)\n\n##Installation\n\nInstall this module with the following command:\n```shell\nnpm install blink-diff\n```\n\nAdd the module to your ```package.json``` dependencies:\n```shell\nnpm install --save blink-diff\n```\nAdd the module to your ```package.json``` dev-dependencies:\n```shell\nnpm install --save-dev blink-diff\n```\n\n##Usage\n\nThe package can be used in two different ways:\n * per command line\n * through an object\n\n###Command-Line usage\n\nThe command-line tool can be found in the ```bin``` directory. You can run the application with\n\n```shell\nblink-diff --output \u003coutput\u003e.png \u003cimage1\u003e.png \u003cimage2\u003e.png\n```\nUse ```image1``` and ```image2``` as the images you want to compare.\nOnly PNGs are supported at this point.\n\n\nThe command-line tool exposes a couple of flags and parameters for the comparison:\n```\n--verbose           Turn on verbose mode\n--debug             Turn on debug mode - leaving all filters and modifications on the result\n--threshold p       Number of pixels/percent 'p' below which differences are ignored\n--threshold-type t  'pixel' and 'percent' as type of threshold. (default: pixel)\n--delta p           Max. distance colors in the 4 dimensional color-space without triggering a difference. (default: 20)\n--copyImageA        Copies first image to output as base. (default: true)\n--copyImageB        Copies second image to output as base.\n--no-copy           Doesn't copy anything to output as base.\n--output o          Write difference to the file 'o'\n--filter f          Filters f (separated with comma) that will be applied before the comparison.\n--no-composition    Turns the composition feature off\n--compose-ltr       Compose output image from left to right\n--compose-ttb       Compose output image from top to bottom\n--hide-shift        Hides shift highlighting (default: false)\n--h-shift           Acceptable horizontal shift of pixel. (default: 0)\n--v-shift           Acceptable vertical shift of pixel. (default: 0)\n--block-out x,y,w,h Block-out area. Can be repeated multiple times.\n--version           Print version\n--help              This help\n```\n\n\n###Object usage\n\nThe package can also be used directly in code, without going through the command-line.\n\n**Example:**\n```javascript\nvar diff = new BlinkDiff({\n    imageAPath: 'path/to/first/image', // Use file-path\n    imageBPath: 'path/to/second/image',\n\n    thresholdType: BlinkDiff.THRESHOLD_PERCENT,\n    threshold: 0.01, // 1% threshold\n\n    imageOutputPath: 'path/to/output/image'\n});\n\ndiff.run(function (error, result) {\n   if (error) {\n      throw error;\n   } else {\n      console.log(diff.hasPassed(result.code) ? 'Passed' : 'Failed');\n      console.log('Found ' + result.differences + ' differences.');\n   }\n});\n```\n\nAll the parameters that were available in the command-line tool are also available through the class constructor, however they might use slightly different wording. The class exposes additional parameters that are not available from the command-line:\n* ```imageAPath``` Defines the path to the first image that should be compared (required; imageAPath or imageA is required - see example below)\n* ```imageA``` Supplies first image that should be compared (required; imageAPath or imageA is required - see example below) - This can be a PNGImage instance or a Buffer instance with PNG data\n* ```imageBPath``` Defines the path to the second image that should be compared (required; imageBPath or imageB is required - see example below)\n* ```imageB``` Supplies second image that should be compared (required; imageBPath or imageB is required - see example below) - This can be a PNGImage instance or a Buffer instance with PNG data\n* ```imageOutputPath``` Defines the path to the output-file. If you leaves this one off, then this feature is turned-off.\n* ```imageOutputLimit``` Defines when an image output should be created. This can be for different images, similar or different images, or all comparisons. (default: BlinkDiff.OUTPUT_ALL)\n* ```verbose``` Verbose output (default: false)\n* ```thresholdType``` Type of threshold check. This can be BlinkDiff.THRESHOLD_PIXEL and BlinkDiff.THRESHOLD_PERCENT (default: BlinkDiff.THRESHOLD_PIXEL)\n* ```threshold``` Number of pixels/percent p below which differences are ignored (default: 500) - For percentage thresholds: 1 = 100%, 0.2 = 20%\n* ```delta``` Distance between the color coordinates in the 4 dimensional color-space that will not trigger a difference. (default: 20)\n* ```outputMaskRed``` Red intensity for the difference highlighting in the output file (default: 255)\n* ```outputMaskGreen``` Green intensity for the difference highlighting in the output file (default: 0)\n* ```outputMaskBlue``` Blue intensity for the difference highlighting in the output file (default: 0)\n* ```outputMaskAlpha``` Alpha intensity for the difference highlighting in the output file (default: 255)\n* ```outputMaskOpacity``` Opacity of the pixel for the difference highlighting in the output file (default: 0.7 - slightly transparent)\n* ```outputShiftRed``` Red intensity for the shift highlighting in the output file (default: 255)\n* ```outputShiftGreen``` Green intensity for the shift highlighting in the output file (default: 165)\n* ```outputShiftBlue``` Blue intensity for the shift highlighting in the output file (default: 0)\n* ```outputShiftAlpha``` Alpha intensity for the shift highlighting in the output file (default: 255)\n* ```outputShiftOpacity``` Opacity of the pixel for the shift highlighting in the output file (default: 0.7 - slightly transparent)\n* ```outputBackgroundRed``` Red intensity for the background in the output file (default: 0)\n* ```outputBackgroundGreen``` Green intensity for the background in the output file (default: 0)\n* ```outputBackgroundBlue``` Blue intensity for the background in the output file (default: 0)\n* ```outputBackgroundAlpha``` Alpha intensity for the background in the output file (default: undefined)\n* ```outputBackgroundOpacity``` Opacity of the pixel for the background in the output file (default: 0.6 - transparent)\n* ```blockOut``` Object or list of objects with coordinates that should be blocked before testing.\n* ```blockOutRed``` Red intensity for the block-out in the output file (default: 0) This color will only be visible in the result when debug-mode is turned on.\n* ```blockOutGreen``` Green intensity for the block-out in the output file (default: 0) This color will only be visible in the result when debug-mode is turned on.\n* ```blockOutBlue``` Blue intensity for the block-out in the output file (default: 0) This color will only be visible in the result when debug-mode is turned on.\n* ```blockOutAlpha``` Alpha intensity for the block-out in the output file (default: 255)\n* ```blockOutOpacity``` Opacity of the pixel for the block-out in the output file (default: 1.0)\n* ```copyImageAToOutput``` Copies the first image to the output image before the comparison begins. This will make sure that the output image will highlight the differences on the first image. (default)\n* ```copyImageBToOutput``` Copies the second image to the output image before the comparison begins. This will make sure that the output image will highlight the differences on the second image.\n* ```filter``` Filters that will be applied before the comparison. Available filters are: blur, grayScale, lightness, luma, luminosity, sepia\n* ```debug``` When set, then the applied filters will be shown on the output image. (default: false)\n* ```composition``` Creates as output a composition of all three images (approved, highlight, and build) (default: true)\n* ```composeLeftToRight``` Creates comparison-composition from left to right, otherwise it lets decide the app on what is best\n* ```composeTopToBottom``` Creates comparison-composition from top to bottom, otherwise it lets decide the app on what is best\n* ```hShift``` Horizontal shift for possible antialiasing (default: 2) Set to 0 to turn this off.\n* ```vShift``` Vertical shift for possible antialiasing (default: 2) Set to 0 to turn this off.\n* ```hideShift``` Uses the background color for \"highlighting\" shifts. (default: false)\n* ```cropImageA``` Cropping for first image (default: no cropping) - Format: { x:\u003cint\u003e, y:\u003cint\u003e, width:\u003cint\u003e, height:\u003cint\u003e }\n* ```cropImageB``` Cropping for second image (default: no cropping) - Format: { x:\u003cint\u003e, y:\u003cint\u003e, width:\u003cint\u003e, height:\u003cint\u003e }\n* ```perceptual``` Turn the perceptual comparison mode on. See below for more information.\n* ```gamma``` Gamma correction for all colors (will be used as base) (default: none) - Any value here will turn the perceptual comparison mode on\n* ```gammaR``` Gamma correction for red - Any value here will turn the perceptual comparison mode on\n* ```gammaG``` Gamma correction for green - Any value here will turn the perceptual comparison mode on\n* ```gammaB``` Gamma correction for blue - Any value here will turn the perceptual comparison mode on\n\n**Example:**\n```javascript\nvar firstImage = PNGImage.readImage('path/to/first/image', function (err) {\n\n  if (err) {\n    throw err;\n  }\n\n  var diff = new BlinkDiff({\n      imageA: srcImage, // Use already loaded image for first image\n      imageBPath: 'path/to/second/image', // Use file-path to select image\n\n      delta: 50, // Make comparison more tolerant\n      \n      outputMaskRed: 0,\n      outputMaskBlue: 255, // Use blue for highlighting differences\n      \n      hideShift: true, // Hide anti-aliasing differences - will still determine but not showing it\n\n      imageOutputPath: 'path/to/output/image'\n  });\n\n  diff.run(function (error, result) {\n    if (error) {\n      throw error;\n    } else {\n      console.log(diff.hasPassed(result.code) ? 'Passed' : 'Failed');\n      console.log('Found ' + result.differences + ' differences.');\n    }\n  });\n});\n```\n\n####Cropping\nImages can be cropped before they are compared by using the ```cropImageA``` or ```cropImageB``` parameters. Single values can be left off, and the system will calculate the correct dimensions. However, ```x```/```y``` coordinates have priority over ```width```/```height``` as the position are usually more important than the dimensions - image will also be clipped by the system when needed.\n\n####Perceptual Comparison\nThe perceptual comparison mode considers the perception of colors in the human brain. It transforms all the colors into a human perception color-space, which is quite different to the typical physical bound RGB color-space. There, in the perceptual color-space, the distance between colors is according to the human perception and should therefore closer resemble the differences a human would perceive seeing the images.\n\n####Logging\n\nBy default, the logger doesn't log events anywhere, but you can change this behavior by overwriting ```blinkDiff.log```:\n\n```javascript\nvar blinkDiff = new BlinkDiff({\n    ...\n});\n\nblinkDiff.log = function (text) {\n    // Do whatever you want to do\n};\n\n...\n```\n\n####Block-Out\nSometimes, it is necessary to block-out some specific areas in an image that should be ignored for comparisons. For example, this can be IDs or even time-labels that change with the time. Adding block-outs to images may decrease false positives and therefore stabilizes these comparisons.\n\nThe color of the block-outs can be selected by the API parameters. However, the block-out areas will not be visible by default - they are hidden even though they are used. To make them visible, turn the debug-mode on.\n\n##Examples\n\nThere are some examples in the ```examples``` folder, in which I used screenshots of YDN to check for visual regressions (and made some manual modifications to the dom to make differences appear ;-)).\nYou can find examples for:\n* Color changes in ```YDN_Color```\n* Missing DOM elements in ```YDN_Missing``` (including some anti-aliasing)\n* Multiple differences in ```YDN_Multi```\n* Disrupted sorting in ```YDN_Sort```\n* Swapped items in ```YDN_Swap``` (including block-out areas)\n* Text capitalization in ```YDN_Upper```\n\nAll screenshots were compared to ```YDN.png```, a previously approved screenshot without a regression.\nEach of the regressions has the screenshot and the output result, highlighting the differences.\n\n##API-Documentation\n\nGenerate the documentation with following command:\n```shell\nnpm run docs\n```\nThe documentation will be generated in the ```docs``` folder of the module root.\n\n##Tests\n\nRun the tests with the following command:\n```shell\nnpm run test\n```\nThe code-coverage will be written to the ```coverage``` folder in the module root.\n\n##Project Focus\nThere are three types of image comparisons:\n* Pixel-by-pixel - Used to compare low-frequency images like screenshots from web-sites, making sure that small styling differences trigger\n* Perceptual - Used to compare image creation applications, for example rendering engines and photo manipulation applications that are taking the human perception into account, ignoring differences a human probably would not see\n* Context - Used to see if parts of images are missing or are severely distorted, but accepts smaller and/or perceptual differences\n\nBlink-Diff was initially created to compare screenshots. These images are generally low-frequency, meaning larger areas with the same color and less gradients than in photos. The pixel-by-pixel comparison was chosen as it will trigger for differences that a human might not be able to see. We believe that a bug is still a bug even if a human won't see it - a regression might have happened that wasn't intended.\nA perceptual comparison would not trigger small differences, possibly missing problems that could get worse down the road.\nPixel-by-pixel comparisons have the reputation of triggering too often, adding manual labor, checking images by hand. Blink-Diff was created to keep this in mind and was optimized to reduce false-positives by taking sub-pixeling and anti-aliasing into account. Additional features like thresholds and the pythagorean distance calculation in the four dimensional color-space makes sure that this won't happen too often. Additionally, filters can be applied to the images, for example to compare luminosity of pixels and not the saturation thereof.\nBlink-Diff also supports partially the perceptual comparison that can be turned on when supplying ```perceptual=true```. Then, the colors will be compared in accordance with the human perception and not according to the physical world. High-frequency filters, however, are not yet supported.\n\n##Project Naming\nThe name comes from the [Blink comparator](http://en.wikipedia.org/wiki/Blink_comparator) that was used in Astronomy to recognize differences in multiple photos, taking a picture of the same area in the sky over consecutive days, months, or years. Most notably, it was used to discover Pluto.\n\n##Contributions\nFeel free to create an issue or create a pull-request if you have an idea on how to improve blink-diff. We are pretty relaxed on the contribution rules; add tests for your pull-requests when possible, but it is also ok if there are none - we'll add them for you. We are trying to improve blink-diff as much as possible, and this can only be done by contributions from the community.\n\nAlso, even if you simply gave us an idea for a feature and did not actually write the code, we will still add you as the Contributor down below since it probably wouldn't be there without you. So, keep them coming!\n\n##Contributors\n* [sarbbottam](https://github.com/sarbbottam)\n* [koola](https://github.com/koola)\n* [jeffposnick](https://github.com/jeffposnick)\n* [a-nwhitmont](https://github.com/a-nwhitmont)\n* [azu](https://github.com/azu)\n* [bradex](https://github.com/bradex)\n\n##Third-party libraries\n\nThe following third-party libraries are used by this module:\n\n###Dependencies\n* promise: https://github.com/then/promise\n* pngjs-image: https://github.com/yahoo/pngjs-image\n\n###Dev-Dependencies\n* chai: http://chaijs.com\n* coveralls: https://github.com/cainus/node-coveralls\n* codeclimate-test-reporter: https://github.com/codeclimate/javascript-test-reporter\n* istanbul: https://github.com/gotwarlost/istanbul\n* mocha: https://github.com/visionmedia/mocha\n* sinon: http://sinonjs.org\n* sinon-chai: https://github.com/domenic/sinon-chai\n* yuidocjs: https://github.com/yui/yuidoc\n\n##License\n\nThe MIT License\n\nCopyright 2014-2015 Yahoo Inc.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyahoo%2Fblink-diff","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyahoo%2Fblink-diff","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyahoo%2Fblink-diff/lists"}