Click here to Skip to main content
Click here to Skip to main content

PixelMap Class and PNM Image Viewer

By , 28 May 2007
 
Screenshot - PixelMapViewer.jpg

Introduction

Although the class of Portable Any Map (PNM) format images -- which includes ASCII and Binary versions of Portable Bit Map (PBM), Portable Grey Map (PGM) and Portable Pixel Map (PPM) images -- represents the "lowest common denominator" of image formats, they are relatively uncommon in modern Windows environments. They also tend to be poorly supported on the free graphics programs for Windows, such as Paint and Paint.NET. Furthermore, I was not (in an admittedly short search) able to find a suitable C# class library for working with these formats programmatically.

Fortunately, the formats are quite simple, so it was relatively easy to build a PixelMap class to encapsulate these images and expose a couple of System.Drawing.Bitmap properties (BitMap and GreyMap) that can be used easily by other classes. Also, the simple Windows application that I created to test the PixelMap class rapidly evolved into a fairly competent viewer and converter that can save the current image as a BMP, JPG, TIFF, GIF, or PNG file.

Using the code

To use the PixelMap class you should:

  1. Copy the PixelMap.cs file into your own project.
  2. Change the namespace in the PixelMap.cs file to the name of your project namespace.
  3. Compile. The PixelMap class should now be available in your project.
The PixelMapViewer application demonstrates the usage of the PixelMap class. It also provides a handy viewing and converting application in its own right.

Points of interest

  • There are ASCII and Binary versions of each of the PBM, PGM, and PPM formats. The binary versions are much, much smaller and faster than the ASCII versions. They ought to be used unless there is a compelling reason to make the image file "human readable." Personally, I prefer to "read" my images by "looking at the pictures." This PixelMap class does not support the binary PBM format (Magic Number P4) at this time.
  • Since PBM, PGM, and PPM are UNIX-centric formats, their pixel order is BGR, rather than the RGB order that Windows programmers would tend to expect.
  • The "stride" of the image (normally calculated as stride = Image.Width * BytesPerPixel) should be a multiple of 4. If this is not the case, then in many programs the output images will become corrupted as they are processed. However, this is not a problem with the PixelMap class since it has been designed to work correctly with "off-size" images. However, it does have to use much less efficient (i.e. slow) algorithms relative to the normal direct-memory algorithms that it uses for well-sized images.

History

25 May, 2007 - Version 1.0.0.0 uploaded to CodeProject

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Stephen Bogner
Engineer Defence R&D Canada
Canada Canada
Member
Stephen Bogner is a Senior Research Engineer with Defence R&D Canada. As the Head Autonomous Applications Group, Autonomous Intelligent Systems Section, he only programs when it can't be avoided, and then only in C#.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralMy vote of 5membermanoj kumar choubey26 Feb '12 - 21:27 
Nice
GeneralThank you!memberkcarrera6 Feb '11 - 9:48 
This is really nice. Thank you very much for posting.
Have a great day - Ken
Generalmemory leak patchmemberleongurman6 Sep '10 - 20:12 
public class PixelMap
{
private IntPtr pImageData;
...
 
private Bitmap CreateBitMap()
{
pImageData = Marshal.AllocHGlobal(this.imageData.Length);
Marshal.Copy(this.imageData, 0, pImageData, this.imageData.Length);
Bitmap bitmap = new Bitmap(this.header.Width, this.header.Height, this.stride, this.pixelFormat, pImageData);
return bitmap;
}
 
private Bitmap CreateGreyMap()
{
...
 
pImageData = Marshal.AllocHGlobal(greyData.Length);
Marshal.Copy(greyData, 0, pImageData, greyData.Length);
Bitmap bitmap = new Bitmap(this.header.Width, this.header.Height, stride, PixelFormat.Format24bppRgb, pImageData);
bitmap.RotateFlip(RotateFlipType.Rotate180FlipNone);
return bitmap;
}
 
public void Dispose()
{
imageData = null;
bitmap.Dispose();
Marshal.FreeHGlobal(pImageData);
}
}
GeneralThanks for solving my problemmemberjimmygyuma18 Mar '10 - 8:22 
With just a few lines of code it converts a folder of ppm images to jpg images in another folder. My pdf image extraction program only seems to know ppm...
GeneralIt doesn't work for some *.pgm images.memberfarid_colombia2 Oct '08 - 18:17 
Hi Mr. Bogner.
 
