www.pudn.com > Gesture[20040824].rar > Image.cpp
// Image.cpp: implementation of the CImage class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "Gesture.h"
#include "Image.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CImage::CImage()
{
Clear();
}
void CImage::Clear()
{
memset( &m_img, 0, sizeof(m_img));
m_memDC = 0;
m_old = 0;
}
void CImage::Destroy()
{
if( m_memDC )
{
DeleteObject( SelectObject( m_memDC, m_old ));
DeleteDC( m_memDC );
}
Clear();
}
CImage::~CImage()
{
Destroy();
}
void FillBitmapInfo( BITMAPINFO* bmi, int width, int height, int bpp )
{
ASSERT( bmi && width > 0 && height > 0 &&
(bpp == 8 || bpp == 24 || bpp == 32) );
BITMAPINFOHEADER* bmih = &(bmi->bmiHeader);
memset( bmih, 0, sizeof(*bmih));
bmih->biSize = sizeof(BITMAPINFOHEADER);
bmih->biWidth = width;
bmih->biHeight = -abs(height);
bmih->biPlanes = 1;
bmih->biBitCount = bpp;
bmih->biCompression = BI_RGB;
if( bpp == 8 )
{
RGBQUAD* palette = bmi->bmiColors;
int i;
for( i = 0; i < 256; i++ )
{
palette[i].rgbBlue = palette[i].rgbGreen = palette[i].rgbRed = (BYTE)i;
palette[i].rgbReserved = 0;
}
}
}
bool CImage::Create( int w, int h, int bpp )
{
char buffer[sizeof(BITMAPINFOHEADER) + 1024];
BITMAPINFO* bmi = (BITMAPINFO*)buffer;
void* data = 0;
int new_step = (w*(bpp/8) + 3) & -4;
ASSERT( bpp == 8 || bpp == 24 || bpp == 32 );
bool AlphaChannel = bpp==32;
if( (m_img.depth & 255) == bpp &&
m_img.width == w && m_img.height == h )
{
return true;
}
Destroy();
m_memDC = CreateCompatibleDC(0);
FillBitmapInfo( bmi, w, h, bpp );
HBITMAP hbmp = CreateDIBSection( m_memDC, bmi, DIB_RGB_COLORS, &data, 0, 0 );
if( !hbmp )
{
DeleteDC( m_memDC );
m_memDC = 0;
}
else
{
BITMAP bmp;
m_old = SelectObject( m_memDC, hbmp );
GetObject( hbmp, sizeof(bmp), &bmp );
/* prepare IPL header */
memset( &m_img, 0, sizeof(m_img));
m_img.nSize = sizeof( m_img );
m_img.nChannels = bpp/8;
m_img.depth = IPL_DEPTH_8U;
strncpy( m_img.colorModel, bpp > 8 ? "RGB\0" : "GRAY", 4 );
strncpy( m_img.channelSeq, bpp > 8 ? "BGR\0" : "GRAY", 4 );
m_img.align = 8;/////////////////////////////////////////////////
m_img.width = w;
m_img.height = abs(h);
m_img.roi = 0;
m_img.widthStep = (w*(bpp/8) + 3)& -4;
m_img.imageSize = m_img.widthStep*m_img.height;
m_img.imageData = m_img.imageDataOrigin = (char*)bmp.bmBits;
iplSetBorderMode( &m_img, IPL_BORDER_REPLICATE, IPL_SIDE_ALL, 0 );
}
return m_old != 0;
}
void CImage::CopyOf( CImage& image, int desired_color )
{
IplImage* img = image.GetImage();
if( img )
{
int color = desired_color;
if( color < 0 ) color = img->nChannels > 1;
Create( img->width, img->height, color ? 24 : 8 );
if( m_img.nChannels == img->nChannels )
iplCopy( img, &m_img );
else
{
CImage tmp_image;
tmp_image.Create( m_img.width, m_img.height, img->nChannels*8 );
IplImage* tmp_img = tmp_image.GetImage();
iplCopy( img, tmp_img );
if( color )
iplGrayToColor( tmp_img, &m_img, 0, 0, 0 );
else
iplColorToGray( tmp_img, &m_img );
}
}
}
bool CImage::LoadBMP2IPL( const char* filename, bool IsColor )
{
int filter = 0;
int width = 0, height = 0;
bool result = false;
int color = 55;
if( gr_fmt_find_filter == 0 ) return false;
if( !(filter = gr_fmt_find_filter( filename ))) goto exit;
if( !gr_fmt_read_header( filter, &width, &height, &color )) goto exit;
Create( width, height, IsColor ? 24 : 8);
if( m_memDC == 0 ) goto exit;
result = gr_fmt_read_data( filter, m_img.imageData, m_img.widthStep, color ) != 0;
exit:
gr_fmt_close_filter( filter );
return result;
}
bool CImage::LoadRect( const char* filename,
int desired_color, RECT r )
{
int filter = 0;
int width = 0, height = 0;
bool result = false;
int color = 0;
int r_width = r.right - r.left;
int r_height = r.bottom - r.top;
int tmp_step = 0;
char* tmp = 0;
if( r_width < 0 || r_height < 0 ) return false;
if( gr_fmt_find_filter == 0 ) return false;
if( !(filter = gr_fmt_find_filter( filename ))) goto exit;
if( !gr_fmt_read_header( filter, &width, &height, &color )) goto exit;
if( r_width == 0 || r_height == 0 )
{
r_width = width;
r_height = height;
}
if( (unsigned)r.left >= (unsigned)width ||
(unsigned)r.top >= (unsigned)height ||
(unsigned)r.right >= (unsigned)width ||
(unsigned)r.bottom >= (unsigned)height ) goto exit;
color = desired_color >= 0 ? desired_color : color > 0;
Create( r_width, r_height, color ? 24 : 8);
if( m_memDC == 0 ) goto exit;
if( r.left == 0 && r.top == 0 &&
(r_width == 0 || r_width == width) &&
(r_height == 0 || r_height == height))
{
tmp = m_img.imageData;
tmp_step = m_img.widthStep;
}
else
{
tmp_step = (width*m_img.nChannels + 3) & -4;
tmp = (char*)malloc( tmp_step * height );
if( !tmp ) goto exit;
}
result = gr_fmt_read_data( filter, tmp, tmp_step, color ) != 0;
if( result && tmp != m_img.imageData )
{
int y;
for( y = 0; y < r_height; y++ )
{
memcpy( m_img.imageData + y*m_img.widthStep,
tmp + (r.top + y)*tmp_step + r.left*m_img.nChannels,
r_width * m_img.nChannels );
}
}
exit:
gr_fmt_close_filter( filter );
if( tmp != 0 && tmp != m_img.imageData ) free( tmp );
return result;
}
void CImage::LoadIPL2IPL(IplImage *image)
{
Create(image->width, image->height, image->nChannels*8);
cvCopyImage(image, &m_img);
}
void CImage::SaveIPL2BMP(const char *fout, IplImage *image)
{
if ( (image->nChannels != 3 && image->nChannels != 1) || image->depth != IPL_DEPTH_8U ) return;
gr_fmt_write_image( image->imageData, image->widthStep,
iplWidth( image ), iplHeight( image ),
image->nChannels == 3, fout, "BMP" );
}
void CImage::Show( HDC dc, int x, int y, int w, int h, int from_x, int from_y )
{
if( m_img.width > 0 )
{
uchar buffer[sizeof(BITMAPINFOHEADER) + 1024];
BITMAPINFO* bmi = (BITMAPINFO*)buffer;
int bmp_w = Width();
int bmp_h = Height();
FillBitmapInfo( bmi, bmp_w, bmp_h, m_img.nChannels*8 );
int sw = MAX( MIN( bmp_w - from_x, w ), 0 );
int sh = MAX( MIN( bmp_h - from_y, h ), 0 );
int res = SetDIBitsToDevice(
dc, // handle to DC
x, // x-coord of destination upper-left corner
y, // y-coord of destination upper-left corner
sw, // source rectangle width
sh, // source rectangle height
from_x, // x-coord of source lower-left corner
from_y, // y-coord of source lower-left corner
from_y, // first scan line in array
sh, // number of scan lines
m_img.imageData + from_y*m_img.widthStep/* +
from_x*m_img.nChannels*/, // array of DIB bits
(BITMAPINFO*)bmi, // bitmap information
DIB_RGB_COLORS ); // RGB or palette indexes
}
}
void CImage::Fill( COLORREF color )
{
if( m_memDC )
{
HBRUSH br = CreateSolidBrush( color );
RECT rect;
GetClipBox( m_memDC, &rect );
FillRect( m_memDC, &rect, br );
DeleteObject( br );
}
}
unsigned char ** CImage::ProcessArray()
{//最多可以处理500 行图象 //仅仅对灰度
for (int i=0;i< m_img.height;i++)
{
image[i]=(unsigned char *)((m_img.imageData)+i*m_img.width);
}
return &image[0];
}