Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Use indexed color for PNG images in PDF files when possible #17895

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jul 14, 2020
Merged

Use indexed color for PNG images in PDF files when possible #17895

merged 5 commits into from
Jul 14, 2020

Conversation

mpetroff
Copy link
Contributor

@mpetroff mpetroff commented Jul 12, 2020

PR Summary

This pull requests modifies the PDF backend to use indexed color for PNG images in PDF files when possible.

When PNG images have 256 colors or fewer, it converts them to indexed color before saving them in a PDF. This can result in a significant reduction in file size in some cases. The is particularly true for raster data that uses a colormap but no interpolation, such as Healpy mollview plots (for some of the maps I tested, the new PDFs are less than half the size).

Currently, this is only done for RGB images. For grayscale images with 128 colors or fewer, there should also be an improvement, since this allows for 4-bit indexed color (or lower) instead of 8-bit grayscale. However, Pillow seems to always use 8-bit indexed color, so there's no improvement in practice. Edit: The PDF specification requires that soft-mask images must use the DeviceGray color space, so they can't be indexed color; this would further complicate extending indexed color to grayscale images, since the PDF backend uses soft-masks.

PR Checklist

  • [Existing PDF tests should cover this] Has Pytest style unit tests
  • Code is Flake 8 compliant
  • [Not applicable] New features are documented, with examples if plot related
  • [Not applicable] Documentation is sphinx and numpydoc compliant
  • [Not applicable] Added an entry to doc/users/next_whats_new/ if major new feature (follow instructions in README.rst there)
  • [Not applicable] Documented in doc/api/next_api_changes/* if API changed in a backward-incompatible way

mpetroff added 3 commits July 12, 2020 02:16
When PNG images have 256 colors or fewer, convert them to index color before
saving them in a PDF. This can result in a signifcant reduction in file size.
It seems to cause problems with images used for alpha transparency. It also
doesn't have any benefit, since Pillow seems to always use 8-bit indexed
color, even when 1-, 2-, or 4-bit indexed color is possible.
PNGs separate large images into chunks, but PDFs do not.
@mpetroff
Copy link
Contributor Author

The test failure seems to be due to an inconsistency in how the PDF to PNG conversion is done for the tests, with regard to indexed color. The difference image shows ten pixels that differ, but flipping through the two PDFs shows no visible differences. Furthermore, if I convert the PDFs to PNGs using mutool instead of gs, the images are identical.

@timhoffm
Copy link
Member

The difference image only differs in single pixels.

grafik

This is some kind of subpixel calculation issue. It's ok to slightly increase the tolerance for the test @image_comparison(..., tol=...) to make it pass.

@tacaswell
Copy link
Member

I am 👍 on adding to the tolerance here and leaving a note in the tests as to why. Given that we have work going to move away for storing the baseline images in the repository (and instead generate them from the previous commit / external package) it is probably not worth re-generating the pdf.

We also do our pdf comparison at a pretty low DPI, that may also be part of the problem here.

@tacaswell tacaswell added this to the v3.4.0 milestone Jul 12, 2020
Copy link
Member

@tacaswell tacaswell left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Modulo an explanatory comment on the test justifying the large error and noting that it is only needed for the pdf test.

There are ten pixels that differ due to how the subpixel calculation is done.
@mpetroff
Copy link
Contributor Author

I added a comment about the tolerance.

I think it's a combination of the low resolution and the fact that Ghostscript doesn't seem to be doing subpixel interpolation; instead of a slight change in value, the change is drastic when it happens. I see a similar issue with one of the tests for the PGF backend when I run the test suite locally.

@jklymak jklymak merged commit be2e5d7 into matplotlib:master Jul 14, 2020
@jklymak
Copy link
Member

jklymak commented Jul 14, 2020

The Azure MacOS job has been quite flaky. I think we can merge on two approvals. I'll merge, though I've not carefully looked at this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants