I post a code tested in borland c++, so some few changes need te be altered.
there you see some dynamic array declaration , instead you have to modify by pointer(dynamic allocation) as a dynamic array;
Main Topics
Browse All TopicsHi everyone ,
I'm doing image processing for the first time and I'm working with VC++ 6.0 under WinXP.
I would like to create a function which loads an 8 bit grayscale bitmap image and convert it
into a 2D array where each element represents one of the image's
pixel intensities for further purposes e.g. to calculate the fft.I saw quite similar
examples on this homepage but none of them returns an 2D array.
My code is attached in Code Snippet
The problem is that I would like to have the values of the array returned and I don't know how it should look like inside LRESULT CALLBACK WndProc function(I'm using Win32 API).And I'm also getting error message because of following declarations:
BYTE tempScanLine[WIDTH * 1] // error C2057:it should be a constant expression
//error C2466 : can't reserved an array of size 0
// error C2133: 'tempScanLine' : unknown parameter
const double grayscale[WIDTH*HEIGHT]; // error C2133: 'grayscale' : unknown parameter
I thought of writing grayscale=new double [WIDTH*HEIGHT] but then I have to give the memory free
and I can't return the array anymore right?
Thank you
This Question has been solved and asker verified All Experts Exchange premium technology solutions are available to subscription members.
Experts Exchange has been collecting answers to technology questions since 1996…3 million and counting! If you have a question, chances are we already have your answer.
If you can't find the exact answer you're looking for, ask our exclusive community of 50,000 experts. You’ll get a personalized answer from a trusted professional.
Thousands of free tech tips, tricks, how-to’s and tutorials are available in our peer reviewed articles section. See for yourself how smart our experts are, no login required.
Access the answers to your technology questions today.
30-day free trial. Register in 60 seconds.
Members of the expert community talk about why the experience at Experts Exchange is different than what you will find anywhere else.

