📄 image.cpp
字号:
// Image.cpp: implementation of the CImage class.
// Author : Lamon Pierre 2000
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "USBCam.h"
#include "Image.h"
#include "Utils.h"
#include "Wingdi.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CImage::CImage()
{
}
CImage::CImage(long width, long height, short bPerPix)
{
DWORD dwBitsSize;
DWORD dwBitsPix;
dwBitsPix = bPerPix * width * height; // size in bytes of the image
dwBitsSize = dwBitsPix;
dwBitsSize += sizeof (BITMAPFILEHEADER); // Add size of file structure
dwBitsSize += sizeof (BITMAPINFOHEADER); // Add size of info structure
hDIB = (HDIB) ::GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, dwBitsSize);
if (hDIB == NULL) NOT_ENOUGH_MEM ("Image");
pHead = (LPBITMAPINFOHEADER) ::GlobalLock((HGLOBAL) hDIB);
if (pHead == NULL) NOT_ENOUGH_MEM ("pHead");
pHead->biSize = sizeof (BITMAPINFOHEADER);
pHead->biWidth = width;
pHead->biHeight = height;
pHead->biPlanes = 1;
pHead->biBitCount = bPerPix * 8;
pHead->biCompression = 0;
pHead->biSizeImage = dwBitsPix;
pHead->biXPelsPerMeter = 0;
pHead->biYPelsPerMeter = 0;
pHead->biClrUsed = 0;
pHead->biClrImportant = 0;
bPerPixel = bPerPix;
GetBitsPointer();
Set2DVectors();
::GlobalUnlock((HGLOBAL) hDIB);
}
CImage::~CImage()
{
Free2DVectors();
if (hDIB != NULL)
{
if (::GlobalFree((HGLOBAL) hDIB) != NULL) AfxMessageBox ("Error with global free !");
hDIB = NULL;
}
}
void CImage::Free2DVectors()
{
if (Pixel != NULL) free (Pixel);
}
BOOL CImage::ReadFromFile(CString filename)
{
CFile file;
CFileException fe;
char buf[50];
strcpy (buf,filename);
if (!file.Open(buf, CFile::modeRead | CFile::shareDenyWrite, &fe))
{
AfxMessageBox ("Error while opening file");
return FALSE;
}
// replace calls to Serialize with ReadDIBFile function
TRY
{
hDIB = ::ReadDIBFile(file);
}
CATCH (CFileException, eLoad)
{
file.Abort(); // will not throw an exception
AfxMessageBox ("Error while reading file");
hDIB = NULL;
return FALSE;
}
END_CATCH
GetImageHeader();
GetBitsPointer();
Set2DVectors();
// Compute the number of byte for one pixel
bPerPixel = pHead->biBitCount / 8;
return TRUE;
}
BOOL CImage::StoreInFile(CString filename)
{
CFile file;
CFileException fe;
char buf[50];
strcpy (buf,filename);
if (!file.Open(filename, CFile::modeCreate |
CFile::modeReadWrite | CFile::shareExclusive, &fe))
{
AfxMessageBox ("Error while opening file");
return FALSE;
}
// replace calls to Serialize with SaveDIB function
BOOL bSuccess = FALSE;
TRY
{
bSuccess = ::SaveDIB(hDIB, file);
file.Close();
}
CATCH (CException, eSave)
{
file.Abort(); // will not throw an exception
AfxMessageBox ("Error while writing file");
return FALSE;
}
END_CATCH
if (!bSuccess)
{
// may be other-style DIB (load supported but not save)
// or other problem in SaveDIB
CString strMsg;
strMsg = "Could not save DIB";
MessageBox(NULL, strMsg, NULL, MB_ICONINFORMATION | MB_OK);
}
return bSuccess;
}
void CImage::DisplayImage(HDC pHdc,int xDest, int yDest, int dWidth, int dHeight,int fcol, int mode, int mask)
{
LPSTR lpDIBHdr; // Pointer to BITMAPINFOHEADER
lpDIBHdr = (LPSTR) ::GlobalLock((HGLOBAL) hDIB);
switch (mode)
{
case ALL_IMAGE :
SetDIBitsToDevice(pHdc,
xDest,
yDest,
pHead->biWidth,
pHead->biHeight,
0,0,0,
pHead->biHeight,
pBits,
(LPBITMAPINFO) lpDIBHdr,
DIB_RGB_COLORS
);
break;
case TRUNK_IMAGE :
StretchDIBits(pHdc,
xDest,
yDest,
dWidth,
dHeight,
fcol,
0,
dWidth,
pHead->biHeight,
pBits,
(LPBITMAPINFO) lpDIBHdr,
DIB_RGB_COLORS,
mask);
break;
case STRETCH_IMAGE :
StretchDIBits(pHdc,
xDest,
yDest,
dWidth,
dHeight,
fcol,
0,
pHead->biWidth,
pHead->biHeight,
pBits,
(LPBITMAPINFO) lpDIBHdr,
DIB_RGB_COLORS,
SRCCOPY
);
break;
}
}
void CImage::Set2DVectors()
{
int i;
int SizeOfLine; // Size in bytes of a image line
SizeOfLine = pHead->biBitCount / 8 * pHead->biWidth;
Pixel = (BYTE **) malloc ( pHead->biHeight * sizeof(void *));
Pixel[0] = (BYTE*) pBits;
for (i = 1; i < pHead->biHeight; i++)
Pixel[i] = (BYTE*) (pBits + i * SizeOfLine);
}
void CImage::GetImageHeader()
{
LPSTR lpDIBHdr; // Pointer to BITMAPINFOHEADER
lpDIBHdr = (LPSTR) ::GlobalLock((HGLOBAL) hDIB);
pHead = LPBITMAPINFOHEADER (lpDIBHdr);
}
void CImage::GetBitsPointer()
{
LPSTR lpDIBHdr; // Pointer to BITMAPINFOHEADER
lpDIBHdr = (LPSTR) ::GlobalLock((HGLOBAL) hDIB);
pBits = (BYTE*) ::FindDIBBits(lpDIBHdr);
}
void CImage::DisplayInfo()
{
CString str = _T("");
str.Format ("%sbiSize : %i\n",str,pHead->biSize);
str.Format ("%sbiWidth : %i\n",str, pHead->biWidth);
str.Format ("%sbiHeight : %i\n",str, pHead->biHeight);
str.Format ("%sbiPlanes : %i\n",str, pHead->biPlanes);
str.Format ("%sbiBitCount : %i\n",str,pHead->biBitCount);
str.Format ("%sbiCompression : %i\n",str,pHead->biCompression);
str.Format ("%sbiSizeImage : %i\n",str, pHead->biSizeImage);
str.Format ("%sbiXPelsPerMeter : %i\n",str, pHead->biXPelsPerMeter);
str.Format ("%sbiYPelsPerMeter : %i\n",str,pHead->biYPelsPerMeter);
str.Format ("%sbibiClrUsed : %i\n", str,pHead->biClrUsed);
str.Format ("%sbiClrImportant : %i\n",str, pHead->biClrImportant);
AfxMessageBox (str);
}
void CImage::GetPixelRGB(int nCol, int nLin, BYTE *r, BYTE *g, BYTE *b)
{
int adrOffset;
adrOffset = nCol * bPerPixel;
*b = Pixel[nLin][adrOffset++];
*g = Pixel[nLin][adrOffset++];
*r = Pixel[nLin][adrOffset];
}
void CImage::GetPixelHSI(int nCol, int nLin, BYTE *h, BYTE *s, BYTE *i)
{
int adrOffset;
adrOffset = nCol * bPerPixel;
*h = Pixel[nLin][adrOffset++];
*s = Pixel[nLin][adrOffset++];
*i = Pixel[nLin][adrOffset];
}
void CImage::SetPixel(int nCol, int nLin, BYTE r, BYTE g, BYTE b)
{
int adrOffset;
adrOffset = nCol * bPerPixel;
Pixel[nLin][adrOffset++] = b;
Pixel[nLin][adrOffset++] = g;
Pixel[nLin][adrOffset] = r;
}
// Copy pixels between sfrom sto (source image) to pixels from dfrom (destination img)
void CImage::CopyToImage(CImage *dest,int dfrom, int sfrom, int sto, short mode)
{
int i,j;
GetBitsPointer();
switch (mode)
{
case ALL_IMAGE :
if (dest->pHead->biSizeImage != pHead->biSizeImage)
{
AfxMessageBox ("The size of the two images are different !");
return;
}
for (i = 0; i < (int) pHead->biSizeImage; i++)
dest->pBits[i] = pBits[i];
break;
case TRUNK_IMAGE :
dfrom = dfrom * bPerPixel;
sfrom = sfrom * bPerPixel;
sto = sto * bPerPixel;
for (i = 0; i < pHead->biHeight; i++)
{
for (j = sfrom; j < sto; j++)
dest->Pixel[i][j+dfrom-sfrom] = Pixel[i][j];
}
break;
}
}
void CImage::Filter_3x3(CImage *dest, short chan, BOOL fast, MATRIX_3X3 mat)
{
int lig, col, index, height, width, t1, t2, t3;
int wTmp;
WORD *pW;
height = pHead->biHeight-1;
width = pHead->biWidth-1;
switch (chan)
{
case (RG_CHANNEL) :
case (RGB_CHANNEL) :
{
if (fast)
{
for (lig = 1; lig < height; lig++)
for (col = 1; col < width; col++)
{
t1 = (col-1)*bPerPixel;
t2 = (col+1)*bPerPixel;
pW = (WORD *) &Pixel[lig-1][t1];
wTmp = - (*pW);
pW = (WORD *) &Pixel[lig-1][t2];
wTmp += *pW;
pW = (WORD *) &Pixel[lig ][t1];
wTmp += *pW * -2;
pW = (WORD *) &Pixel[lig ][t2];
wTmp += *pW * 2;
pW = (WORD *) &Pixel[lig+1][t1];
wTmp += -(*pW);
pW = (WORD *) &Pixel[lig+1][t2];
wTmp += *pW;
// Take the absolute value of the gradient
wTmp = abs (wTmp);
}
}
else
{
for (lig = 1; lig < height; lig++)
for (col = 1; col < width; col++)
{
index = col * bPerPixel;
t1 = (col-1)*bPerPixel;
t2 = (col+1)*bPerPixel;
pW = (WORD *) &Pixel[lig-1][t1];
wTmp = *pW * mat[0][0];
pW = (WORD *) &Pixel[lig-1][index];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -