Skip to content
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

The doc.image() method must scale image by 72/96 to automatically convert pixels to points. #1266

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

adrift2000
Copy link
Contributor

What kind of change does this PR introduce?

Since image sizes are specified in pixels and PDFKit uses point units, the doc.image() method must scale image by 72/96 to automatically convert pixels to points.

For example the image is 50x50 pixels and we draw it in actual size:

  doc.image('test.png', 0, 0);

and then draw a rectangle of the same size over the image:

  doc.rect(0, 0, 37.5, 37.5) // 37.5pt = 50px
     .stroke()

Expected: The image and the rectangle must be the same size.
Actual: The image is bigger then the rectangle.

Checklist:

  • Unit Tests
  • Documentation
  • Update CHANGELOG.md
  • Ready to be merged

@v-python
Copy link

Does this account for images that have DPI specified in their metadata? Or does it assume every image has 96dpi?

@adrift2000
Copy link
Contributor Author

adrift2000 commented Jun 23, 2021

Does this account for images that have DPI specified in their metadata? Or does it assume every image has 96dpi?

It doesn't account for DPI in metadata and assumes the image sizes in device-independent pixels, 1/96 inch.
It is more correct behavior than the current one, which assumes that 1 pixel = 1 point = 1/72 inch,

@blikblum
Copy link
Member

@liborm85 can you look at this?
May affect pdfmake

@liborm85
Copy link
Collaborator

pdfmake always passes options parameter with width and height, therefore change is not a problem.

@v-python
Copy link

Older monitors had pixels that were 1/72". Most new monitors do, indeed, use 1/96" pixels, or smaller, and the term "pixel" is defined in Web browsers to effectively be 1/96", so assuming 1/96" pixels is perhaps slightly more correct today than it was 15 years ago, but it would be far better to use the image metadata to define the overall size of the image, which, from other comments, is what pdfmake appears to do, and which could/would provide correct results. I have no problem with assuming either 1/72" or 1/96" pixel size for images that have no metadata declarations.... if the image doesn't say what it is, you get something.... One could make the assumption that BMP file format uses 1/72" pixels, since that was the standard monitor pixel size when it was invented. Other image formats generally have a DPI specification that can be used.

@adrift2000
Copy link
Contributor Author

adrift2000 commented Jun 24, 2021

@v-python

Older monitors had pixels that were 1/72"

It may be true for some specific monitors only.
AFAIK, 72 dpi was introduced by Apple, because some of their Macs in 1980s had 9" monitors with a fixed resolution of 512x384. With aspect ratio of 4:3 it gives us 512/7.2 = ~71 dpi.

One could make the assumption that BMP file format uses 1/72" pixels, since that was the standard monitor pixel size when it was invented

BMP was introduced by Microsoft in 1987 or earlier.
AFAIR a typical PC of the late 1980s had 14" monitor with CGA/EGA adapter and various display resolutions from 320x200 (~28 dpi) to 640×350 (~57 dpi).

Microsoft defines device-independent pixel as 1/96" since Windows 95 at least.

@blikblum
Copy link
Member

Other image formats generally have a DPI specification that can be used.

Can you provide images with and without metadata so we can do some tests. See how other libraries/apps handles that

@v-python
Copy link

v-python commented Jun 24, 2021

72 dpi was introduced by Apple,

Maybe so. Apple introduced Postscript too, the predecessor to PDF. So there is maybe a long and appropriate history for pixel = 1/72" in Postscript and PDF tools, for images without metadata! Seems I had some DOS and Windows 3 monitors with 1/72" pixels at one point, I never had an Apple of any sort.

Can you provide images with and without metadata so we can do some tests. See how other libraries/apps handles that

I'll attach a couple, but I'll point out that the IrfanView program (free download for Windows) has an easy way to read and modify the DPI setting for any of the many image formats it supports, which include TIFF & JPG which are the most common formats. So it is trivial to make and adjust images to have various DPI settings.

Looks like even BMP supports a DPI settings these days, so I'll stick with it, supplying a random small image in "original" format with no DPI setting, and then with 72, 96, and 200 dpi. Same exact image, just the DPI is different.
1-samples.zip

@fstrube
Copy link

fstrube commented Aug 13, 2021

Is there any concern with backwards compatibility?

Why isn't the default assumption of 72dpi for images acceptable? As I understand it, there is a difference between dots per inch (dpi) for print output and pixels per inch (ppi) for screens.

In printing, DPI (dots per inch) refers to the output resolution of a printer or imagesetter, and PPI (pixels per inch) refers to the input resolution of a photograph or image. Source

96ppi as a default is derived from common screen pixel density, not necessarily a standard, right? I don't think that the input resolution of an image should, by default, affect how it is placed in the PDF document.

I'm wondering if the behavior should be triggered by a new option on the .image() function rather than being a default. Something like dpi: 96 for instance. Or dpi: 'inherit' if you want to inherit the DPI from image metadata. That way it won't break the current behavior, but will still allow for DPI to be set.

@liborm85
Copy link
Collaborator

DPI change via configuration sounds reasonable to avoid BC.

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

Successfully merging this pull request may close these issues.

None yet

5 participants