分享

Image Processing using GDI and VC 6.0 - CodeGuru

 unununy 2010-03-21

Environment: GDI+ and VC6

I was recently working on a small project to convert an image to the WAP's WBMP format. WAP is the Wireless Application Protocol, for people who didn't know and WBMP stands for Wireless Bitmap.

I was having a hard time reading various formats (GIFs, JPGs, and BMPs) until I came across some excellent articles on using GDI+ at the CodeGuru site and also on the CodeProject site. These articles developed my interest further into image processing and I got hooked on it. What started out as a simple picture-to-WBMP convertor is fast growing into a complete image processing framework. The articles of Christian Grauss on using GDI+ and .NET for image processing are excellent resources. I wanted to code all stuff in VC++ and not .NET—simply because I am used to VC++.

For any image processing task, one needs to access raw pixel data. If you look at the GDI+ API for doing this, it's quite complex; besides, I also wanted to code my image processing routines so that I can port them to other environments. In other words, I did not want any GDI+ specific code in the core image processing routines. This compelling requirement forced me to make a choice on which pixel data format to use. I decided to use only the ARGB (Alpha, red, green, blue) mode of the image data that can easily be encoded in an 'int'. I wrote helper functions to create an array of ARGB encoded ints given a GDI+ Bitmap and also to create a GDI+ Bitmap from my integer array. Here are the functions:

// Given a Bitmap - get an integer encoded data of the pixels
int * Bitmap2PixelData(Bitmap *b) {
// get width and height of Bitmap
int width = b->GetWidth();
int height = b->GetHeight();
// make sure these are valid
if ( width *height <= 0 )
return NULL;
// allocate memory for pixel data
int *pixelData_ARGB = new int[width*height];
if ( pixelData_ARGB == NULL )
return NULL;
// get the pixel values from the bitmap and encode
// into the array allocated above.
BitmapData bmData;
Rect rect(0, 0, width, height);
b->LockBits(rect,
ImageLockModeRead,
PixelFormat32bppARGB,
&bmData);
int stride = bmData.Stride;
BYTE *p = (BYTE *)((void *)bmData.Scan0);
int nOffset = stride - width*4;    // bytes to skip at end of
// each row
for(int y=0; y < height;y++) {
for(int x=0; x < width; ++x ) {
// GDI lies about RGB - internally it's BGR
pixelData_ARGB[y*width+x] =  ARGB2Pixel(p[3], p[2], p[1],
p[0]);
p += 4;
}
p += nOffset;
}
b->UnlockBits(&bmData);
// return the pixel data array
return (pixelData_ARGB);
}

The preceding code uses ARGB2Pixel. This is an inline function that computes the pixel value—given Alpha, Red, Green and Blue values. It also clamps the ARGB component such that they all lie between 0 and 255, inclusive. Here is the code for that:

inline int ARGB2Pixel(int alpha, int r, int g, int b) {
if ( alpha > 255 )
alpha = 255
else if ( alpha < 0 )
alpha = 0;
if ( r > 255 )
r = 255
else if ( r < 0 )
r = 0;
if ( g > 255 )
g = 255
else if ( g < 0 )
g = 0;
if ( b > 255 )
b = 255
else if ( b < 0 )
b = 0;
// shift r and g to encode
r = (r << 16);
g = (g << 8 );
return ( ((alpha << 24 )&0xff000000)  | r | g| b );
}

Given below is the function that takes an integer array and creates a GDI+ Bitmap that can then be displayed.

Bitmap * PixelData2BitMap(int width, int height,
int *pixData_ARGB) {
// create a temporary Bitmap
Bitmap bit(width, height, PixelFormat32bppARGB);
// create its clone for returning
Bitmap *b = bit.Clone(0, 0, bit.GetWidth(), bit.GetHeight(),
PixelFormat32bppARGB);
BitmapData bmData;
Rect rect(0, 0, b->GetWidth(), b->GetHeight());
b->LockBits(rect,
ImageLockModeRead | ImageLockModeWrite,
PixelFormat32bppARGB,
&bmData);
int stride = bmData.Stride;
BYTE *p = (BYTE *)((void *)bmData.Scan0);
int nOffset = stride - width*4;   // bytes to skip at end of
// each row
int pixel;
for(int y=0; y < height;y++) {
for(int x=0; x < width; ++x ) {
// GDI lies about RGB - internally it's BGR
pixel = pixData_ARGB[y*width+x];
p[3] = (BYTE) ((pixel >> 24) & 0xff);    // alpha
p[2] = (BYTE) ((pixel >> 16) & 0xff);    // pixel red
p[1] = (BYTE) ((pixel >> 8 ) & 0xff);    // pixel green
p[0] = (BYTE) ((pixel      ) & 0xff);    // pixel blue
p += 4;
}
p += nOffset;
}
b->>UnlockBits(&bmData);
return (b);
}