Try it out and discover for yourself.
30-day free trial. Register in 60 seconds.
Join the community of experts here and help other tech pros by answering question in your area of expertise. You can earn FREE access to all Experts Exchange's premium features and resources.
As I am working with Microsoft VC++ 6.0, what should be appropriate to replace TTBitmap , TTByteArray with?Do I have to define a Class for Bitmap?If I have to use pointer in order to store the pixels I would have to use pointer auf pointer right? How is the function set_length() define?what about ScanLine?I can't see the definition for it anywhere. Where in the above code should be the file loaded and opened?
I downloaded the class Cximage on the following website:
http://www.codeproject.com
Do you have an idea ow I could use that class in order to store the pixel in an 2D array?
>> what should be appropriate to replace TTBitmap
I'm not so expert in VC, but instead of Tbitmap, you can see HBITMAP, CBitmapclass in Vc++
> TTByteArray
TTByteArray is dynamic 1D array of bytes, you can use instead a dynamic allocation by pointers
for exemple
BYTE *buffBitmap = new BYTE[];
>>function set_length()
since I had used dynamic array, this function set a new size to the array in each step of adding an element in it;
>> ScanLine[];
is a function to indicate (set pointer) to a row, which in turn has his own pixels(columns)
First of all, don't put something like that in your WM_PAINT handler.
Here is how I'd proceed in experimenting with and learning about these issues:
1) Create new dialog-based MFC application.
2) Add a smallish gray-scale image to your resources (IDB_BITMAP1)
3) Add a picture control to your dialog box, Set properties:
ID: IDC_MyBmpCtrl <<--- important: not IDC_STATIC
Type: bitmap
Image: IDB_BITMAP1
The image is now automatically displayed for you!
4) Click on the bitmap in the dialog and press Ctrl+W (class wizard)
5) Click Member Variables; select IDC_MyBmpCtrl
6) Click [Add Variable]
Member name: m_ctlMyBmp
Category: Control
Variable TYpe: CStatic
7) Add a button to the dialog (IDC_BUTTON1)
8) Double click it (add dlg member function OnButton1()
Put this text there:
MessageBox("You rang?");
After that, you now can start experimenting. The image is automatically loaded and displayed. When you click a button, some specific code will be executed. You can obtain the HBITMAP my using:
HBITMAP hBmp= m_ctlMyBmp.GetBitmap()
You can use the various CBitmap functions by:
CBitmap* pcBmp= CBitmap::FromHandle( hBmp );
and then...
CSize cs= pcBmp->GetBitMapDimension(
... and so forth.
When you get to this point, and have read up on CBitmap class object, let me know, and we'll take it to the next step.
-- Dan
Hi,
I've never used MFC before and it took some time to reach until step 4.At Step four I was asked to create a new Class!(I named the Class MyBitmap).the MessageBox should be then in the function "void MyBitmap::OnButton1" right?Where should I write the following statements?
HBITMAP hBmp= m_ctlMyBmp.GetBitmap();
CBitmap* pcBmp= CBitmap::FromHandle( hBmp );
CSize cs= pcBmp->GetBitMapDimension(
Thank you
You should not have needed to create a new class object -- only a new member function for the CDialog-derived object that is the main (only) window your new program has.
Assuming that your project name is MyTestApp...
The OnButton1 function will be a member of CMyTestAppDlg (the ClassWizard will place it into the MyTestAppDlg.cpp source file.
I've seen where my mistake was.I was asked to create a new class
because I created a new dialog for the picture instead of using
the Dialog which was already generated by VC++.The function OnButton1()
is now at the right place.no error by compiling but the bitmap is not displayed at all.I'm having only
a blank page.....
What about
HBITMAP hBmp= m_ctlMyBmp.GetBitmap();
CBitmap* pcBmp= CBitmap::FromHandle( hBmp );
CSize cs= pcBmp->GetBitMapDimension(
Should they be put in (I renamed my project MyTestApp) MyTestAppView.cpp?
thank you
>> I'm having only
a blank page.....
This leads me to think that perhaps you did not create a Dialog-based application. That option is on the first page presented by the AppWizard. Revised detail for step #1:
1a) menu: File / New...
1b) Select Projects tab
1c) Select MFC AppWizard [exe] / Project name: MyTestApp / [OK]
1d) Select Dialog based [Finished]
(Your empty dialog is displayed.)
You are right.I hadn't created a Dialog-based application but a SDI application.
Now my 8bpp grayscale image is automatically loaded and displayed. By clicking on the button1 a message is also displayed.
How could I now store the pixel intensities in an array where each element represents one of the image's pixel intensities?
Thank you
OK, here's the next step. Put this code into the OnButton1 handler:
HBITMAP hBmp= (HBITMAP)LoadImage(NULL,"c
m_ctlMyBmp.SetBitmap( hBmp );
CBitmap* pcBmp= CBitmap::FromHandle( hBmp );
BITMAP rBmp;
int n= pcBmp->GetBitmap( &rBmp );
But use a filename of a bitmap you want to work with. I suggest you make a small one, say 10x10 or 32x32 for testing purposes. First run the revised code: You should see the desired bitmap appear in the control.
Next, put a breakpoint on the last line. Single-step it. Now use the debugger to examine the filled-in values in rBmp (a BITMAP structure). It will provide the dimensions of the newly-loaded bitmap and other information. Report what it says for
rBmp.bmBitsPixel
and
rBmp.bmPlanes
This is important for the next step, because some "grayscale" images are really full-color images.
I loaded for testing purposes a colored 32x32 bitmap and a grayscale 26x24 bitmap.For the 32x32 bitmap I become as information:
rBmp.bmWidth=32
rBmp.bmHeight=32
rBmp.bmBitsPixel=32
rBmp.bmPlanes=1
and for the grayscale 26x24 bitmap I'm having:
rBmp.bmBitsPixel=32
rBmp.bmPlanes=1
I also tested all other "grayscale" bitmap(with dimensions 256x256) I had and it happened that they are all 32Bpp Bitmap with rBmp.bmPlanes=1.
that means I thought I was handling with 8Bpp grayscale image and in fact they weren't right?
thank you
The simplest, and easiest-to-understand tool that is available to you is:
GetPixel(x,y)
It returns a COLORREF value that represents the intensity of each of the Red, Green, Blue (RGB) components of the single pixel at the designated position.
In order to access that function, the bitmap must be selected into a "DC" (Device Context). Because we have set up a test scenario in which the bitmap is already being displayed, this is easy.
Your next step is to experiment with this as follows:
1) Use the code (in the attachment, below) in your OnButton1 handler (or add an OnButton2 handler... whatever)
2) Click the button to see the result.
An all-white pixel will be (255,255,255) and an all-black one will be (0,0,0).
In a color bitmap, an all-red pixel will be (255,0,0) and so forth,
3) Open Paintbrush or other bitmap editor and change the color of the pixel in the top left corner (x=0, y=0). Save the bitmap and click the button in your dialog box. You should see the new result -- both visibly in the displayed bitmap (that one pixel will change color) and in the message box.
4) You can now experiment with accessing other pixels.
5) If you want, you can modify the bitmap. Add another button and use CDC::SetPixel() For instance:
void CD39Dlg::OnButton4()
{
CDC* pCDC= m_ctlMyBmp.GetWindowDC();
pCDC->SetPixel(0,0, RGB(255,0,0) );
pCDC->SetPixel(1,0, RGB(255,0,0) );
pCDC->SetPixel(0,1, RGB(255,0,0) );
pCDC->SetPixel(1,1, RGB(255,0,0) );
}
When you click that (newly-added button) the four pixels in the top/left corner will turn red.
If you have a grayscale bitmap, then your RGB values will be all the same... e.g.,
(0,0,0)= black;
(32,32,32)= very light gray,
(127,127,127) is medium gray,
(255,255,255)= pure black,
etc.
=-=-=-=-=-=-=-=-=-=
If you have a particular (smallish) gray-scale bitmap that you want to experiment with (and about which you have questions), you can attach it to your next comment, and I'll refer to it in subsequent comments of my own.
-- Dan
The step 1) until step 5) work all fine. Thank you very much for the detailed explanations.
In the MSDN website the function GetPixel is defined like this:
COLORREF GetPixel(
HDC hdc, // handle to device context
int nXPos, // x-coordinate of pixel
int nYPos // y-coordinate of pixel
)
Why did you use only two arguments instead of three when calling GetPixel?
Was it possible in order to retrieve the red, green and blue value of a pixel to use the RGBQUAD structure?
Thank you
>>Why did you use only two arguments instead of three when calling GetPixel?
I'm not sure If I could answer like DanRollins, but anyway I found another representation in MSDN
http://msdn2.microsoft.com
it may be pertinent
The ::GetPixel() API function
http://msdn2.microsoft.com
requires an HDC parameter. But you will recall that I used the syntax:
pCDC->GetPixel(0,0);
which uses the similar function that is a member of the CDC class object. That object already knows the HDC, and it uses it when it calls the underlying API function.
>> Was it possible in order to retrieve the red, green and blue value of a pixel to use the RGBQUAD structure?
I'm not certain what you mean by this.
The RGBQUAD and COLORREF structures are functionally similar ways to looks at a 32-bit value that contains the RGB information used to describe the color of a pixel.
I have a question at line 24 of your code.What happens when RGB are not all the same?do I have to include a if-clause?
Isit possible to use a function of my own on abPixels[x][y]= GetRValue( clrRGB )?(line 24)
The code depends on the fact that a dialog-based application has been used.It is possible to read each pixel of the image without displaying it by using MFC of course?
thank you
"...all the same" refers to the fact that it is a grayscale image.
That means that when in memory, for use by a color device (the screen) the R,G, and B values will always be equal. That provides 256 levels of whiteness. Consider that if the values were not all the same -- say there was more red than green -- then the image would contain non-gray pixels.
As to the fact that there is a dialog box involved...
The only reason for that is to make it easy to see the results of experiments. The functionaity would be the same if you never display the image. For instance, the only relevant difference is that the above code uses:
m_ctlMyBmp.SetBitmap( hBmp );
so that you can physically *see* the bitmap. It is perfectly valid to make changes to the pixel data without ever displaying the image anywhere. The fact that a dialog box is used is not part of that equation. You could just as easily create an off-screen DC and manipulate the pixels there.
Thanks for the points and the grade :-)
Business Accounts
Answer for Membership
by: abosultanPosted on 2008-03-05 at 09:37:30ID: 21052467
I suggest you to use opencv library since you work on VC and first time on image processing; it can help you if you like to continue in this field /%7Elagani er/tutoria l/ opencv%2 Bdirectsho w/cvision. htm
have a look at Open cv
http://www.site.uottawa.ca