Fanning Software Consulting

Interpolated Images in PostScript

Facebook Twitter RSS Google+

QUESTION: It appears the Interpolate keyword to cgImage is broken when outputting to the PostScript device. Consider the two images shown below. I used the same command to produce both figures:

   cgImage, image, /Interpolate

The image on the left is what is displayed in my graphics window. The image on the right is what is created in my PostScript file when I run the same code. Clearly the PostScript image is more pixelated and looks like it is displayed with a lower resolution. Can you fix this?

Display image. PostScript image.
The display image on the left and the PostScript image on the right.
 

ANSWER: In fact, the Interpolate keyword is not broken. What you see here is an artifact of the way images are resized in the PostScript device.

A pixel in PostScript is scaleable (it can be stretched) in both directions. Pixels on the display, of course, cannot change their size or shape. So, if you want to visualize an image that is, say, 64x64 and display it at a resolution of 400x400 on your display, you have to size the image (by creating more pixels) to do so. In your case, you are asking cgImage to resize the image with interpolation. Internally, the code looks something like this.

   displayImage = Congrid(image, 400, 400, /Interp)
   TV, displayImage

But, this is not how PostScript images are resized. To make the PostScript image take up the same amount of space in the PostScript "display," you simply scale or stretch the pixels in the original image to the correct size. In this hypothetical case, 400 pixels might be represented by four inches in Postscript. (PostScript units are expressed in inches and centimeters, not pixels!). The internal cgImage code looks something like this.

   TV, image, XSize=4, YSize=4, /Inches 

As you can see, there is no interpolation involved. And, since your image doesn't have much native "resolution", it appears blocky in PostScript. One "solution" to this problem would be to resize your image, with interpolation, before you send it to PostScript. The code you use may look something like this.

   IF !D.Name EQ 'PS' THEN BEGIN
      dims = Size(image, /Dimensions)
      displayImage = Congrid(image, dims[0]*5, dims[1]*5, /Interp)
   ENDIF

I should warn you, though, that interpolation creates values in your display image that do not exist in the original image. Many scientists (astronomers and people doing remote sensing, in particular) hate image interpolation, because they don't want these kinds of artifacts in their data. This is why the default for cgImage is to do nearest neighbor interpolation of pixels when the image size needs to change. This makes sure only original image values are in the resized image. I would use the Interpolate keyword with a great deal of trepidation.

Version of IDL used to prepare this article: IDL 8.2.3

Written: 12 December 2013