{ "info": { "author": "Bram Geron", "author_email": "bram@bram.xyz", "bugtrack_url": null, "classifiers": [ "License :: OSI Approved :: MIT License", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7" ], "description": "\n***************************************************************\n``diff-pdf-visually``: Find visual differences between two PDFs\n***************************************************************\n\n.. image:: https://img.shields.io/pypi/v/diff-pdf-visually.svg\n :target: https://pypi.python.org/pypi/diff-pdf-visually/\n\n.. image:: https://img.shields.io/pypi/l/diff-pdf-visually.svg\n :target: https://pypi.python.org/pypi/diff-pdf-visually/\n\nThis script checks whether two PDFs are visually the same. So:\n\n- White text on a white background will be **ignored**.\n- Subtle changes in position, size, or color of text will be **detected**.\n- This program will ignore changes caused by a different version of the PDF generator, or by invisible changes in the source document.\n\nThis is in contrast to most other tools, which tend to extract the text stream out of a PDF, and then diff those texts. Such tools include:\n\n- `pdf-diff `_ by Joshua Tauberer\n\nThere seem to be some tools similar to the one you're looking at now, although I have experience with none of these:\n\n- V\u00e1clav Slav\u00edk seems to have `an open source one `_\n- There might be more useful ones mentioned on `this SuperUser thread `_\n\nThe strength of this script is that it's simple to use on the command line, and it's easy to reuse in scripts:\n\n.. code-block:: python\n\n from diff_pdf_visually import pdfdiff\n\n # Returns True or False\n pdfdiff(\"a.pdf\", \"b.pdf\")\n\nOr use it from the command line:\n\n.. code-block:: shell\n\n $ pip3 install --user diff-pdf-visually\n $ diff-pdf-visually a.pdf b.pdf\n\nHow it works\n============\n\nWe use ``pdftocairo`` to convert both PDFs to a series of PNG images in a temporary directory. The number of pages and the dimensions of the page must be exactly the same. Then we call ``compare`` from ImageMagick to check how similar they are; if one of the pages compares different above a certain threshold, then the PDFs are reported as different, otherwise they are reported the same.\n\n**You must have ImageMagick and pdftocairo already installed**.\n\nCall ``diff-pdf-visually`` without parameters (or run ``python3 -m diff_pdf_visually``) to see its command line arguments. Import it as ``diff_pdf_visually`` to use its functions from Python.\n\nThere are some options that you can use either from the command line or from Python::\n\n $ diff-pdf-visually -h\n usage: diff-pdf-visually [-h] [--silent] [--verbose] [--threshold THRESHOLD]\n [--dpi DPI] [--time TIME]\n a.pdf b.pdf\n\n Compare two PDFs visually. The exit code is 0 if they are the same, and 2 if\n there are significant differences.\n\n positional arguments:\n a.pdf\n b.pdf\n\n optional arguments:\n -h, --help show this help message and exit\n --silent, -q silence output (can be used only once)\n --verbose, -v show more information (can be used 2 times)\n --threshold THRESHOLD\n PSNR threshold to consider a change significant,\n higher is more sensitive (default: 100)\n --dpi DPI resolution for the rasterised files (default: 50)\n --time TIME number of seconds to wait before discarding temporary\n files, or 0 to immediately discard (hint: use -v)\n\nThese \"temporary files\" include a PNG image of where any differences are, per page, as well as the log output of ImageMagick. If you want to get a feeling for thresholds, there are some example PDFs in the ``tests/`` directory.\n\nSo what do you use this for?\n============================\n\nPersonally, I've used this a couple of times to refactor my LaTeX documents: I just simplify or remove some macro definitions, and if nothing changes, apparently it's safe to make that change.\n\nHow to install this\n===================\n\n``pip3 install diff-pdf-visually``\n\nStatus\n======\n\nAt the moment, this program/module works best for finding *whether* two PDFs are visually different.\n\nThis project is licenced under the MIT licence. It does not work on Python 2, but patches are welcome if they are not too invasive.\n\n", "description_content_type": "text/x-rst", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/bgeron/diff-pdf-visually", "keywords": "", "license": "MIT", "maintainer": "Bram Geron", "maintainer_email": "bram@bram.xyz", "name": "diff-pdf-visually", "package_url": "https://pypi.org/project/diff-pdf-visually/", "platform": "", "project_url": "https://pypi.org/project/diff-pdf-visually/", "project_urls": { "Homepage": "https://github.com/bgeron/diff-pdf-visually" }, "release_url": "https://pypi.org/project/diff-pdf-visually/1.3.1/", "requires_dist": null, "requires_python": ">=3.0,<4.0", "summary": "A simple script to test whether there is a significant difference between two PDFs using ImageMagick and pdftocairo.", "version": "1.3.1" }, "last_serial": 4245415, "releases": { "1.1.0": [ { "comment_text": "", "digests": { "md5": "fa60096172d9267466d443f723765fe2", "sha256": "1c32648e903697c61c7cad380ffdfaef6b50ac4b4a4d30f04bddf5b17dbf4584" }, "downloads": -1, "filename": "diff_pdf_visually-1.1.0-py3-none-any.whl", "has_sig": false, "md5_digest": "fa60096172d9267466d443f723765fe2", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.0,<4.0", "size": 9865, "upload_time": "2018-09-05T23:19:40", "url": "https://files.pythonhosted.org/packages/69/18/3dda32df02e6a0c90a0b397d86045e4acae9660bc03b6116ab6104feded1/diff_pdf_visually-1.1.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "958ce26cbc5689420d8e5b24ed780086", "sha256": "130ec75a5c5d68fac4a2ba5bba71b640adc8a1c2cb2186db603208d55d4721e2" }, "downloads": -1, "filename": "diff-pdf-visually-1.1.0.tar.gz", "has_sig": false, "md5_digest": "958ce26cbc5689420d8e5b24ed780086", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.0,<4.0", "size": 4901, "upload_time": "2018-09-05T23:19:39", "url": "https://files.pythonhosted.org/packages/50/ba/c493cfc2ad0c582c08dd9063c9ebe49f03856ef404da378b6fdcb0da14e5/diff-pdf-visually-1.1.0.tar.gz" } ], "1.2.0": [ { "comment_text": "", "digests": { "md5": "0f1a27b358fc18e10f1ab0ce18d92f2d", "sha256": "b21e038f80f36a64891373faa5351d1d931efeda645ae79c8d2c412fc444dc69" }, "downloads": -1, "filename": "diff_pdf_visually-1.2.0-py3-none-any.whl", "has_sig": false, "md5_digest": "0f1a27b358fc18e10f1ab0ce18d92f2d", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.0,<4.0", "size": 10645, "upload_time": "2018-09-05T23:27:47", "url": "https://files.pythonhosted.org/packages/11/cc/ae4944f72fd88aefc8c61b958b547e4df6cc454ea2038cf5d6410582786f/diff_pdf_visually-1.2.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "a52a56aac8218bb722aae2141e613dcd", "sha256": "992c6852e4f850352e1dce607c782a9c265b21a65558cdc026df5025495bbc3a" }, "downloads": -1, "filename": "diff-pdf-visually-1.2.0.tar.gz", "has_sig": false, "md5_digest": "a52a56aac8218bb722aae2141e613dcd", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.0,<4.0", "size": 5100, "upload_time": "2018-09-05T23:27:46", "url": "https://files.pythonhosted.org/packages/7d/3e/d88dcf7a0cbd939d96ab7c7d45d0842c36d6dcc47fbdb91eb1e2bedce3a7/diff-pdf-visually-1.2.0.tar.gz" } ], "1.2.1": [ { "comment_text": "", "digests": { "md5": "4b1a2d7989d4aab886e5e3770c5ccd58", "sha256": "a78f7f578b959ed6a89a78ec52c25695427fac348a38eda6dd74ac018ed9e61f" }, "downloads": -1, "filename": "diff_pdf_visually-1.2.1-py3-none-any.whl", "has_sig": false, "md5_digest": "4b1a2d7989d4aab886e5e3770c5ccd58", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.0,<4.0", "size": 11149, "upload_time": "2018-09-06T00:00:38", "url": "https://files.pythonhosted.org/packages/e5/94/194d16775f52f75f083d369c00d5f876c254acae85eba82d554096bf6d33/diff_pdf_visually-1.2.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "8d3d333b7a817bc17e32c0a6791e91cd", "sha256": "375642adc6440098888282d4b6a823e6c00809c2f731a2132e5829860344d096" }, "downloads": -1, "filename": "diff-pdf-visually-1.2.1.tar.gz", "has_sig": false, "md5_digest": "8d3d333b7a817bc17e32c0a6791e91cd", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.0,<4.0", "size": 5588, "upload_time": "2018-09-06T00:00:36", "url": "https://files.pythonhosted.org/packages/ee/d2/ef9a74dc0b8bc4adbc97f4d4eb4fd71c7ae3fea73af3e8d7dc597057a321/diff-pdf-visually-1.2.1.tar.gz" } ], "1.2.2": [ { "comment_text": "", "digests": { "md5": "404528ff641cc2a1261afa0c51cd2c30", "sha256": "a2b6e62ebe9b56fca9337feb74248ce39c7ef0c5b35e9ab6aa3fb1f5949cd93b" }, "downloads": -1, "filename": "diff_pdf_visually-1.2.2-py3-none-any.whl", "has_sig": false, "md5_digest": "404528ff641cc2a1261afa0c51cd2c30", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.0,<4.0", "size": 11649, "upload_time": "2018-09-06T12:04:46", "url": "https://files.pythonhosted.org/packages/92/ff/c1313c472db454b48f33e755d8aa53114525beb86cec2e45b309c10a463a/diff_pdf_visually-1.2.2-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "38d20493c22f5b46bfc5170bb6507ee2", "sha256": "59a6dd9599fc63544fce8034a80c53d51345d9db65ab048e8890ec0e33d17fe9" }, "downloads": -1, "filename": "diff-pdf-visually-1.2.2.tar.gz", "has_sig": false, "md5_digest": "38d20493c22f5b46bfc5170bb6507ee2", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.0,<4.0", "size": 5757, "upload_time": "2018-09-06T12:04:45", "url": "https://files.pythonhosted.org/packages/fa/51/4713649cf6d2d3e8a4660512235bb9ec1fe41e7d5dafa358ed1da3378f23/diff-pdf-visually-1.2.2.tar.gz" } ], "1.3.0": [ { "comment_text": "", "digests": { "md5": "d8b126fe0223cf2a9a3aea35075b9940", "sha256": "fc6d1cb3e28d22d6e29bde01406058325c4585b8763cf789f60391001bdad048" }, "downloads": -1, "filename": "diff_pdf_visually-1.3.0-py3-none-any.whl", "has_sig": false, "md5_digest": "d8b126fe0223cf2a9a3aea35075b9940", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.0,<4.0", "size": 12573, "upload_time": "2018-09-06T14:09:41", "url": "https://files.pythonhosted.org/packages/c4/e8/3f9c7460272d78310a5a493453e92284d9ad64e16c38a76dd84e6cfb1e78/diff_pdf_visually-1.3.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "f49a18e969d84562afdd08dbf053a89b", "sha256": "e6ed6169789c5651e566ce65944f1784a7fd5823f5bfcfbb3ff5692de5fe8fd2" }, "downloads": -1, "filename": "diff-pdf-visually-1.3.0.tar.gz", "has_sig": false, "md5_digest": "f49a18e969d84562afdd08dbf053a89b", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.0,<4.0", "size": 6010, "upload_time": "2018-09-06T14:09:40", "url": "https://files.pythonhosted.org/packages/3a/ae/79c9ba1cb8900959d1b1c4c7efd1044d28287a57214c4e8649035e7854b9/diff-pdf-visually-1.3.0.tar.gz" } ], "1.3.1": [ { "comment_text": "", "digests": { "md5": "7b21f6420a02b7563325ac128501d492", "sha256": "5c5ad5a34097a378f39f833dd195b2f5d83aa185ca0374374bbb4fb082feb3e6" }, "downloads": -1, "filename": "diff_pdf_visually-1.3.1-py3-none-any.whl", "has_sig": false, "md5_digest": "7b21f6420a02b7563325ac128501d492", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.0,<4.0", "size": 13228, "upload_time": "2018-09-06T16:38:05", "url": "https://files.pythonhosted.org/packages/82/51/b4214d48bdcadd19909b0c0249b650360b32b01e9e2606457727409bef41/diff_pdf_visually-1.3.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "8a4a97c10bd24eab75adeedbf9169f88", "sha256": "7f16ad3891c080f16ff98d296c7011b2cee4f72d161dcf008203d51ad01cc00b" }, "downloads": -1, "filename": "diff-pdf-visually-1.3.1.tar.gz", "has_sig": false, "md5_digest": "8a4a97c10bd24eab75adeedbf9169f88", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.0,<4.0", "size": 6213, "upload_time": "2018-09-06T16:38:03", "url": "https://files.pythonhosted.org/packages/fa/00/d53bf1663b1cbaac5c55b8c67c4985d4ebb56a5c563b0f48598b038558e4/diff-pdf-visually-1.3.1.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "7b21f6420a02b7563325ac128501d492", "sha256": "5c5ad5a34097a378f39f833dd195b2f5d83aa185ca0374374bbb4fb082feb3e6" }, "downloads": -1, "filename": "diff_pdf_visually-1.3.1-py3-none-any.whl", "has_sig": false, "md5_digest": "7b21f6420a02b7563325ac128501d492", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.0,<4.0", "size": 13228, "upload_time": "2018-09-06T16:38:05", "url": "https://files.pythonhosted.org/packages/82/51/b4214d48bdcadd19909b0c0249b650360b32b01e9e2606457727409bef41/diff_pdf_visually-1.3.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "8a4a97c10bd24eab75adeedbf9169f88", "sha256": "7f16ad3891c080f16ff98d296c7011b2cee4f72d161dcf008203d51ad01cc00b" }, "downloads": -1, "filename": "diff-pdf-visually-1.3.1.tar.gz", "has_sig": false, "md5_digest": "8a4a97c10bd24eab75adeedbf9169f88", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.0,<4.0", "size": 6213, "upload_time": "2018-09-06T16:38:03", "url": "https://files.pythonhosted.org/packages/fa/00/d53bf1663b1cbaac5c55b8c67c4985d4ebb56a5c563b0f48598b038558e4/diff-pdf-visually-1.3.1.tar.gz" } ] }