{ "info": { "author": "Wu Haotian", "author_email": "whtsky@gmail.com", "bugtrack_url": null, "classifiers": [ "License :: OSI Approved", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9" ], "description": "# pixelmatch-py\n\nA fast pixel-level image comparison library, originally created to compare screenshots in tests.\nNow with additional support of PIL.Image instances\nPython port of https://github.com/mapbox/pixelmatch.\n\nFeatures accurate **anti-aliased pixels detection**\nand **perceptual color difference metrics**.\n\n```python\nfrom pixelmatch import pixelmatch\n\nnum_diff_pixels = pixelmatch(img1, img2, 800, 600, diff, threshold=0.1)\n```\n\nImplements ideas from the following papers:\n\n- [Measuring perceived color difference using YIQ NTSC transmission color space in mobile applications](https://pdfs.semanticscholar.org/cb71/56034b6e427ddc9b5da1a4f5fcb10831c9fd.pdf) (2010, Yuriy Kotsarenko, Fernando Ramos)\n- [Anti-aliased pixel and intensity slope detector](https://www.researchgate.net/publication/234126755_Anti-aliased_Pixel_and_Intensity_Slope_Detector) (2009, Vytautas Vy\u0161niauskas)\n\n## Install\n\n```bash\npython -m pip install pixelmatch\n```\n\n## Example usage\n\n### PIL.Image comparison\n\n```python\nfrom PIL import Image\n\nfrom pixelmatch.contrib.PIL import pixelmatch\n\nimg_a = Image.open(\"a.png\")\nimg_b = Image.open(\"b.png\")\nimg_diff = Image.new(\"RGBA\", img_a.size)\n\n# note how there is no need to specify dimensions\nmismatch = pixelmatch(img_a, img_b, img_diff, includeAA=True)\n\nimg_diff.save(\"diff.png\")\n```\n\n### Raw Image Data Comparison\n\n```python\nfrom pixelmatch import pixelmatch\n\nwidth, height = 1920, 1080\nimg_a = [R1, G1, B1, A1, R2, B2, G2, A2, ...]\nimg_b = [R1, G1, B1, A1, R2, B2, G2, A2, ...]\n\ndata_diff = [0] * len(img_a)\n\nmismatch = pixelmatch(img_a, img_b, width, height, data_diff, includeAA=True)\n```\n\n## API\n\n### pixelmatch(img1, img2, width, height, output, threshold, includeAA, alpha, aa_color, diff_color, diff_mask, fail_fast)\n\n- `img1`, `img2` \u2014 RGBA Image data of the images to compare. **Note:** image dimensions must be equal.\n- `width`, `height` \u2014 Width and height of the images.\n- `output` \u2014 Image data to write the diff to, or `None` if don't need a diff image. Note that _all three images_ need to have the same dimensions.\n- `threshold` \u2014 Matching threshold, ranges from `0` to `1`. Smaller values make the comparison more sensitive. `0.1` by default.\n- `includeAA` \u2014 If `true`, disables detecting and ignoring anti-aliased pixels. `false` by default.\n- `alpha` \u2014 Blending factor of unchanged pixels in the diff output. Ranges from `0` for pure white to `1` for original brightness. `0.1` by default.\n- `aa_color` \u2014 The color of anti-aliased pixels in the diff output in `[R, G, B]` format. `[255, 255, 0]` by default.\n- `diff_color` \u2014 The color of differing pixels in the diff output in `[R, G, B]` format. `[255, 0, 0]` by default.\n- `diff_mask` \u2014 Draw the diff over a transparent background (a mask), rather than over the original image. Will not draw anti-aliased pixels (if detected).\n- `fail_fast` - If true, will return after first different pixel.\n\nCompares two images, writes the output diff and returns the number of mismatched pixels.\n\n### contrib.PIL.pixelmatch\n\nCompares two images, writes the output diff and returns the number of mismatched pixels. Exact same API as `pixelmatch.pixelmatch` except for the important fact that it takes instances of PIL.Image for image parameters (`img1`, `img2`, and `output`) and the width/size need not be specified.\n\n## Example output\n\n| expected | actual | diff |\n| ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- |\n| ![https://github.com/whtsky/pixelmatch-py/raw/master/fixtures/4a.png](https://github.com/whtsky/pixelmatch-py/raw/master/fixtures/4a.png) | ![https://github.com/whtsky/pixelmatch-py/raw/master/fixtures/4b.png](https://github.com/whtsky/pixelmatch-py/raw/master/fixtures/4b.png) | ![1diff](https://github.com/whtsky/pixelmatch-py/raw/master/fixtures/4diff.png) |\n| ![https://github.com/whtsky/pixelmatch-py/raw/master/fixtures/3a.png](https://github.com/whtsky/pixelmatch-py/raw/master/fixtures/3a.png) | ![https://github.com/whtsky/pixelmatch-py/raw/master/fixtures/3b.png](https://github.com/whtsky/pixelmatch-py/raw/master/fixtures/3b.png) | ![1diff](https://github.com/whtsky/pixelmatch-py/raw/master/fixtures/3diff.png) |\n| ![https://github.com/whtsky/pixelmatch-py/raw/master/fixtures/6a.png](https://github.com/whtsky/pixelmatch-py/raw/master/fixtures/6a.png) | ![https://github.com/whtsky/pixelmatch-py/raw/master/fixtures/6b.png](https://github.com/whtsky/pixelmatch-py/raw/master/fixtures/6b.png) | ![1diff](https://github.com/whtsky/pixelmatch-py/raw/master/fixtures/6diff.png) |\n| ![https://github.com/whtsky/pixelmatch-py/raw/master/fixtures/7a.png](https://github.com/whtsky/pixelmatch-py/raw/master/fixtures/7a.png) | ![https://github.com/whtsky/pixelmatch-py/raw/master/fixtures/7b.png](https://github.com/whtsky/pixelmatch-py/raw/master/fixtures/7b.png) | ![1diff](https://github.com/whtsky/pixelmatch-py/raw/master/fixtures/7diff.png) |\n\n## Changelog\n\n### v0.3.0\n\n- feat: add fail_fast option [#144](https://github.com/whtsky/pixelmatch-py/pull/144)\n### v0.2.4\n- type: fix typing issues\n- chore: test Python 3.10\n\n### v0.2.3\n\n- feat: make package comply with PEP-561\n\n### v0.2.2\n\n- typing: use `Sequence` instead of `List` for `RGBTuple`\n- build: switch to `poetry_core` [#81](https://github.com/whtsky/pixelmatch-py/pull/81)\n\n### v0.2.1\n\n- feat: add function to compare PIL.Image instances through contrib.PIL.pixelmatch [#42](https://github.com/whtsky/pixelmatch-py/pull/42)\n\n### v0.2.0\n\n- BREAKING CHANGE: remove `options` parameter [#38](https://github.com/whtsky/pixelmatch-py/pull/38)\n- docs: use absolute url for images in README\n\n### v0.1.1\n\n- fix: fix bug in fast path [#18](https://github.com/whtsky/pixelmatch-py/pull/18)\n\n### v0.1.0\n\n- Initial release\n\n", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/whtsky/pixelmatch-py", "keywords": "", "license": "ISC", "maintainer": "", "maintainer_email": "", "name": "pixelmatch", "package_url": "https://pypi.org/project/pixelmatch/", "platform": null, "project_url": "https://pypi.org/project/pixelmatch/", "project_urls": { "Homepage": "https://github.com/whtsky/pixelmatch-py", "Repository": "https://github.com/whtsky/pixelmatch-py" }, "release_url": "https://pypi.org/project/pixelmatch/0.3.0/", "requires_dist": null, "requires_python": ">=3.7,<4.0", "summary": "A pixel-level image comparison library.", "version": "0.3.0", "yanked": false, "yanked_reason": null }, "last_serial": 13270307, "releases": { "0.1.0": [ { "comment_text": "", "digests": { "md5": "ee9573c076ca7bc04fccf8878890dd9d", "sha256": "436da5944e6f5468b3c5372d4ce0acfa33e0a820c042c4f1acaaab1e7b393463" }, "downloads": -1, "filename": "pixelmatch-0.1.0-py3-none-any.whl", "has_sig": false, "md5_digest": "ee9573c076ca7bc04fccf8878890dd9d", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6,<4.0", "size": 4151, "upload_time": "2019-10-31T10:15:12", "upload_time_iso_8601": "2019-10-31T10:15:12.373136Z", "url": "https://files.pythonhosted.org/packages/98/5a/f591fe38574b921e74b084a80b59efeeb6117781112945cd58243cc46298/pixelmatch-0.1.0-py3-none-any.whl", "yanked": false, "yanked_reason": null }, { "comment_text": "", "digests": { "md5": "d2fd3305b57b3f344110ea151b951139", "sha256": "e486aac0db8364113ac9da32b4e7f453cf0ca1a3a4aba8702a08f6bec1ea2629" }, "downloads": -1, "filename": "pixelmatch-0.1.0.tar.gz", "has_sig": false, "md5_digest": "d2fd3305b57b3f344110ea151b951139", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6,<4.0", "size": 3837, "upload_time": "2019-10-31T10:15:21", "upload_time_iso_8601": "2019-10-31T10:15:21.036248Z", "url": "https://files.pythonhosted.org/packages/4c/8d/ad7cb406167721bb81b135b36b8c9c893e0a3a395714433a7ae8b288fd7a/pixelmatch-0.1.0.tar.gz", "yanked": false, "yanked_reason": null } ], "0.1.1": [ { "comment_text": "", "digests": { "md5": "76425bc54dd7f8af59f6b8019b718e1f", "sha256": "cf02670dda2a74c761656f8abb7b4ecbb08e97136e35b9f1adb47123cd145f65" }, "downloads": -1, "filename": "pixelmatch-0.1.1-py3-none-any.whl", "has_sig": false, "md5_digest": "76425bc54dd7f8af59f6b8019b718e1f", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6,<4.0", "size": 5663, "upload_time": "2020-03-12T17:58:08", "upload_time_iso_8601": "2020-03-12T17:58:08.624507Z", "url": "https://files.pythonhosted.org/packages/78/44/a39b581641e7a1a9240450b173b0955048b130b4942823ef337bd269d8b5/pixelmatch-0.1.1-py3-none-any.whl", "yanked": false, "yanked_reason": null }, { "comment_text": "", "digests": { "md5": "d705fe7ce9f110d673851fdd80b9cb08", "sha256": "e35a5a4563ddd9ceea1fe9e22d628e9d47ec30d64b602691cc6a8ca17e5ec830" }, "downloads": -1, "filename": "pixelmatch-0.1.1.tar.gz", "has_sig": false, "md5_digest": "d705fe7ce9f110d673851fdd80b9cb08", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6,<4.0", "size": 5699, "upload_time": "2020-03-12T17:58:10", "upload_time_iso_8601": "2020-03-12T17:58:10.206541Z", "url": "https://files.pythonhosted.org/packages/3f/d8/f3790bc1f2bf4f5acb391e9db1cfd591124b6e1ce3e989e5b8871703aa22/pixelmatch-0.1.1.tar.gz", "yanked": false, "yanked_reason": null } ], "0.2.0": [ { "comment_text": "", "digests": { "md5": "62405258f04db23f758d08bef9fdc008", "sha256": "a33118eafae1142d1aab4362cb762b9934059c0f4beff856decb0d1f066acc9d" }, "downloads": -1, "filename": "pixelmatch-0.2.0-py3-none-any.whl", "has_sig": false, "md5_digest": "62405258f04db23f758d08bef9fdc008", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6,<4.0", "size": 6329, "upload_time": "2020-05-08T18:32:03", "upload_time_iso_8601": "2020-05-08T18:32:03.888458Z", "url": "https://files.pythonhosted.org/packages/98/a8/c2fb13cebda2d3d134912931ad60d3d16eb04c31991dc1023b344d9235b3/pixelmatch-0.2.0-py3-none-any.whl", "yanked": false, "yanked_reason": null }, { "comment_text": "", "digests": { "md5": "780bb39557af985135502280383eae73", "sha256": "357dcfcb2936d97b98dc3285ae98ebb4d8607b3a52af67f27fa652fd7a66b8dd" }, "downloads": -1, "filename": "pixelmatch-0.2.0.tar.gz", "has_sig": false, "md5_digest": "780bb39557af985135502280383eae73", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6,<4.0", "size": 6310, "upload_time": "2020-05-08T18:32:05", "upload_time_iso_8601": "2020-05-08T18:32:05.553443Z", "url": "https://files.pythonhosted.org/packages/b3/c3/d1c3bcef8fa10a8117a7ee2173287580e229daf4d6bfd6aa0e35bb133402/pixelmatch-0.2.0.tar.gz", "yanked": false, "yanked_reason": null } ], "0.2.1": [ { "comment_text": "", "digests": { "md5": "79ed17bed3da6371d729232e5048b9ef", "sha256": "627b3140d31f88c0cd62c44fded8075c9c552c96d3118f52a0c2b7be56f71d7f" }, "downloads": -1, "filename": "pixelmatch-0.2.1-py3-none-any.whl", "has_sig": false, "md5_digest": "79ed17bed3da6371d729232e5048b9ef", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6,<4.0", "size": 8722, "upload_time": "2020-05-11T13:46:45", "upload_time_iso_8601": "2020-05-11T13:46:45.804073Z", "url": "https://files.pythonhosted.org/packages/c5/36/b1a29e54f0836ea7b243858ed3a97c7b083e24e1851d3d416999eb6c113f/pixelmatch-0.2.1-py3-none-any.whl", "yanked": false, "yanked_reason": null }, { "comment_text": "", "digests": { "md5": "1f1bcaad6273836c43dbd99fd6b52574", "sha256": "7309d71bd1880165132b55070bc9edba501bba0229a724bbcf7d5c2b31f3eeae" }, "downloads": -1, "filename": "pixelmatch-0.2.1.tar.gz", "has_sig": false, "md5_digest": "1f1bcaad6273836c43dbd99fd6b52574", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6,<4.0", "size": 8628, "upload_time": "2020-05-11T13:46:47", "upload_time_iso_8601": "2020-05-11T13:46:47.146173Z", "url": "https://files.pythonhosted.org/packages/23/46/2f2df0266e6ab1269a38a66345a4548471f165d17fe9f2b2f0340b2c14d9/pixelmatch-0.2.1.tar.gz", "yanked": false, "yanked_reason": null } ], "0.2.2": [ { "comment_text": "", "digests": { "md5": "ee21b31e7642a0da842c70abb6b9c047", "sha256": "43fc71239b5cba13598321f1975c922fa67ef40f6fff6ac3866baedc80a9633c" }, "downloads": -1, "filename": "pixelmatch-0.2.2-py3-none-any.whl", "has_sig": false, "md5_digest": "ee21b31e7642a0da842c70abb6b9c047", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6,<4.0", "size": 8782, "upload_time": "2021-02-06T06:11:43", "upload_time_iso_8601": "2021-02-06T06:11:43.217661Z", "url": "https://files.pythonhosted.org/packages/4d/62/a0f203a823eddd8bc73846671eef17e82d2128d5500a07cb4f7685e7c8c2/pixelmatch-0.2.2-py3-none-any.whl", "yanked": false, "yanked_reason": null }, { "comment_text": "", "digests": { "md5": "9b7b016ba0747e5d3d97542c931857de", "sha256": "b60019b42b9924cd6cd374006f381f75b701092a6b85fde3ce74acee58d8c38e" }, "downloads": -1, "filename": "pixelmatch-0.2.2.tar.gz", "has_sig": false, "md5_digest": "9b7b016ba0747e5d3d97542c931857de", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6,<4.0", "size": 8769, "upload_time": "2021-02-06T06:11:45", "upload_time_iso_8601": "2021-02-06T06:11:45.048256Z", "url": "https://files.pythonhosted.org/packages/ae/01/c6dd97e82c3704751ffde78f43350787b947459abe938af5907dfdd17267/pixelmatch-0.2.2.tar.gz", "yanked": false, "yanked_reason": null } ], "0.2.3": [ { "comment_text": "", "digests": { "md5": "18a07bba317a186d2f454b04fa4b458d", "sha256": "dd084fb2f7c45193bcd1ff743410be7107d56ec1c3dd81f5f70f5b67ef4559e3" }, "downloads": -1, "filename": "pixelmatch-0.2.3-py3-none-any.whl", "has_sig": false, "md5_digest": "18a07bba317a186d2f454b04fa4b458d", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6,<4.0", "size": 8933, "upload_time": "2021-02-17T12:24:20", "upload_time_iso_8601": "2021-02-17T12:24:20.484172Z", "url": "https://files.pythonhosted.org/packages/04/19/9b9d4934c2162a7a61bb5a3996d5908c665b9890705edb30f52632ef5dcd/pixelmatch-0.2.3-py3-none-any.whl", "yanked": false, "yanked_reason": null }, { "comment_text": "", "digests": { "md5": "2924cfc6e54a254efd480c943a8750f5", "sha256": "7e24d93a755126125ff58e460dfa0baac39e282d95709f63c03423be47033e9d" }, "downloads": -1, "filename": "pixelmatch-0.2.3.tar.gz", "has_sig": false, "md5_digest": "2924cfc6e54a254efd480c943a8750f5", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6,<4.0", "size": 8947, "upload_time": "2021-02-17T12:24:21", "upload_time_iso_8601": "2021-02-17T12:24:21.876657Z", "url": "https://files.pythonhosted.org/packages/a0/54/43b3610133eccc666f46d3395fd7448a8f740cd4b4b6fa3334af1a8feba8/pixelmatch-0.2.3.tar.gz", "yanked": false, "yanked_reason": null } ], "0.2.4": [ { "comment_text": "", "digests": { "md5": "9fc78aa26d870ac438ae529d32669c93", "sha256": "ca2b7891ae6ed027b256a7c92c67376f1c36a9263111665a1117ec4b6d80f8d4" }, "downloads": -1, "filename": "pixelmatch-0.2.4-py3-none-any.whl", "has_sig": false, "md5_digest": "9fc78aa26d870ac438ae529d32669c93", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6.2,<4.0.0", "size": 8984, "upload_time": "2022-01-09T15:48:00", "upload_time_iso_8601": "2022-01-09T15:48:00.028094Z", "url": "https://files.pythonhosted.org/packages/6f/c9/b03cb66a3539a430e40cef0b1baeb228e9cd04012bbbdd9bf8d9c5eb7763/pixelmatch-0.2.4-py3-none-any.whl", "yanked": false, "yanked_reason": null }, { "comment_text": "", "digests": { "md5": "4276a4fd5e9caa59d10ed8cb0cada86b", "sha256": "ad0e59ff5517f5ab498f357e439bce48cd6539da30af332c4e19c886067bf340" }, "downloads": -1, "filename": "pixelmatch-0.2.4.tar.gz", "has_sig": false, "md5_digest": "4276a4fd5e9caa59d10ed8cb0cada86b", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6.2,<4.0.0", "size": 7509, "upload_time": "2022-01-09T15:48:02", "upload_time_iso_8601": "2022-01-09T15:48:02.778905Z", "url": "https://files.pythonhosted.org/packages/9b/24/3a5e4d6c8c3abd8e51aba998c90dc3f3b1b417ee4c718a7d937c43cd4f6a/pixelmatch-0.2.4.tar.gz", "yanked": false, "yanked_reason": null } ], "0.3.0": [ { "comment_text": "", "digests": { "md5": "135c0b849ce7ac6fd4ec97351ef3deba", "sha256": "1fe86c50e7d00eb4b4de7b991f8b7ebc12da841ce1e9f7304480ab0f58a2bd81" }, "downloads": -1, "filename": "pixelmatch-0.3.0-py3-none-any.whl", "has_sig": false, "md5_digest": "135c0b849ce7ac6fd4ec97351ef3deba", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.7,<4.0", "size": 9155, "upload_time": "2022-03-23T14:51:33", "upload_time_iso_8601": "2022-03-23T14:51:33.271493Z", "url": "https://files.pythonhosted.org/packages/e1/09/766e3cb038be997cef78a29cfd4ec5e9be739b8ea44a09c839a6da8cb55b/pixelmatch-0.3.0-py3-none-any.whl", "yanked": false, "yanked_reason": null }, { "comment_text": "", "digests": { "md5": "bcb2542e8326820e55232725976c79ff", "sha256": "d0fa36a593cfcfa2d4b225da9d72c5b5218aef8b0594bc1a91953533c2676099" }, "downloads": -1, "filename": "pixelmatch-0.3.0.tar.gz", "has_sig": false, "md5_digest": "bcb2542e8326820e55232725976c79ff", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.7,<4.0", "size": 9142, "upload_time": "2022-03-23T14:51:35", "upload_time_iso_8601": "2022-03-23T14:51:35.225311Z", "url": "https://files.pythonhosted.org/packages/1c/59/ebc53e64156db78c75c6d7f535e3f80f62c8a8e1545783770f06f528e187/pixelmatch-0.3.0.tar.gz", "yanked": false, "yanked_reason": null } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "135c0b849ce7ac6fd4ec97351ef3deba", "sha256": "1fe86c50e7d00eb4b4de7b991f8b7ebc12da841ce1e9f7304480ab0f58a2bd81" }, "downloads": -1, "filename": "pixelmatch-0.3.0-py3-none-any.whl", "has_sig": false, "md5_digest": "135c0b849ce7ac6fd4ec97351ef3deba", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.7,<4.0", "size": 9155, "upload_time": "2022-03-23T14:51:33", "upload_time_iso_8601": "2022-03-23T14:51:33.271493Z", "url": "https://files.pythonhosted.org/packages/e1/09/766e3cb038be997cef78a29cfd4ec5e9be739b8ea44a09c839a6da8cb55b/pixelmatch-0.3.0-py3-none-any.whl", "yanked": false, "yanked_reason": null }, { "comment_text": "", "digests": { "md5": "bcb2542e8326820e55232725976c79ff", "sha256": "d0fa36a593cfcfa2d4b225da9d72c5b5218aef8b0594bc1a91953533c2676099" }, "downloads": -1, "filename": "pixelmatch-0.3.0.tar.gz", "has_sig": false, "md5_digest": "bcb2542e8326820e55232725976c79ff", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.7,<4.0", "size": 9142, "upload_time": "2022-03-23T14:51:35", "upload_time_iso_8601": "2022-03-23T14:51:35.225311Z", "url": "https://files.pythonhosted.org/packages/1c/59/ebc53e64156db78c75c6d7f535e3f80f62c8a8e1545783770f06f528e187/pixelmatch-0.3.0.tar.gz", "yanked": false, "yanked_reason": null } ], "vulnerabilities": [] }