Steve on Image Processing

Digital image processing using MATLAB: writing image files 3

Posted by Steve Eddins,

Today's post is part of an ongoing tutorial series on digital image processing using MATLAB. I'm covering topics in roughly the order used in the book Digital Image Processing Using MATLAB.

The MATLAB function imwrite writes image data to a variety of different formats including: reads image data from a variety of formats, including JPEG, JPEG 2000, TIFF, PNG, and GIF (as well as a few older formats no longer commonly used).

Probably most people use form where you just provide the image array and a filename.

I'll read in one of the sample images in Image Processing Toolbox to experiment with.

rgb = imread('peppers.png');
imshow(rgb)
imwrite(rgb,'mypeppers.tif')

In the above call to imwrite, the function decides which image format to use based on the extension (.tif) in the filename.

Sometimes, though, you might want to use a filename extension for a different purpose. In that case, you call pass a third argument to imwrite to let it know which image format to use.

imwrite(rgb, 'test_image.study_013', 'tif')

Most image file formats support some form of compression. That means that the image takes up less space on disk than you might think based on a simple calculation. For example, the rgb array above takes up about 576 kilobytes in memory.

bytes_in_memory_peppers = numel(rgb)
bytes_in_memory_peppers =

      589824

But it takes less space on disk when you save it to an image format that uses compression. Let's try writing to a PNG file:

imwrite(rgb,'mypeppers.png')

info = imfinfo('mypeppers.png');
bytes_on_disk_peppers_png = info.FileSize
bytes_on_disk_peppers_png =

      287589

compression_ratio = bytes_in_memory_peppers / bytes_on_disk_peppers_png
compression_ratio =

    2.0509

The PNG format uses lossless compression. This means that you can recover the original image data exactly.

peppers2 = imread('mypeppers.png');
isequal(rgb, peppers2)
ans =

     1

Lossless compression methods save a lot more space when the image has large constant areas or contains certain kinds of repetitive, predictable patterns. For example, this image is a screen shot of a MATLAB plot:

url = 'http://blogs.mathworks.com/images/steve/2012/plot_screen_shot.png';
rgb_plot = imread(url);
bytes_in_memory_plot = numel(rgb_plot)
bytes_in_memory_plot =

      336000

info = imfinfo(url);
bytes_on_disk_plot = info.FileSize
bytes_on_disk_plot =

        3284

compression_ratio = bytes_in_memory_plot / bytes_on_disk_plot
compression_ratio =

  102.3143

That's a pretty big compression ratio!

Other image file formats, such as JPEG, use lossy compression. (There is a lossless form of JPEG, but it is obscure and rarely used.) With lossy compression, properties of the human visual system are exploited to reduce the disk size even further, but at a cost --- the original pixels are not exactly recoverable. Let's write out the peppers image using JPEG compression.

imwrite(rgb,'peppers.jpg');
info = imfinfo('peppers.jpg');
bytes_on_disk_peppers_jpg = info.FileSize
bytes_on_disk_peppers_jpg =

       23509

compression_ratio_peppers_jpg = bytes_in_memory_peppers / ...
    bytes_on_disk_peppers_jpg
compression_ratio_peppers_jpg =

   25.0893

That's a much bigger compression ratio than we got with the PNG format above. The cost is in reduced image quality. JPEG does a pretty good job of reducing space without adversely affecting image quality:

imshow('peppers.jpg')

But it isn't perfect, as you can see by zooming in.

subplot(1,2,1)
imshow('peppers.png')
limits = [232 276 215 248];
axis(limits)
title('Original')

subplot(1,2,2)
imshow('peppers.jpg')
axis(limits)
title('JPEG compressed')

You can see the compression artifacts around the stem.

Compression artifacts tend to be more visible on images such as the plot screen shot above.

imwrite(rgb_plot,'plot_screen_shot.jpg')
rgb_plot_compressed = imread('plot_screen_shot.jpg');

subplot(2,2,1)
imshow(rgb_plot)
title('Original image')
limits = [80 105 210 230];
axis(limits);

subplot(2,2,2)
imshow(rgb_plot_compressed)
title('JPEG compressed image')
axis(limits);

subplot(2,2,3)
imshow(rgb_plot)
limits = [345 380 240 265];
axis(limits);

subplot(2,2,4)
imshow(rgb_plot_compressed)
axis(limits);

That's why I usually use PNG for screen shots of many MATLAB graphics. For more complex images, on the other hand, I usually use JPEG.

For more information, see Section 2.4 of Digital Image Processing Using MATLAB.

See also the reference pages for imwrite, as well as the section Reading and Writing Image Data in the Image Processing Toolbox User's Guide.


Get the MATLAB code

Published with MATLAB® 7.13

3 CommentsOldest to Newest

Hi Steve,

I am able to overlay a series of complex data plots over an image and I need to write this to a png file. Is it possible to convert this figure to a form that I can use with imwrite? Using the print, saveas, getframe, etc options don’t work for me as they do not output the image with the original resolution and they add a white box around the image.

Thanks,

Michael

Michael—I believe it is possible, but it will take some programming on your part. You’ll want to have the axes positioned to fill the figure. Then you should be able to set the figure units and size, together with the -r option to the print command, to get the effect you’re looking for.

Michael : I’ve had great success in similar situations by printing the images to color eps using the print command

print -depsc foo.eps

I’ve noticed that saving to eps does not create the white box around the plot (beyond the axis labels, that is).. The eps figure can then be converted to png in any desired resolution. I know this is not exactly what you are trying to achieve, but, it will give you the png images with sufficiently high resolution.

These postings are the author's and don't necessarily represent the opinions of MathWorks.