The trick here is to increase the density(resolution) of the original image before doing any other processing like resizing or rotating.
% convert -density 300 inputfile.png inputfile.png
Normally, it would be necessary to specify the units (-units PixelsPerInch
or -units PixelsPerCentimeter
) along with density, but since PNG files only use the pixels /cm unit, it's not necessary here.
The reason we have to do this is because to resize an image, it must pass through one (or more) of several filters (algorithms). With a low resolution (like 72 dpi for printing) there simply isn't enough data for the algorithms to use for their calculations. ImageMagick has a lenghthy section on resizing and the different filters you can use and how they work: https://legacy.imagemagick.org/Usage/resize/#other. Unfortunately, none worked well enough until I realized that the data in the image was just too "thin."
By doing nothing other than increasing the density we're essentially giving the same element (a single bar code line for example) more data points to work with when we do manipulate the image later on. The more it has, the more accurate it can be though the trade off is speed. It will take longer to process.
By doing this first and then manipulating the image, I was able to achieve a crisp and clear image at the size I needed for printing on my laser printer. The other option I had was to purchase a dedicated label printer (like the Zebra or Brother printers) so I could use the high quality PDF they supplied.
Below is a more step-by-step process of how to manipulate the image to get the desired result
If we look at the resolution of the original image file (identify -ping -verbose image.png | head
) we see that it's set for a resolution of 28.35x28.35 ppcm and a print size of 42.328cm x 63.4921cm (16.66" x 25").
Filename: sample_label_orig.png
Format: PNG (Portable Network Graphics)
Mime type: image/png
Class: PseudoClass
Geometry: 1200x1800+0+0
Resolution: 28.35x28.35
Print size: 42.328x63.4921
Units: PixelsPerCentimeter
Colorspace: Gray
Since everything is metric, to convert to inches, multiply by 2.54. 28 ppcm translates to 72 ppi (or 72 DPI). This is supposedly the correct DPI for printing.
You can use the same filename for both input and output so it makes the changes "in place." I'm using a separate file for this example.
% convert -density 300 sample_label_orig.png sample_label.png
When the density/resolution is increased to 300 ppcm, everything falls into place. However, don't be fooled by the new print size though; it's 4cm x 6cm not 4" x 6"!
Filename: sample_label.png
Format: PNG (Portable Network Graphics)
Mime type: image/png
Class: PseudoClass
Geometry: 1200x1800+0+0
Resolution: 300x300
Print size: 4x6
Units: PixelsPerCentimeter
Colorspace: Gray
Now, instead of resizing the label, we simply specify the new label geometry. Note that geometry not the print size of the label. It's the dimensions of the label multiplied by the density. So, a 4x6 inch label would be 10.16x15.24 cm meaning the final geometry would be 300*(10.15x15.24) = 3048x4572.
% convert sample_label.png -geometry 3048x4572 label_out.png
Now, when we look at the details of the label (identify -ping -verbose label_out.png | head
), everything is as it should be. It's a 4x6 inch label (converted from cm) with a 300 ppcm resolution
Filename: label_out.png
Format: PNG (Portable Network Graphics)
Mime type: image/png
Class: PseudoClass
Geometry: 3048x4572+0+0
Resolution: 300x300
Print size: 10.16x15.24
Units: PixelsPerCentimeter
Colorspace: Gray
We can even rotate the label at the same time we change the geometry to make the process more efficient.
% convert sample_label.png -geometry 3048x4572 -rotate -90 label_out.png
This will create a crisp and clear label in the correct orientation to be printed on the laser printer.