Well, I could opened all my images in the *.ppm format, however, for some images in *.pgm format the algorithm seems to be not working. It doesn't throw an error or something like that while it is running but the result is not what I was waiting or at least what it was supposed to be.
I don't get the *.pgm images in a grey scales, I get it in some colors. It is like when you use Adobe Fireworks and you make a kind of a crazy effect that turns the image in brilliant colors.
I'm pretty sure that you will not understand me at all, but I don't know here how can I send you my image. Then you would be able to only open that image with your software.
For *.ppm, it is working perfectly. It has been a great utility for me. But I would like to know if maybe it has a solution. To get the images in *.pgm I use a free sotware called infranview. I change the format from jpeg or other to pgm.
 
Thanks for your attention and i hope your soon answer. Big Grin | :-D Laugh | :laugh:
GeneralRe: It doesn't work for some *.pgm images.memberStephen Bogner21 Oct '08 - 4:38 
Hi Farid;
 
The program uses a mapped palette to initially show the .pgm images. This is a sort of "false color" version that highlights differences more graphically. However, to make it show "greyscale" images correctly use the "Show - Greymap" menu command.
 
Hope this helps.
 
Steve.
GeneralRe: It doesn't work for some *.pgm images.memberfarid_colombia26 Oct '08 - 6:46 
Thanks a lot, it helped me. It works perfectly. Wink | ;)
A question: Do you know how to make 3D graphs with C#. I have the list of the points with X,Y and Z coordinates, but I haven't found some info about how to do it.
Thanks again!
GeneralRe: It doesn't work for some *.pgm images.memberMos Dan - Lucian12 Jan '10 - 8:30 
try the Charting/Graphs lib available in 3.5 and above from MS.
or there are also some good articles on graphs here on code project first one
or second one
GeneralPLEASE HEPL ME !!memberxuanvuongspkt24 Sep '08 - 3:06 
THE WAY TO VIEW GIF IMAGE IN C FOR DOS
Confused | :confused:
GeneralThanks!memberdaothanhtuan25 Mar '08 - 10:29 
Thank you very much.
I've been searching on this type of program but almost what i found in the Internet(written in C#) are full of bugs. Good job.
GeneralRe: Thanks!memberStephen Bogner25 Mar '08 - 12:25 
I'm glad that you found the class useful. Thanks for the feedback!
 
Steve.
GeneralRe: Thanks!memberdaothanhtuan3 Apr '08 - 9:18 
I just tried your class in linux(Suse 10.3). It didn't work. I ran the class in Mono 1.9.
I guess your mapping function from pgm to bitmap didn't correspond with things in linux.
I wonder if you have any concern to this.
Best regards.
Tuan
GeneralMuch appreciatedmemberSteveAbbott29 May '07 - 7:08 
Thanks for the excellent class. I'd written my own PNM viewer but it had plenty of problems and yours works marvellously.
I needed to port it to VB and had the usual fun with C# using names like magicnumber and MagicNumber as two different variables, but apart from some oddities over Char issues it worked fine.
 
Steve Abbott
GeneralRe: Much appreciatedmemberStephen Bogner1 Jun '07 - 7:48 
I'm glad that you found the class useful! Thanks for the feedback..
 
Steve.

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web02 | 2.6.130523.1 | Last Updated 28 May 2007
Article Copyright 2007 by Stephen Bogner
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid