Get Resolution (dpi) and physical dimensions, in mm of any image file.

Hi, I have a script that, using sips, gets the dpi of an image file (tiff, jpeg, pdf, eps, etc.). Then works out the physical dimensions in millimeters (rounded up or down).

Not sure if anyone will find this useful, but this works without having to rely on any other application to achieve this. (Photoshop or similar).

set source_file to choose file
set type to paragraph 2 of (do shell script "GetFileInfo " & quoted form of POSIX path of source_file & " | cut -d'\"' -f2")

-- sips does not work on eps files so we have to convert to pdf, save as a temp file on the Desktop, then delete it (by default this will create a 150dpi pdf!)
if type contains "EPSF" then
	set epsSaved to do shell script "/usr/bin/pstopdf " & quoted form of POSIX path of source_file & " -o ~/Desktop/tmp.pdf"
	set Res to paragraph -1 of (do shell script "sips -g dpiHeight ~/Desktop/tmp.pdf | awk '/dpiHeight:/ {print $NF}'")
	set dimensions to paragraphs -2 thru -1 of (do shell script "sips -g  pixelHeight -g  pixelWidth ~/Desktop/tmp.pdf | awk '/pixel/ {print $NF}'")
	delay 0.1
	do shell script "rm ~/Desktop/tmp.pdf"
	set Res to round Res
	
else
	set Res to paragraph -1 of (do shell script "sips -g  dpiHeight -g  dpiWidth " & quoted form of POSIX path of source_file & " | awk '/dpi/ {print $NF}'")
	--end if
	set Res to round Res
	set dimensions to paragraphs -2 thru -1 of (do shell script "sips -g  pixelHeight -g  pixelWidth " & quoted form of POSIX path of source_file & " | awk '/pixel/ {print $NF}'")
	
end if
set dpi_to_dpmm to Res / 25.4 -- converts dots per inch to dots per mm
set h to round (item 1 of dimensions) / dpi_to_dpmm -- works out pixel height as mm
set w to round (item 2 of dimensions) / dpi_to_dpmm -- works out pixel width as mm

display dialog "Resolution of this file is : " & Res & "dpi" & return & return & "Image is " & h & "mm h x " & w & "mm w (Approx!)"

The only problem I can see with this is the fact that, because sips does not work with eps files, I have had to convert all eps’s to pdf’s with ‘pstopdf’ and, by default, this produces 150dpi pdfs regardless of how the pdf was generated initially, but it does still give the dimensions of the pdf!

This is exactly was I am looking for but I get an error when I try this script. I tried it in OS X 10.5 and 10.7

AppleScript error
error “Can not get paragraph -2 of "".” number -1728 from paragraph -2 of “”

Hi Anders,

Do you get anything with this:-

set source_file to choose file
set dimensions to paragraphs of (do shell script "sips -g  pixelHeight -g  pixelWidth " & quoted form of POSIX path of source_file & " | awk '/pixel/ {print $NF}'")

This should just return the dimensions in pixels!

Run the above script in script editor and the results should be displayed below.

Does this make a difference?

set source_file to choose file
set type to (do shell script "GetFileInfo " & quoted form of POSIX path of source_file & " | cut -d'\"' -f2")

-- sips does not work on eps files so we have to convert to pdf, save as a temp file on the Desktop, then delete it (by default this will create a 150dpi pdf!)
if type contains "EPSF" then
	set epsSaved to do shell script "/usr/bin/pstopdf " & quoted form of POSIX path of source_file & " -o ~/Desktop/tmp.pdf"
	set Res to paragraphs of (do shell script "sips -g  dpiHeight -g  dpiWidth " & quoted form of POSIX path of source_file & " | grep dpiHeight | cut -d ':' -f 2 | cut -d ' ' -f 2")
	set dimensions to paragraphs of (do shell script "sips -g  pixelHeight -g  pixelWidth " & quoted form of POSIX path of source_file & " | grep pixel | cut -d':' -f 2 | cut -d ' ' -f 2")
	delay 0.1
	do shell script "rm ~/Desktop/tmp.pdf"
	set Res to round Res
	