The sample project also has some neat undo-redo stuff. It does not save any images yet. Nevertheless, it's quite easy to add support for various image formats (use GDI+ to save as well). There are several articles on CodeGuru to do that.

Downloads

Download source - 20 Kb
  • 1
missing the file "GDIPLUS.H".
Legacy CodeGuru | 02/07/2003 12:00am
open commentclose comment
Originally posted by: JeongDong, Lee

Compiling...
StdAfx.cpp
c:\download\codeguru\gdi\imgproc\stdafx.h(26) :
fatal error C1083: Cannot open include file: 'gdiplus.h': No such file or directory
Error executing cl.exe.

ImgProc.exe - 1 error(s), 0 warning(s)

 

This code has leak.
Legacy CodeGuru | 02/11/2003 12:00am
open commentclose comment
Originally posted by: AbhijeetR

When exiting with more than one image opend, the current image item is not released.

Need to modify CImgProcDoc destructor as below.

CImgProcDoc::~CImgProcDoc()
{
if( NULL != current)
delete current;
}

 

error case not handled
Legacy CodeGuru | 02/11/2003 12:00am
open commentclose comment
Originally posted by: Na-iem Dollie

Hi

I notice the following code in method:


/*start code*/
// make sure these are valid
if ( width *height <= 0 )
return NULL;
/*end code*/

doesn't handle the case of width < 0 && height < 0.

Regards,
Na-iem

 

hello
Legacy CodeGuru | 02/24/2003 12:00am
open commentclose comment
Originally posted by: jacob

fucked

 

Image on scrollview
Legacy CodeGuru | 03/05/2003 12:00am
open commentclose comment
Originally posted by: simmy

Hi Deepak,
Can you please help me as i have to meet some deadline here?
Actually i am trying to display the image in a scrollview which works fine.But i want to be able to rotate,zoom the image ,which is also fine but the scrolls are not getting set properly on zoom or rotation.Can you send me some sample program which can help me ??
Thanks
Simmy

 

transparented GIF
Legacy CodeGuru | 03/14/2003 12:00am
open commentclose comment
Originally posted by: Mihai

How can I save an Bitmap object in .gif file - BUT with transparency background ? I use:

GetEncoderClsid(_T("image/gif"), &encoderClsid);
Bitmap bmp(hBmp, hpal);
stat = bmp.Save(strFileName, &encoderClsid, NULL);
//I looked for some &encoderParameters);

Thank you in advance,
Mihai

 

Help Need in doing ImageComparission
Legacy CodeGuru | 04/11/2003 12:00am
open
commentclose comment
Originally posted by: Raju Selvaraj

Dear Friend,
Iam Raju Selvaraj.Working in BGI Tech Chennai,
Friend i've been assigned a project in Image Processing topic "Image Comparission".objective is to compare to bitmaps and to high light difference in the images.iam familier with VC++,but no knowledge about Image PRocessing.
I'll be thakfull if u help me in doing project.

I went thru u r code,it seems very useful but the thing is i couldnt understatnd funcnalities.It'll be better if u send me ur code with some documentation.

Reply to me if possible to "raju_obuli@yahoo.com".

Expecting u r valule reply.
Advance Thanks,
Raju selvaraj.

 

Image Processing using GDI+ and VC++ 6.0
Legacy CodeGuru | 04/11/2003 12:00am
open
commentclose comment
Originally posted by: Raju Selvaraj

