Displaying a Transparent PNG Image
QUESTION: I have a logo in the form of a transparent PNG image that I would like to display in a graphics window. The image itself is dimensioned [4,93,93]. I presume this is a 24-bit image with an alpha channel, but I cannot work out how to display this in IDL direct graphics. (It displays correctly in IDL object graphics, presumably because images in that system are allowed alpha channels.) Can you help?
![]()
ANSWER: You are correct that the extra dimension is an alpha channel. And you are also correct that without some modifications you will not be able to display this image with the TV command. However, all is not hopeless yet.
To see how to do this, I downloaded a transparent PNG image that was provided by Stefan Schneider on a PNG image web page. I saved the image with the name “example.png”, and I read the image into IDL with these commands:
IDL> image = Read_PNG('example.png')
IDL> Help, image
IMAGE BYTE = Array[4, 162, 150]
We see this image is a pixel interleaved image with an alpha channel. Images like this are a bit easier to work with in IDL if they are band interleaved, so I converted it to a band interleaved image first.
IDL> image = Transpose(image, [1,2,0]) IDL> Help, image IMAGE BYTE = Array[162, 150, 4]
Your first thought might be that you could just ignore the alpha channel altogether. This was my first thought, too. But the result is unsatisfactory. Considerable detail, for example, is missing from the image. (In the original image from the person who asked this question, the text in the image was unreadable and blurred.) You can see the result in the figure below.
IDL> Window, XSIZE=162, YSIZE=150 IDL> TV, image[*,*,0:2], TRUE=3
![]() |
| The image without an alpha channel. |
In fact, the alpha channel has information in it that we would like to use. We can have a look at the alpha channel by itself.
IDL> alpha_channel = image[*,*,3]
IDL> MinMax, alpha_channel
0 255
IDL> TV, alpha_channel
![]() |
| The image alpha channel. |
You see here that the alpha channel of the image is byte scaled into the range 0 to 255. Normally, alpha channels are scaled into the range of 0 to 1, and we will need to scale it into that range if we wish to use it later on. I do so with the Scale_Vector command from the Coyote Library. The alpha channel essentially tells us how to blend the foreground image (the bird, in this case) with the background image (normally the pixels on the display where we are going to place the bird image).
IDL> scaled_alpha = Scale_Vector(alpha_channel , 0.0, 1.0)
We are also going to want to make our alpha image a 24-bit image.
IDL> s = Size(image[*,*,0:2], /DIMENSIONS) IDL> alpha = Rebin(scaled_alpha, s[0], s[1], s[2])
Let's take the first three channels of our image and name that image foregnd. And let's create an all white background image, named backgnd.
IDL> foregnd = image[*,*,0:2] IDL> backgnd = BytArr(s[0], s[1], 3) + 255B
Then the formula we are going to use to create a final image is this:
IDL> final_image = foregnd*alpha + (1 - alpha) * backgnd
And to display the image, we simply use the TV command.
IDL> TV, final_image, TRUE=3
![]() |
| The image with a white background. |
We can use any background color that we like. Suppose we wish to use a pale yellow [240,230,140] background color. We can do this.
IDL> backgnd = Rebin([ [[240]], [[230]], [[140]] ], s[0], s[1], s[2]) IDL> TV, foregnd*alpha + (1 - alpha) * backgnd, TRUE=3
![]() |
| The image with a pale yellow background. |
This suggests a way to place the image onto another image, and use the other images pixels as the background image. We could put this image on a map of Africa, for example.
IDL> filename = Filepath('africavlc.png', SubDir=['examples', 'data'])
IDL> africa= Read_PNG(filename, r, g, b)
IDL> win = Size(africa, /DIMENSIONS)
IDL> Window, XSIZE=win[0], YSIZE=win[1]
IDL> TVLCT, r, g, b
IDL> cgImage, africa, /TV
What we need to do is get a 24-bit image from the location where we want to display the bird image. Suppose we wish to put the bird on this image with the lower-left corner of the image at pixel location [183,338]. Then we could capture a 24-bit image from this location (this assumes you are using a 24-bit graphics card), like this.
IDL> backgnd = TVRD(183, 338, s[0], s[1], TRUE=3)
And we just display the image normally.
IDL> TV, foregnd*alpha + (1 - alpha) * backgnd, TRUE=3, 183, 338
The result is shown below.
![]() |
| The image on top of another image. |
Update
As of May 15th, 2009 cgImage is now written in such a way that it can display transparent PNG files directly. And a new program, cgBlendImage, is available to create semi-transparent or blended images of any two 24-bit images.
Update
On 5 November 2010 I introduced changes to cgImage that allow it to display a transparent image directly on a background image.
I also introduced the program Make_Transparent_Image that allows you to create a transparent image from either another image or from the contents of an IDL graphics window. You can specify the transparent color in several different ways. You can also save the transparent image directly to a transparent PNG file. Here is an example of how it works.
We first display a histogram plot in the display window. We make a transparent image out of that with Make_Transparent_Image. Then, we display a background image in the window. Finally, we display the transparent image on top of the original image. The code looks like this.
cgDisplay, 550, 350
cgHistoplot, cgDemoData(7), /FILL, AXISCOLOR='yellow', $
THICK=3, CHARSIZE=1.5, CHARTHICK=2
transparentImage = Make_Transparent_Image(COLOR='white')
LoadCT, 0, /SILENT
cgImage, cgDemoData(7)
cgImage, transparentImage
You see the result in the figure below.
![]() |
| A transparent image created and displayed on another image. |
You can use keywords to position the transparent image. Suppose, for example, you wanted to position the histogram plot in the upper-right corner of the display. You could type commands like this.
cgDisplay, 550, 350
cgHistoplot, cgDemoData(7), /FILL, AXISCOLOR='yellow', $
THICK=3, CHARSIZE=1.5, CHARTHICK=2
transparentImage = Make_Transparent_Image(COLOR='white')
LoadCT, 0, /SILENT
cgImage, cgDemoData(7)
cgImage, transparentImage, AlphaFGPosition=[0.5, 0.5, 0.95, 0.95]
You see the result in the figure below.
![]() |
| The transparent image in the upper-right corner of the background image. |
To create a PostScript file like this, you must pass in the background image with the AlphaBackgroundImage keyword, since there is no "window" in PostScript to obtain the image from. The code will look like this.
cgDisplay, 550, 350
cgHistoplot, cgDemoData(7), /FILL, AXISCOLOR='yellow', $
THICK=3, CHARSIZE=1.5, CHARTHICK=2
transparentImage = Make_Transparent_Image(COLOR='white')
LoadCT, 0, /SILENT
cgImage, cgDemoData(7)
snapshot = cgSnapshot()
PS_Start
cgImage, transparentImage, AlphaFGPosition=[0.5, 0.5, 0.95, 0.95], $
AlphaBackgroundImage=snapshot
PS_End
![]()
Version of IDL used to prepare this article: IDL 7.0.1.
![]()
![]()
Last Updated: 22 November 2011