else
	set Res to paragraphs of (do shell script "sips -g  dpiHeight -g  dpiWidth " & quoted form of POSIX path of source_file & " | grep dpiHeight | cut -d ':' -f 2 | cut -d ' ' -f 2")
	--end if
	set Res to round Res
	set dimensions to paragraphs of (do shell script "sips -g  pixelHeight -g  pixelWidth " & quoted form of POSIX path of source_file & " | grep pixel | cut -d':' -f 2 | cut -d ' ' -f 2")
	
end if
set dpi_to_dpmm to Res / 25.4 -- converts dots per inch to dots per mm
set h to round (item 1 of dimensions) / dpi_to_dpmm -- works out pixel height as mm
set w to round (item 2 of dimensions) / dpi_to_dpmm -- works out pixel width as mm

display dialog "Resolution of this file is : " & Res & "dpi" & return & return & "Image is " & h & "mm h x " & w & "mm w (Approx!)"

Hi

Thanks, this example works.

I figured out that I can use the number 6.096 instead of 25.4 to get the image size at 300 dpi (magazine print).

Some tabloid papers use only 170 dpi so it would be nice to have the dialog show these measurements too, like this.

Image size at 300 dpi : 67x103 mm
Image size at 170 dpi : 119x179 mm

How can I add another calculation?

Hmm, I see now that my idea only works if the image is 72 dpi.

The script takes the dpi from the selected file and the width and height in pixels. Dividing the dpi by 25.4 gives dots per mm. I can then divide width and height by dpmm to return pixels as mm!

If you then wanted to work out mm at a different resolution, this may work:

take current resolution (300) divide by desired resolution (170) = 1.7647058 then multiply each of the dimensions by this number.

So in your example 300dpi image with dimensions of 67x103

300/170 = 1.7647058
67 x 1.7647058 = 118.23528
103 x 1.7647058 = 181.76469

Gives 170dpi with dimensions of 118 x 182mm

Not sure if this helps?

If you wanted to actually change the dpi, then sips can do this:

sips -s dpiHeight 170.0 -s dpiWidth 170.0 original.jpg --out resampled.jpg

(this would be a ‘do shell script’ in Applescript and original.jpg would probably be a variable as would resampled.jpg!!)

The problem is this.

If I open a 300 dpi image the measurements shown in mm are already correct. They need no more calculation.

But if I open a 72 dpi image it will need another round of calculation to show the corresponding measurements at 300 dpi.

How can the script know if it should calculate or not?

Am I making sense?

Hi Anders,

The script does not know if to calculate or not! I never intended it to calculate effective resolution at a dpi other than what it reads form the file.

Basically, it reads the dpi of the file then calculates the dimensions in mm based on the physical dpi.

I guess you could add another part that asks the user to input a desired dpi, then calculate what the dimensions would be based on that input (this is the same as changing the resolution in Photoshop and NOT resampling!!)

I think I assumed that it had to do with calculations for print. I just don’t know of a case where the measurements of a 72 dpi image in mm would be of interest?

I see these two cases
72 dpi for web or ppt-presentations: how many pixels is it?
72 dpi to be used for printing purposes: how many mm will it be at 170 or 300 dpi?

Hi Anders,

I am happy for you (or anyone) to take this script as a starting point, to then add further functionality to either inform the user of dimensions if the image was to be resampled to a different dpi, or ask for a desired dpi, then using the calculations I gave in an earlier post, have sips actually resample the image.

If I get time, I may even have a crack at this myself! If I come up with anything I’ll post it here.

Steve.

OK, didn’t take as long as I anticipated!!

The below script reads the dpi and dimensions in mm, (as previously) but now asks the user to input a new dpi to resample the original image to, and saves the resulting file in the same location as the original, adding ‘resampled_’ to the beginning of the filename.

set source_file to choose file
set type to (do shell script "GetFileInfo " & quoted form of POSIX path of source_file & " | cut -d'\"' -f2")

