0

Ultimately, I'm trying to determine the size of an image in inches so I can be certain it lays out properly on the printer.

If I use the command identify document.pdf I get the following output:

document.pdf PDF 612x792 612x792+0+0 16-bit sRGB 29289B 0.000u 0:00.000

If I divide 612 and 792 each by 72 respectively, I get 8.5x11 which tells me the size. I know this is correct because I printed it. The problem is, it's not always going to be 8.5x11 nor will the DPI always be the same (and I won't be there to "know" how it was printed/saved).

From ImageMagic's page on using Identify they have a -verbose output flag and an example of "calculating an image size at 72 DPI" but they don't say how they got the DPI!

How can I programmatically determine the DPI of an image?

(Graphics are bit out of my wheelhouse and with the sheer volume of ImageMagick's options along with terms I'm not familiar with is a bit like drinking from the fire hose.)

14
  • 1
    DPI may be embedded in a document, but doesn't have to be. Strictly speaking, an image doesn't have a dpi until it's laid out on a printable document or actually printed, all it has is dimensions in pixels. [This type of question crops up a lot on photography/graphic design sites, because there is an insane amount of 'interwebz wisdom' that gets it wrong.] – Tetsujin Apr 20 '20 at 15:38
  • 1
    there is an insane amount of 'interwebz wisdom' that gets it wrong.]. ← This, @Tetsujin Add this to list of universal constants like the force due to gravity and the speed of light. – Allan Apr 20 '20 at 15:42
  • Yeah. tbh, I don't know image magick at all so I probably can't help with specifics, but just generally, if your image is 1000x1000 & DPI is 100 it will print at 10". If you print that on a bigger sheet, you don't change the image at all, you just print it at a lower DPI. It really is a 'stretch-or-shink-to-fill' structure, very flexible to an actual print output. Pagination software may care, but nothing else does. – Tetsujin Apr 20 '20 at 15:45
  • So, the DPI changes?! Oy vey. The next step is to crop the image so that it's no bigger than 6" because I have to combine it with another image and put it all on an 8.5"x11" shipping label. I have no idea how to account for that mysterious variable. – Allan Apr 20 '20 at 16:04
  • If you are using a single image as a 'repetitive task' you should be able to save it from even Gimp etc with a 'known' dpi for your pagination software. Alternatively [again very dependant on what you are paginating in] you could just tell it to "fill this box with this image, fill that box with that one, allow overlap with this one on top, + transparency" – Tetsujin Apr 20 '20 at 16:09
1

(Thanks to Tetsujin for his helpful comments leading me to the answer)

ImageMagick can get a little confusing with their myriad of options when you're attempting to do something. There's a couple of ways that you can find out the DPI of an image. Both of them use the identify command.

For the examples below, I'm using a sample, royalty free photo of an Apple iMac saved natively as a JPG and exported as a PNG.

  • Manually calculating the size. To do this, we need two pieces of information, the resolution and the Units. In this case, we lucked out because the the units are in PPI (pixels per inch) so the resolution makes sense - it's 72 PPI or 72 DPI

    identify -verbose apple_photo.jpeg | grep -E -i "resolution|units"                         
    Resolution: 72x72
    Units: PixelsPerInch
    

    However, if the image file is a PNG, things are stored as PPCM or pixels per centimeter. Issuing the same command:

    % identify -verbose apple_photo.png | grep -E -i "resolution|units"
      Resolution: 28.34x28.34
      Units: PixelsPerCentimeter
    

    This tells us that it's 28.34 PPCM. To get DPI we have to do a little calculation. 1in = 2.54cm, so to get DPI we multiply that to the resolution as follows:

    2.54 * 28.34 = 71.9836 or 72DPI
    


  • Real-time Calculation. Again, using JPEG, we know that it's resolution is in DPI, so we just need to get the resolution value using the -format flag and the the percent (%) escape sequences:

    identify -format "%[fx:resolution.x]" apple_photo.jpeg
    

    Since PNG files are in PPCM, we can use the calculated FX expressions and the percent (%) escape sequences, to calculate this value. Here, we're getting the resolution value and multiplying it by 2.54 to get DPI.

    % identify -format "%[fx:resolution.x*2.54] DPI" apple_photo.png
    71.9836 DPI
    

    Note: You can get the units using the %[units] escape sequence here:

    % identify - identify -format `"%[units]"` apple_photo.jpeg
    

Calculate the size. We can now calculate the size (inches) of the image. Here, we use the %[w] escape sequence to get the width in DPI or PPCM

    % identify -format "%[fx:w]" apple_photo.jpeg
    3004

Divide by 72 to get inches

    % identify -format "%[fx:w/72] inches" apple_photo.jpeg
    41.7222 inches
0

This question really holds two separate questions:

First the question is of the DPI of a document, and the file in question is a PDF file. PDF files are complicated in nature, and actually allows a single document to hold objects of varying DPIs.

So even though the PDF specifies a DPI for the document itself, this means that it doesn't always make sense to programmatically determine the DPI of a document, simply because there doesn't have to be one single DPI for all of the document's contents.

The command given in the question reads out numbers for the PDF document itself, but rather you want to get the information about the actual image object inside the PDF like this:

pdfimages -list document.pdf

This will list the number of pixels per inch for each image object contained within the document in the "x-ppi" and "y-ppi" columns.

If the PDF files always contain a single image, you can read out the PPI from this command as the way to programmatically obtain the PPI. Note that it might differ from the value you have from identify for the PDF document as a whole, even though the file contains just a single image.

Secondary the question is about images in general - no file formats listed. Some of the most common file formats for images are JPEG and PNG files, which are simpler than PDF files.

For PNG files, the DPI is embedded in the pHY chunk that describes the physical pixel dimensions for the image. The DPI is allowed to be either unspecified, or specified in terms of an integer number of pixels per meter. Note - it is not stored in pixels per inch or pixels per centimeter, but rather as pixels per meter. This has implications for the precision of the values.

For JPEG files, the DPI is embedded in the JFIF APP0 marker segment that describes the X and Y density of the image as integers. The unit is similarly described in that segment as either unspecified, pixels per inch or pixels per centimeter.

So some JPEG files will have their density specified in pixels per inch, and others as pixels per centimeters.

In both cases you can use identify to extract the DPI information from the files:

identify -units PixelsPerInch -format '%[resolution.x] x %[resolution.y] %[units]' file.png
identify -units PixelsPerInch -format '%[resolution.x] x %[resolution.y] %[units]' file.jpeg

Note that in this case we ask ImageMagick to convert the actual density information to pixels per inch instead of some times getting the value as pixels per centimeter, and some times as pixels per inch. ImageMagick does not support getting the numbers in their native unit, as only those units can be output by the program - and for example PNG files store it as pixels per meter (as described above) - so a conversion takes place in those cases anyways.

Final, and probably most important note: For bitmap images, such as JPEG and PNG files, the actual image data is "DPI agnostics". Meaning that if you change the DPI of the file from for example 72x72 to 200x200, the actual image data does not change at all. The density information is just a metadata field in the file, and it does not as such affect the actual image data. It only comes into play when printing the image on physical paper.

What this means is that when processing "random images" for different sources, there's a high risk that the DPI information in the image is just some default value from the image processing software used. This means that you'll often see 72x72 DPI, but the value has no relation to the actual image data or how large the creator of the image actually thought it would be in the physical world (if he/she thought anything about that at all). Therefore it is typical not a good idea to rely on the DPI information for such "random images".

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .