How to change DPI of a PNG file? (in command line, without ImageMagick)

9

I am looking for a way to change the DPI on PNG image files. Using ImageMagick this is easy:

$ convert -density 150 -units pixelsperinch file.png file.png

The problem is that I will run this command from my application, running on multiple VMs, which don't have ImageMagick installed. I can push the upgrade packages to these VMs, but in case of ImageMagick that would add about 30MB to an upgrade bundle, which is a bit too much for my use case.

Long story short: is there a way I can change the DPI on a PNG file using a small (as in package size) command-line tool?

Optionally, changing bytes in a raw image file would be okay too, if someone knows where to look for them...

johndodo

Posted 2013-09-18T07:42:15.840

Reputation: 269

You might consider doing your own implementation. Manipulating the PNG chunks is straight-forward enough. If you only intend to apply one particular DPI to all of them, you don't even need to have a working checksum function - just copy a pre-made pHYs chunk from a PNG made in Photoshop. – Zdenek – 2017-04-22T20:41:26.630

Answers

6

Is 2.10 MB small enough? If yes, use NConvert and a batch command like:

nconvert -out png -dpi 150 -keepdocsize -keepfiledate mysource.png

What is NConvert for?

XnView is a GUI-based application, you can change and manipulate images using a graphical user interface. NConvert has about the same capabilities as XnView, but it is a command line tool and has no graphical user interface. You can use NConvert in Batch scripts or another application can call it.

Helpful links

  • Beginner guide and Wiki with some examples to start
  • Help file to see what command line parameters are available (Uploaded on pastebin)
  • A graphical front-end using Nconvert is XnConvert. Use this to create & export Nconvert batch files
  • Forum for Xnconvert and Nconvert for

nixda

Posted 2013-09-18T07:42:15.840

Reputation: 23 233

Thanks, looks great and will probably come handy in the future! In this case I ended up studying PNG format (which was fortunately simple enough) and changing the images through a small custom app (15 lines in PHP). – johndodo – 2013-09-25T08:22:00.317

@johndodo This sounds interesting. May you want to share your application with us? – nixda – 2013-09-25T08:59:05.397

Unfortunately I am not at liberty to do that, but you can do the same by reading a (great!) specification of PNG file format and making an app that changes the pHYs chunk. It really is simple once you know what you are doing.

– johndodo – 2013-10-16T12:31:43.750

1

You mentioned you would be running this command "from your application," and this leads me to believe that you have written this application, or are maintaining it. That said, there are ImageMagick API's for several languages, and you could use one of them to add the functionality right into your existing program. The increase in package size would depend on what language your application is written in and whether you link the library statically or dynamically, but I would imagine it would be significantly smaller than a 30 MB increase.

Another option is not to include the entire ImageMagick package. You can download the ImageMagick Zip file (which is only 13 MB BTW), and extract just the convert tool and it's dependencies and distribute that to your VM's. There is a tool called Dependency Walker that you can use to determine what the dependencies of the convert tool are.

Drew Chapin

Posted 2013-09-18T07:42:15.840

Reputation: 4 839

1

Use the -size flag in the netpbm pnmtopng program. The units used are pixels per meter. The following example will set newfile.png to 300dpi.

pngtopnm <oldfile.png | pnmtopng -size='11811 11811 1' >newfile.png

Diomidis Spinellis

Posted 2013-09-18T07:42:15.840

Reputation: 532

0

The proper Image Magick "convert" command line for this would be to use the -resample argument:

convert image.png -resample 150x150 -units pixelsperinch ../ImagesAdjusted/image.png

tolistim

Posted 2013-09-18T07:42:15.840

Reputation: 1

0

Well, you could potentially use a python script.

#!/usr/bin/python
im = Image.open("in.png")
nx, ny = im.size
im2 = im.resize((int(nx*1.5), int(ny*1.5)), Image.BICUBIC)
im2.save("out.png")

Source.

Goncalo

Posted 2013-09-18T07:42:15.840

Reputation: 109

The Python 3.3.2 installer (not including source code) is 19.3 MB, and the Python 2.7.5 installer is 15.5 MB. – Drew Chapin – 2013-09-27T09:39:41.510

5That will resize the image, not change the DPI. – Bobby – 2013-09-27T10:54:17.037