Hi Deepa,
When i tried to run ur program i got a error message "Cannot open include file: 'gdiplus.h': No such file or directory", what might be the problem.And i am new to Image processing ,recently i've assingned project of "Image Comparission" in VC++.Can u help me in developing that.
I'll be thakfull if u help me.Expecting u r valuble reply.
advance Thanks,
Regards,
Raju Selvaraj

 

Memory Reference Errors occured: Using above code for real-time applications
Legacy CodeGuru | 04/24/2003 12:00am
open commentclose comment
Originally posted by: Atif Bashir

AOA

Memory Reference error is occured and the application terminates when I want to use the image-processing code provided by you i.e.

When I use to process the images/frames at some rate e.g. 20 fps, the program executes for a minute approximately and suudenly gives Memory Reference Error and also demands to
Increase the Virtual Memory Paging File size to run the window properly.

Can you advise me about the matter.

I'll be very grateful for your early response.

Kind Regards
------------------------ Atif

 

colors used in a bitmap with 24 bit color depth
Legacy CodeGuru | 05/04/2003 12:00am
open commentclose comment
Originally posted by: MAJED

I have a bitmap with few number of colors but it is stored in format of 24 bit.
the problem is:
to calculate the number of this colors and what is it without using GetPixel() API function for performance needs.

if there is an effective way so please advice me.
Best Regards

Eng.Majed

 

I prefer Free Image Processing Library !
Legacy CodeGuru | 05/08/2003 12:00am
open
commentclose comment
Originally posted by: Mohamed El Kayyali

Hi. I didnt use your GDI++ Code till now. but what i understand is that you were spending too much time reading Image formates. Actually I do not recommend any one interesting to develop image processing applications to use GDI++ or other platforms unless there is many image processing library can fit your applications.
Good luck .

Mohamed El Kayyali
IEEE member.
Image Processing researcher.

 

Can you please specify names, URL of some library...
Jigar Mehta | 05/12/2004 6:23am
open commentclose comment
Hye, Can you please tell us some names of image processing libraries...
compiling error
Legacy CodeGuru | 05/21/2003 12:00am
open commentclose comment
Originally posted by: Hello

error C2664: 'LockBits' : cannot convert parameter 1 from 'class Gdiplus::Rect' to 'const class Gdiplus::Rect *'

No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called

Am I wrong to set some configuration?

Compiling error as well
Legacy CodeGuru | 05/30/2003 12:00am
open commentclose comment
Originally posted by: miguel Mendez

I also got the same C2664 compiling error
Do you solve the problem?

Thanks,

Miguel Mendez

 

How To use
Legacy CodeGuru | 12/02/2003 12:00am
open commentclose comment
Originally posted by: Venkatesh

I am able to complie the program but how I can load an image and look at it by Negate and Gray scale menu option.

 

Nice program...
SanjeevKumar | 05/05/2004 10:36am
open commentclose comment
Its a very nice program man...
need help on Image processing
sonali_dp | 05/28/2004 2:48am
open commentclose comment
Hello This is Sonali and i went through ur article i need help on how to store an image in an array and then read each pixel from the arrays and then perform some computations and then display from the array please help.
please help me
naveenkumarsk | 08/11/2004 8:57am
open commentclose comment
hi naveen here,i need help on to read a file which contains hexadecimal numbers i.e 96x6 format,after reading i want to store in a buffer, again from buffer i want to display the pixels on screen
Gdiplus need to be initialized
Joowoong Kim | 04/16/2005 10:49pm
open commentclose comment
To compile and run above code sample, you have to initialize the GDI+ library first.
// By Kim Joo-woong
// must be class or global variable, because of being used in initializing and deinitializing
ULONG_PTR			gdiplusToken;
// initializing code - add below code to startup GDI+ library
GdiplusStartupInput gdiplusStartupInput;
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
// deinitializing code - add below code to free GDI+ library
GdiplusShutdown( gdiplusToken );
The Memory could not be ''read''
Dreamzdoll | 12/04/2008 1:18am
open commentclose comment
Hi! Even i have a similar problem. In a MFC, MDI, MultiThreaded Application with Serial Communication in it (Rs-232), i have to update the toolbar buttons every 180 millisecs and save the recieved data into a ''DBF'' every time. How do i handle this problem. Please help!
(You must be signed in to comment on an article. Not a member? Click here to register)

 

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多