-- sips does not work on eps files so we have to convert to pdf, save as a temp file on the Desktop, then delete it (by default this will create a 150dpi pdf!)
if type contains "EPSF" then
	set epsSaved to do shell script "/usr/bin/pstopdf " & quoted form of POSIX path of source_file & " -o ~/Desktop/tmp.pdf"
	set Res to paragraphs of (do shell script "sips -g  dpiHeight -g  dpiWidth " & quoted form of POSIX path of source_file & " | grep dpiHeight | cut -d ':' -f 2 | cut -d ' ' -f 2")
	set dimensions to paragraphs of (do shell script "sips -g  pixelHeight -g  pixelWidth " & quoted form of POSIX path of source_file & " | grep pixel | cut -d':' -f 2 | cut -d ' ' -f 2")
	delay 0.1
	do shell script "rm ~/Desktop/tmp.pdf"
	set Res to round Res
	
else
	set Res to paragraphs of (do shell script "sips -g  dpiHeight -g  dpiWidth " & quoted form of POSIX path of source_file & " | grep dpiHeight | cut -d ':' -f 2 | cut -d ' ' -f 2")
	--end if
	set Res to round Res
	set dimensions to paragraphs of (do shell script "sips -g  pixelHeight -g  pixelWidth " & quoted form of POSIX path of source_file & " | grep pixel | cut -d':' -f 2 | cut -d ' ' -f 2")
	
end if
set dpi_to_dpmm to Res / 25.4 -- converts dots per inch to dots per mm
set h to round (item 1 of dimensions) / dpi_to_dpmm -- works out pixel height as mm
set w to round (item 2 of dimensions) / dpi_to_dpmm -- works out pixel width as mm

set resample to text returned of (display dialog "Resolution of this file is : " & Res & "dpi" & return & return & "Image is " & h & "mm h x " & w & "mm w (Approx!)" & return & "What dpi do you want to resample to?" default answer "300")

set nameOnly to do shell script "basename " & quoted form of POSIX path of source_file
set destinationPath to do shell script "dirname " & quoted form of POSIX path of source_file

do shell script "sips -s dpiHeight " & resample & ".0 -s dpiWidth " & resample & ".0 " & quoted form of POSIX path of source_file & " --out " & destinationPath & "/resample_" & nameOnly

THIS WILL NOT WORK WITH EPS FILES, AS THEY ARE NOT COMPATIBLE WITH SIPS!!

I guess another nice addition would be for the script to first calculate what the final dimensions would be, then ask the user if they wish to continue.

  1. For those who want to use your code: the reserved word type must be replaced by |type|.
  2. EPS files are not images, so sips is not required to work with them. Is appropriate here to limit the choice of the user to the selection of images only. Then you don’t need a lot of extra code.
  3. As you noticed, it is better to give the user the opportunity to leave the image as is:

set source_file to quoted form of POSIX path of (choose file of type {"public.image"})

set Res to round (paragraphs of (do shell script "sips -g  dpiHeight -g  dpiWidth " & ¬
	source_file & " | grep dpiHeight | cut -d ':' -f 2 | cut -d ' ' -f 2"))
set dimensions to paragraphs of (do shell script "sips -g  pixelHeight -g  pixelWidth " & ¬
	source_file & " | grep pixel | cut -d':' -f 2 | cut -d ' ' -f 2")

set dpi_to_dpmm to Res / 25.4 -- converts dots per inch to dots per mm
set h to round (item 1 of dimensions) / dpi_to_dpmm -- works out pixel height as mm
set w to round (item 2 of dimensions) / dpi_to_dpmm -- works out pixel width as mm

set resample to text returned of (display dialog "Resolution of this file is :  " & Res & ¬
	"dpi" & return & return & "Image is: about   " & h & " mm (height) x " & w & "mm (width)" & ¬
	return & return & "Set dpi if you want to resample image." & return & ¬
	"ELSE, press \"OK\"" default answer (Res as text))

if resample ≠ (Res as text) then
	set nameOnly to do shell script "basename " & source_file
	set destinationPath to do shell script "dirname " & source_file
	try
		do shell script "sips -s dpiHeight " & resample & ".0 -s dpiWidth " & resample & ".0 " & source_file & " --out " & destinationPath & "/resample_" & nameOnly
	on error
		display dialog "Something went wrong." & return & return & ¬
			"Most likely, you specified the wrong dpi."
	end try
end if