- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I always have this pesky problem of loading the image created after using ippiMalloc(). Have done it in the past on IPPI 3 but can't find the code. This time I have a webcam image with its window so I have the window handle and can get the HDC using GetWindowDC() but what is the mechanism for transferring the image to the ippi image? Lost in the details. Have tried memcpy() and BitBlt() but may have done it incorrectly, or should I use something else? Not using MFC for this app and have checked all the Forum here with no luck. Thanks for any assistance.
Rick
Link Copied
7 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
HI,
May be you can use Win32 GetDIBits function?
Anyway, it wouild be great if someone can share here such a code or just link to where people can find it. Let's collect some simple tips&tricks!
From my side, I can share here part of my old sample, which demonstrate how to use IJL to compress desktop window. (you need get access to the pixel data by HDC of desktop window) So, here is the function which do actual work
static BOOL sshOnScreenshot(
PAPP_DATA)
{
int ires;
int width;
int height;
int pad_bytes;
int line_width;
int nChannels;
BOOL bres = FALSE;
HDC hdesktopDC = NULL;
HDC hmemDC = NULL;
HWND hWndDesktop = NULL;
HBITMAP holdBmp = NULL;
HBITMAP hdesktopBmp = NULL;
BYTE* dibits = NULL;
BITMAPINFO bmi;
BITMAPINFOHEADER bmih;
IJLERR jerr;
JPEG_CORE_PROPERTIES jcprops;
PAPP_DATA)
{
int ires;
int width;
int height;
int pad_bytes;
int line_width;
int nChannels;
BOOL bres = FALSE;
HDC hdesktopDC = NULL;
HDC hmemDC = NULL;
HWND hWndDesktop = NULL;
HBITMAP holdBmp = NULL;
HBITMAP hdesktopBmp = NULL;
BYTE* dibits = NULL;
BITMAPINFO bmi;
BITMAPINFOHEADER bmih;
IJLERR jerr;
JPEG_CORE_PROPERTIES jcprops;
ZeroMemory(&bmi,sizeof(BITMAPINFO));
ZeroMemory(&bmih,sizeof(BITMAPINFOHEADER));
ZeroMemory(&jcprops,sizeof(JPEG_CORE_PROPERTIES));
ZeroMemory(&bmih,sizeof(BITMAPINFOHEADER));
ZeroMemory(&jcprops,sizeof(JPEG_CORE_PROPERTIES));
hWndDesktop = GetDesktopWindow();
if(NULL == hWndDesktop)
{
bres = FALSE;
goto Exit;
}
{
bres = FALSE;
goto Exit;
}
hdesktopDC = GetDC(hWndDesktop);
if(NULL == hdesktopDC)
{
bres = FALSE;
goto Exit;
}
{
bres = FALSE;
goto Exit;
}
hmemDC = CreateCompatibleDC(hdesktopDC);
if(NULL == hmemDC)
{
bres = FALSE;
goto Exit;
}
{
bres = FALSE;
goto Exit;
}
width = GetSystemMetrics(SM_CXSCREEN);
height = GetSystemMetrics(SM_CYSCREEN);
height = GetSystemMetrics(SM_CYSCREEN);
if(width == 0 || height == 0)
{
bres = FALSE;
goto Exit;
}
{
bres = FALSE;
goto Exit;
}
bmih.biSize = sizeof(BITMAPINFOHEADER);
bmih.biWidth = width;
bmih.biHeight = height;
bmih.biPlanes = 1;
bmih.biBitCount = 24;
bmih.biCompression = BI_RGB;
bmih.biSizeImage = 0;
bmih.biXPelsPerMeter = 0;
bmih.biYPelsPerMeter = 0;
bmih.biClrUsed = 0;
bmih.biClrImportant = 0;
bmih.biWidth = width;
bmih.biHeight = height;
bmih.biPlanes = 1;
bmih.biBitCount = 24;
bmih.biCompression = BI_RGB;
bmih.biSizeImage = 0;
bmih.biXPelsPerMeter = 0;
bmih.biYPelsPerMeter = 0;
bmih.biClrUsed = 0;
bmih.biClrImportant = 0;
hdesktopBmp = CreateDIBitmap(hdesktopDC,&bmih,0,NULL,NULL,DIB_RGB_COLORS);
if(NULL == hdesktopBmp)
{
bres = FALSE;
goto Exit;
}
{
bres = FALSE;
goto Exit;
}
holdBmp = (HBITMAP)SelectObject(hmemDC,hdesktopBmp);
if(NULL == holdBmp)
{
bres = FALSE;
goto Exit;
}
{
bres = FALSE;
goto Exit;
}
bres = BitBlt(hmemDC,0,0,width,height,hdesktopDC,0,0,SRCCOPY);
if(FALSE == bres)
{
goto Exit;
}
{
goto Exit;
}
// we want 3 channel dib data
nChannels = 3;
nChannels = 3;
pad_bytes = IJL_DIB_PAD_BYTES(width,nChannels);
line_width = (width * nChannels) + pad_bytes;
line_width = (width * nChannels) + pad_bytes;
dibits = new BYTE [line_width * height];
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmi.bmiHeader.biWidth = width;
bmi.bmiHeader.biHeight = height;
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biBitCount = 24;
bmi.bmiHeader.biCompression = BI_RGB;
bmi.bmiHeader.biSizeImage = 0;
bmi.bmiHeader.biXPelsPerMeter = 0;
bmi.bmiHeader.biYPelsPerMeter = 0;
bmi.bmiHeader.biClrUsed = 0;
bmi.bmiHeader.biClrImportant = 0;
bmi.bmiHeader.biWidth = width;
bmi.bmiHeader.biHeight = height;
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biBitCount = 24;
bmi.bmiHeader.biCompression = BI_RGB;
bmi.bmiHeader.biSizeImage = 0;
bmi.bmiHeader.biXPelsPerMeter = 0;
bmi.bmiHeader.biYPelsPerMeter = 0;
bmi.bmiHeader.biClrUsed = 0;
bmi.bmiHeader.biClrImportant = 0;
ires = GetDIBits(hdesktopDC,hdesktopBmp,0,height,dibits,&bmi,DIB_RGB_COLORS);
if(ires == 0)
{
bres = FALSE;
goto Exit;
}
{
bres = FALSE;
goto Exit;
}
// now we have 24 bpp bitmap data
jerr = ijlInit(&jcprops);
if(IJL_OK != jerr)
{
bres = FALSE;
goto Exit;
}
{
bres = FALSE;
goto Exit;
}
jcprops.DIBWidth = width;
jcprops.DIBHeight = -height;
jcprops.DIBChannels = nChannels;
jcprops.DIBPadBytes = IJL_DIB_PAD_BYTES(width,3);
jcprops.DIBColor = IJL_BGR;
jcprops.DIBSubsampling = IJL_NONE;
jcprops.DIBBytes = dibits;
jcprops.DIBHeight = -height;
jcprops.DIBChannels = nChannels;
jcprops.DIBPadBytes = IJL_DIB_PAD_BYTES(width,3);
jcprops.DIBColor = IJL_BGR;
jcprops.DIBSubsampling = IJL_NONE;
jcprops.DIBBytes = dibits;
jcprops.JPGWidth = width;
jcprops.JPGHeight = height;
jcprops.JPGChannels = nChannels;
jcprops.JPGColor = IJL_YCBCR;
jcprops.JPGSubsampling = IJL_411;
jcprops.JPGBytes = NULL;
jcprops.JPGSizeBytes = 0;
jcprops.JPGFile = "desktop.jpg";
jcprops.jquality = 75;
jcprops.JPGHeight = height;
jcprops.JPGChannels = nChannels;
jcprops.JPGColor = IJL_YCBCR;
jcprops.JPGSubsampling = IJL_411;
jcprops.JPGBytes = NULL;
jcprops.JPGSizeBytes = 0;
jcprops.JPGFile = "desktop.jpg";
jcprops.jquality = 75;
jerr = ijlWrite(&jcprops,IJL_JFILE_WRITEWHOLEIMAGE);
if(IJL_OK != jerr)
{
bres = FALSE;
goto Exit;
}
{
bres = FALSE;
goto Exit;
}
bres = TRUE;
Exit:
ijlFree(&jcprops);
if(NULL != dibits)
{
delete [] dibits;
}
{
delete [] dibits;
}
if(NULL != holdBmp && NULL != hmemDC)
{
SelectObject(hmemDC,holdBmp);
}
{
SelectObject(hmemDC,holdBmp);
}
if(NULL != hdesktopBmp)
{
DeleteObject(hdesktopBmp);
}
{
DeleteObject(hdesktopBmp);
}
if(NULL != hmemDC)
{
DeleteDC(hmemDC);
}
{
DeleteDC(hmemDC);
}
if(NULL != hWndDesktop && NULL != hdesktopDC)
{
ReleaseDC(hWndDesktop,hdesktopDC);
}
{
ReleaseDC(hWndDesktop,hdesktopDC);
}
return bres;
} // sshOnScreenshot()
} // sshOnScreenshot()
Regards,
Vladimir
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Vladimir,
Thank you very much for your quick response and code example. It looks promising and I'll let you know how that approach works.
On a prior project I used the ippiSample file as a starting place and read .bmp files to load images and that worked OK for that project. I like the ippiSample as there are several useful C++ classes ready to use and I couldadd others for printing etc.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Vladimir,
I used pieces of your example code in my webcam application. Thanks for that, it helped see the process requirements. I couldn't get the GetDIBits() call to function, everything before that seemed OK. I found some similar code at mathtools.net that uses the Clipboard and that works! OK for now as I would like to eliminate that requirement later. I used the ippiSample MFC project included with IPPI 4.0 as that provides a comple MFC framework. (But adding printing with that is a big problem, why didn't they check off the printing support when creating the application with the MFC Wizard?). Simple code is below. Iput the standard capCreateCaptureWindow() and capDriverConnect() callsin CIppiSampleApp::InitInstance to set up the camera. Then I used the MFC wizard to add a menu item link to the CSampleView to grab an image from the camera to the ippiImage (ie the CSampleDoc).
void CSampleView::OnGrabframe()
{
bool bAns;
HBITMAPm_hBmp = NULL;
CBitmap m_bmp; //bitmap object
BITMAP bm;
CPaintDC dc(this); // device context for painting
bAns = capGrabFrame(hWndC); // grab an image from the camera to the MDI doc.
capEditCopy(hWndC); // copies the frame to the clipboard
bAns = OpenClipboard(); //like virtual memory.
m_hBmp = (HBITMAP)::GetClipboardData(CF_BITMAP); //m_hBmp is a Handle to clipboard Bitmap.
CloseClipboard(); // free it up
{
bool bAns;
HBITMAPm_hBmp = NULL;
CBitmap m_bmp; //bitmap object
BITMAP bm;
CPaintDC dc(this); // device context for painting
bAns = capGrabFrame(hWndC); // grab an image from the camera to the MDI doc.
capEditCopy(hWndC); // copies the frame to the clipboard
bAns = OpenClipboard(); //like virtual memory.
m_hBmp = (HBITMAP)::GetClipboardData(CF_BITMAP); //m_hBmp is a Handle to clipboard Bitmap.
CloseClipboard(); // free it up
m_bmp.Detach(); //cleaning the bitmap.
m_bmp.Attach(m_hBmp); //connecting the bitmap, throw the handle.
this->Invalidate(true);
m_bmp.Attach(m_hBmp); //connecting the bitmap, throw the handle.
this->Invalidate(true);
m_bmp.GetBitmap(&bm);
bAns = m_ImageDC.DeleteDC();
bAns = m_ImageDC.DeleteDC();
m_ImageDC.CreateCompatibleDC(&dc);
m_ImageDC.SelectObject(&m_bmp);
m_ImageDC.SelectObject(&m_bmp);
dc.StretchBlt(0, 0, 640,480,
&m_ImageDC,0,0,bm.bmWidth,bm.bmHeight, SRCCOPY);
}
&m_ImageDC,0,0,bm.bmWidth,bm.bmHeight, SRCCOPY);
}
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Vladimir,
OK, here is a rudimentary "rest of the solution" to grab a frame from a Logitech webcam and put it into an Ippi image ready for the Ippi suite of processing algorithms available. My previous post merely copies the webcam image to the CSampleView window and displays it. More work has to be done, using the GetDIBits() to copy the image to an Ippi image buffer. To test it is working (just because no ippiErr is returned doesn't mean an image was copied) I added another menu itemto cause the image to rotate 45 degrees about its center. CSampleView::OnProcessRot45(). I still don't see a way to eliminate copying the webcam image to the Clipboard.
*****************************************************************************
void CSampleView::OnGrabframe()
{
bool bAns;
int iAns;
IppStatus rslt;
HBITMAPm_hBmp = NULL;
CBitmapm_bmp; //bitmap object
BITMAPbm;
{
bool bAns;
int iAns;
IppStatus rslt;
HBITMAPm_hBmp = NULL;
CBitmapm_bmp; //bitmap object
BITMAPbm;
CPaintDC dc(this); // device context for painting
bAns = capGrabFrame(hWndC); // grab an image from the camera to the MDI doc.
bAns = capGrabFrame(hWndC); // grab an image from the camera to the MDI doc.
capEditCopy(hWndC); // copies the frame to the clipboard
bAns = OpenClipboard(); //like virtual memory.
m_hBmp = (HBITMAP)::GetClipboardData(CF_BITMAP); //m_hBmp is a Handle to clipboard Bitmap.
bAns = OpenClipboard(); //like virtual memory.
m_hBmp = (HBITMAP)::GetClipboardData(CF_BITMAP); //m_hBmp is a Handle to clipboard Bitmap.
CloseClipboard(); // free it up
m_bmp.Detach(); //cleaning the bitmap.
m_bmp.Attach(m_hBmp); //connecting the bitmap, throw the handle.
this->Invalidate(true);
m_bmp.Attach(m_hBmp); //connecting the bitmap, throw the handle.
this->Invalidate(true);
iAns = m_bmp.GetBitmap(&bm);
bAns = m_ImageDC.DeleteDC();//m_ImageDC is DC for the SampleView
m_ImageDC.CreateCompatibleDC(&dc);
m_ImageDC.SelectObject(&m_bmp);
bAns = dc.StretchBlt(0, 0, 640,480, // dc is Paint object for this SampleView
&m_ImageDC,0,0,bm.bmWidth,bm.bmHeight, SRCCOPY);//uses CDC*
//****************** done copying camera image to window
&m_ImageDC,0,0,bm.bmWidth,bm.bmHeight, SRCCOPY);//uses CDC*
//****************** done copying camera image to window
int totl;
BITMAPINFObmi;
BITMAPINFOHEADER bmih;
BITMAPINFObmi;
BITMAPINFOHEADER bmih;
bmih.biSize = sizeof(BITMAPINFOHEADER);
bmih.biWidth = 640;
bmih.biHeight = 480;
bmih.biPlanes = 1;
bmih.biBitCount = 24;
bmih.biCompression = BI_RGB;
bmih.biSizeImage = 0;
bmih.biXPelsPerMeter = 0;
bmih.biYPelsPerMeter = 0;
bmih.biClrUsed = 0;
bmih.biClrImportant = 0;
bmih.biWidth = 640;
bmih.biHeight = 480;
bmih.biPlanes = 1;
bmih.biBitCount = 24;
bmih.biCompression = BI_RGB;
bmih.biSizeImage = 0;
bmih.biXPelsPerMeter = 0;
bmih.biYPelsPerMeter = 0;
bmih.biClrUsed = 0;
bmih.biClrImportant = 0;
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmi.bmiHeader.biWidth = 640;
bmi.bmiHeader.biHeight = 480;
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biBitCount = 24;
bmi.bmiHeader.biCompression = BI_RGB;
bmi.bmiHeader.biSizeImage = 0;
bmi.bmiHeader.biXPelsPerMeter = 0;
bmi.bmiHeader.biYPelsPerMeter = 0;
bmi.bmiHeader.biClrUsed = 0;
bmi.bmiHeader.biClrImportant = 0;
bmi.bmiHeader.biWidth = 640;
bmi.bmiHeader.biHeight = 480;
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biBitCount = 24;
bmi.bmiHeader.biCompression = BI_RGB;
bmi.bmiHeader.biSizeImage = 0;
bmi.bmiHeader.biXPelsPerMeter = 0;
bmi.bmiHeader.biYPelsPerMeter = 0;
bmi.bmiHeader.biClrUsed = 0;
bmi.bmiHeader.biClrImportant = 0;
totl = GetDIBits( m_ImageDC, // handle to device context
m_hBmp, // handle to bitmap
0, // first scan line to set in destination bitmap
480, // number of scan lines to copy
(void*)p_mem, // address of array for bitmap bits, our ipp8u memory
&bmi, // address of structure with bitmap data
DIB_RGB_COLORS // RGB or palette index
);
m_hBmp, // handle to bitmap
0, // first scan line to set in destination bitmap
480, // number of scan lines to copy
(void*)p_mem, // address of array for bitmap bits, our ipp8u memory
&bmi, // address of structure with bitmap data
DIB_RGB_COLORS // RGB or palette index
);
DeleteObject(m_hBmp);
}
}
void CSampleView::OnProcessRot45()
{
IppStatus rslt;
CSampleDoc* thedoc;
CIppiImage* thisimg;
IppiRecttheRO I;
IppiSize imgsz;
CDC*pdc;
CIppiImageDC viewIppiDC;
{
IppStatus rslt;
CSampleDoc* thedoc;
CIppiImage* thisimg;
IppiRecttheRO I;
IppiSize imgsz;
CDC*pdc;
CIppiImageDC viewIppiDC;
thedoc = this->GetDocument();
thisimg = thedoc;
pdc = this->GetDC();
thisimg = thedoc;
pdc = this->GetDC();
theROI.height = 480;
theROI.width = 640;
theROI.x= 0;
theROI.y= 0;
theROI.width = 640;
theROI.x= 0;
theROI.y= 0;
imgsz.height = 480;
imgsz.width = 640;
imgsz.width = 640;
rslt = ippiRotateCenter_8u_C3R((Ipp8u*) p_mem, imgsz, thisimg->Step(), theROI,
(Ipp8u*) thisimg->DataPtr(), thisimg->Step(), theROI,
45, 320, 240, IPPI_INTER_NN);
m_ImageDC.SetData();// put img to device context
(Ipp8u*) thisimg->DataPtr(), thisimg->Step(), theROI,
45, 320, 240, IPPI_INTER_NN);
m_ImageDC.SetData();// put img to device context
this->Invalidate(true);// repaint
}// end ::OnProcessRot(45)
}// end ::OnProcessRot(45)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
As I understand you can get access to captured frame pixels when you use grabber callback function. Can you get pointer to LPVIDEOHDR structure which describes captured frame?
Regards,
Vladimir
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Vladimir,
Thanks for the tip and I got the callback to work:
///////////
.
.
capSetCallbackOnFrame(hWndC,capVideoStreamCallback); // callbak for GrabFrame
.
bAns = capGrabFrame(hWndC); // grab an image from the camera to the MDI doc.
.
.
/////////
callback:
LRESULT CALLBACK capVideoStreamCallback(HWND hWnd, LPVIDEOHDR lpVHdr)
{
p_videodat = lpVHdr->lpData;
videodatlngth = lpVHdr->dwBufferLength;
{
p_videodat = lpVHdr->lpData;
videodatlngth = lpVHdr->dwBufferLength;
return true;
}
}
Now I just have to figure out again how to use this pointer to copy the image data to the View......
Rick
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Rick
actually it is pointer to DIB pixels. Only thing you need - to get format of these data with couple of functions:
capGetVideoFormatSize
capGetVideoFormat
DWORD capGetVideoFormat(
hwnd,
psVideoFormat,
wSize
);
- hwnd
- Handle of a capture window.
- psVideoFormat
- Address of a BITMAPINFO structure. You can also specify NULL to retrieve the number of bytes needed by BITMAPINFO.
- wSize
- Size, in bytes, of the structure referenced by s.
Regards,
Vladimir
Vladimir
Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page