Re: display array in a frame wnd
I thank you for your answer.
When I make image processing, I have to display results.
p1 , p2 , p3 are pointers on IplImage*
I would like to create a function where I can give a title and the image
pointer to get a window with the image in it.
// here is what I want to do
display("image source",p1) ;
process(p1,p2) ;
display("first result",p2) ;
process(p1,p3) ;
display("second result",p3) ;
In the lib opencv I use, I just have to do
cvNamedWindow("source image",0) ;// create window
cvShowImage("source image",p1) ; // display window
cvDestroyWindow("source image") ; // to detroy it
The window can be used in all the program thanks to the name "source image".
It is very easy but the problem is that I want in the future to add a status
bar and also a menu to the window, and I think it is easier to
create window through MFC than modifying existing code of the lib.
This window can be created anywhere in the program.
"Joseph M. Newcomer" <newcomer@flounder.com> a ?crit dans le message de
news: vn8td3heqr95ruls37bdeohgs0pkatkmol@4ax.com...
First, did you create this program using the Wizards? If not, it is hard
to tell what is
going on. Is it MDI, SDI, or what?
My application is SDI.(without view).
Generally, I see no reason to be creating a frame window at all; this is
normally done for
you by the wizards, and you should be working in a view window.
Many bugs below,,,
On Wed, 5 Sep 2007 10:52:57 +0200, "J-F Portala" <jfportala@free.fr>
wrote:
Hi,
I am using opencv wich is an image processing lib.
I would like to display in a CFrameWnd, images represented by an
array.(IplImage format)
pImg is the IplImage*
****
It appears that you are using an ImageInfo * structure, so why did you not
say this? An
LPIImage format is nothing more than a pointer to an IImage, which does
not have any of
the fields you are using.
****
I have some difficulties to display the array.
First , I create CFramWnd,
CFrameWnd* pw ;
pw = new CFrameWnd() ;
pw->Create("NULL,"test") ;
pw->ShowWindow(SW_SHOW) ;
****
And why are you creating a CFrameWnd? You should not be doing this at
all, but if you
need to create one for some obscure reason, you definitely need to
subclass it and create
an instance of your subclass. But I think this is a mistake.
I would like to display a window anywhere (it could be just for debugging a
special image processing algorithm)
that is the reason why I have created a CFrameWnd when I need it.
Note that if you are NOT using the wizards, you need to restart the
project, creating the
project using the AppWizard. It makes no sense to create an application
like this unless
you are ABSOLUTELY CERTAIN you know EXACTLY what you are doing, and in
this case it is
clear that you do not understand basic Windows programming. Until you do,
do not attempt
to create programs other than using the wizards. (After using MFC for
over 12 years, I
would not consider doing building a program other than with the wizards,
since it would
only be a waste of my time or be cheating my clients by taking their money
under false
pretenses).
You are right. I am working with visual C++ for several years but
I was using before matrox library, where I could make a link between an
image buffer and a CFrameWnd created in the beginning of the program.
I have added menu and status bar to the CDisplayWnd (subclass of CFrameWnd)
That is the reason why I have chosen CFrameWnd
but I am not familiar with bitmap, palette and device context.
****
I get the window.
then
//Initialize the BMP display buffer
BITMAPINFO* bmi;
BITMAPINFOHEADER* bmih;
RGBQUAD* palette;
unsigned int buffer[sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD)*256];
****
Why are you declaring an unsigned int array whose size is based on BYTE
counts? LPBYTE
buffer would make sense, or dividing the size value by sizeof(int), but
this creates an
array four times larger than what you need.
****
bmi = (BITMAPINFO*)buffer;
bmih = &(bmi->bmiHeader);
memset(bmih, 0, sizeof(*bmih));
****
Using ::ZeroMemory would be a better choice
****
bmih->biSize = sizeof(BITMAPINFOHEADER);
bmih->biWidth = pImg->width;
bmih->biHeight = pImg->height;
bmih->biPlanes = 1;
bmih->biCompression = BI_RGB;
bmih->biBitCount = 8 * pImg->nChannels;
palette = bmi->bmiColors;
*****
What is pColor? where does it come from? where is it initialized?
pColor is pImg, I have changed the name to make it more comprehensive (I use
generally 8bits image in grey levels)
but I have forgotten to replace pColor.
*****
if (pColor->nChannels == 1)
{
for( int i = 0; i < 256; i++ )
{
palette[i].rgbBlue = palette[i].rgbGreen =
palette[i].rgbRed
= (BYTE)i;
palette[i].rgbReserved = 0;
}
}
CPaintDC dc(pw);
****
This makes no sense. A CPaintDC is declared ONLY in the OnPaint handler,
which is where
all this code belongs, yet you seem to imply this code is done somewhere
else, such as in
the place where you are creating the frame window. But why are you
drawing in a frame
window and not a view? Why is this not in an OnPaint handler?
I explained it above ( perhaps cView is more adapted) but can I attach a
status bar and a menu.
The code I have tested was obtained during my researches on internet.
****
CDC* pDC = &dc;
*****
Get rid of this line. It makes ABSOLUTELY NO SENSE WHATSOEVER! There is
absolutely no
reason to introduce a gratuitous pointer variable that contributes nothing
to the program,
and merely decreases the readability of the code. There is not a single
sane reason this
variable should exist.
*****
int res = StretchDIBits(
pDC->GetSafeHdc(), //dc
****
Why not use
::StretchDIBits((HDC)dc, ...)
why introduce a meaningless pointer variable that serves no useful
purpose, only to call a
method that makes no sense? Or you could have written
::StretchDIBits(dc.m_hDC, ...)
but GetSafeHdc doesn't make sense here. And if you DID want to write it,
you would have
written
dc.GetSafeHdc()
instead of using a meaningless pointer variable that serves no purpose
whatsoever.
****
0, //x dest
0, //y dest
int(pImg->width), //x dest dims
int(pImg->height), //y dest dims
0, // src x
0, // src y
pImg->width, // src dims
pImg->height, // src dims
pImg->imageData, // array of DIB bits
(BITMAPINFO*)bmi, // bitmap information
DIB_RGB_COLORS, // RGB or palette indexes
SRCCOPY); // raster operation code
// Update Window, force View to redraw.
pw->RedrawWindow(
****
So your comment says UpdateWindow, but your call is RedrawWindow....
Since this would be in the OnPaint handler of the CFrameWnd-derived class,
or better
still, in the OnPaint handler of the view class, this call would have no
meaning. Since
you appear to be doing this somewhere else, it cannot possibly work,
because the CPaintDC
is meaningless.
****
NULL, // handle to window
NULL, // update rectangle
RDW_INVALIDATE // handle to update region
);
I have no display of my image.
Where is the problem ?
****
You used a CPaintDC outside an OnPaint handler, you did painting outside
an OnPaint
handler.
Start over. Create a document/view application, put the initialization in
the
OnInitialUpdate handler, put the drawing code in the OnPaint handler of
the view.
joe
****
Thank you for your help
Jeff