📄 dibimage.cpp
字号:
{
case 1:
return 2;
break;
case 4:
return 16;
break;
case 8:
return 256;
break;
default:
return 0;
break;
}
}
/*************************************************************************
* 函数名称:
* CopyHandle()
* 参数:
* HGLOBAL h - 要复制的内存区域
* 返回值:
* HGLOBAL - 复制后的新内存区域
* 说明:
* 该函数复制指定的内存区域。返回复制后的新内存区域,出错时返回0。
************************************************************************/
HGLOBAL CDibImage::CopyHandle (HGLOBAL h)
{
if (h == NULL)
{
return NULL;
}
DWORD dwLen = ::GlobalSize((HGLOBAL) h); // 获取指定内存区域大小
HGLOBAL hCopy = ::GlobalAlloc(GHND, dwLen); // 分配新内存空间
if (hCopy != NULL) // 判断分配是否成功
{
void* lpCopy = ::GlobalLock((HGLOBAL) hCopy);
void* lp = ::GlobalLock((HGLOBAL) h);
memcpy(lpCopy, lp, dwLen);
::GlobalUnlock(hCopy);
::GlobalUnlock(h);
}
return hCopy;
}
/*************************************************************************
* 函数名称:
* SaveDIB()
* 参数:
* HDIB hDib - 要保存的DIB
* CFile& file - 保存文件CFile
* 返回值:
* BOOL - 成功返回TRUE,否则返回FALSE或者CFileException
* 说明:
* 该函数将指定的DIB对象保存到指定的CFile中。该CFile由调用程序打开和关闭。
*************************************************************************/
BOOL CDibImage::SaveDIB(HDIB hDib, CFile& file)
{
BITMAPFILEHEADER bmfHdr; // Bitmap文件头
LPBITMAPINFOHEADER lpBI; // 指向BITMAPINFOHEADER的指针
DWORD dwDIBSize; // DIB大小
if (hDib == NULL)
{
return FALSE;
}
// 读取BITMAPINFO结构,并锁定
lpBI = (LPBITMAPINFOHEADER) ::GlobalLock((HGLOBAL) hDib);
if (lpBI == NULL)
{
return FALSE;
}
// 判断是否是WIN3.0 DIB
if (!IS_WIN30_DIB(lpBI))
{
// 不支持其它类型的DIB保存
::GlobalUnlock((HGLOBAL) hDib);
return FALSE;
}
////////////////////////////////////////////////////////////////////////
// 填充文件头///////////////////////////////////////////////////////////
bmfHdr.bfType = DIB_HEADER_MARKER; // 文件类型"BM"
// 计算DIB大小时,最简单的方法是调用GlobalSize()函数。但是全局内存大小并
// 不是DIB真正的大小,它总是多几个字节。这样就需要计算一下DIB的真实大小。
// 文件头大小+颜色表大小
// (BITMAPINFOHEADER和BITMAPCOREHEADER结构的第一个DWORD都是该结构的大小)
dwDIBSize = *(LPDWORD)lpBI + PaletteSize((LPSTR)lpBI);
// 计算图像大小
if ((lpBI->biCompression == BI_RLE8) || (lpBI->biCompression == BI_RLE4))
{
// 对于RLE位图,没法计算大小,只能信任biSizeImage内的值
dwDIBSize += lpBI->biSizeImage;
}
else
{
DWORD dwBmBitsSize; // 象素的大小
dwBmBitsSize = WIDTHBYTES((lpBI->biWidth)*((DWORD)lpBI->biBitCount))
* lpBI->biHeight; // 大小为Width * Height
dwDIBSize += dwBmBitsSize; // 计算出DIB真正的大小
// 更新biSizeImage(很多BMP文件头中biSizeImage的值是错误的)
lpBI->biSizeImage = dwBmBitsSize;
}
// 计算文件大小:DIB大小+BITMAPFILEHEADER结构大小
bmfHdr.bfSize = dwDIBSize + sizeof(BITMAPFILEHEADER);
// 两个保留字
bmfHdr.bfReserved1 = 0;
bmfHdr.bfReserved2 = 0;
// 计算偏移量bfOffBits,它的大小为Bitmap文件头大小+DIB头大小+颜色表大小
bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + lpBI->biSize
+ PaletteSize((LPSTR)lpBI);
/////////////////////////////////////////////////////////////////////////
// 尝试写文件////////////////////////////////////////////////////////////
TRY
{
file.Write((LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER)); // 写文件头
file.WriteHuge(lpBI, dwDIBSize); // 写DIB头和象素
}
CATCH (CFileException, e)
{
::GlobalUnlock((HGLOBAL) hDib);
THROW_LAST();
}
END_CATCH
::GlobalUnlock((HGLOBAL) hDib);
return TRUE;
}
/*************************************************************************
* 函数名称:
* ReadDIBFile()
* 参数:
* CFile& file - 要读取得文件文件CFile
* 返回值:
* HDIB - 成功返回DIB的句柄,否则返回NULL。
* 说明:
* 该函数将指定的文件中的DIB对象读到指定的内存区域中。除BITMAPFILEHEADER
* 外的内容都将被读入内存。
*************************************************************************/
HDIB CDibImage::ReadDIBFile(CFile& file)
{
BITMAPFILEHEADER bmfHeader;
HDIB hDIB;
LPSTR pDIB;
DWORD dwBitsSize;
dwBitsSize = file.GetLength(); // 获取DIB(文件)长度(字节)
// 尝试读取DIB文件头
if (file.Read((LPSTR)&bmfHeader, sizeof(bmfHeader)) != sizeof(bmfHeader))
{
return NULL;
}
// 判断是否是DIB对象,检查头两个字节是否是"BM"
if (bmfHeader.bfType != DIB_HEADER_MARKER)
{
return NULL;
}
// 为DIB分配内存
hDIB = (HDIB) ::GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, dwBitsSize);
if (hDIB == 0)
{
return NULL;
}
pDIB = (LPSTR) ::GlobalLock((HGLOBAL) hDIB);
if (file.ReadHuge(pDIB, dwBitsSize - sizeof(BITMAPFILEHEADER)) !=
dwBitsSize - sizeof(BITMAPFILEHEADER) ) // 读象素
{
::GlobalUnlock((HGLOBAL) hDIB);
::GlobalFree((HGLOBAL) hDIB);
return NULL;
}
::GlobalUnlock((HGLOBAL) hDIB);
return hDIB;
}
//DEL BOOL CDibImage::JuanJi(CDib *pDib)
//DEL {
//DEL //BYTE* lpSrc;
//DEL
//DEL LONG lWidth = pDib->GetDimensions().cx;
//DEL LONG lHeight = pDib->GetDimensions().cy;
//DEL
//DEL LONG lLineBytes = WIDTHBYTES(lWidth * 8); // 图像每行的字节数
//DEL
//DEL LPBYTE lpDIBits = pDib->m_lpImage; //Get the point of image data
//DEL
//DEL //int sum = (m_num0 + m_num1 + m_num2 + m_num3 );
//DEL
//DEL float fCoef = 0 ;
//DEL
//DEL return true;
//DEL }
BOOL CDibImage::JuanJi(CDib *pDib, float *pdpTemp, float modelFc)
{
//point to saved image
LPBYTE lpImage;
//variable
int i ,j,k,l;
// point to original image
unsigned char* lpSrc;
// Point to the copied area
unsigned char* lpDst;
//The result
float dbResult;
//Image size
CSize sizeImage = pDib->GetDimensions();
//the storage size
int nSizeImage = pDib->GetSizeImage();
lpImage = (LPBYTE) new char[nSizeImage];
if (lpImage == NULL) {
return FALSE;
}
//Copy data of original to variable
memcpy(lpImage,pDib->m_lpImage,nSizeImage);
// to JuanJi
for (i = 1; i < sizeImage.cy - 1; i++)
{
for (j = 1; j < sizeImage.cx - 1; j++)
{
lpDst = (unsigned char*)lpImage + pDib->GetPixelOffset(i,j);
dbResult = 0;
//to calculate
for (k = 0; k < 3; k++)
{
for (l = 0; l < 3; l++)
{
lpSrc = (unsigned char*)pDib->m_lpImage +
pDib->GetPixelOffset(i - 1 + k,j - 1 + l);
dbResult += (*lpSrc) * pdpTemp[k * 3 + 1];
}
}
dbResult *= modelFc;
dbResult = (float)fabs(dbResult);
if (dbResult > 255)
{
*lpDst = 255;
}
else
{
*lpDst = (unsigned char)(dbResult + 0.5);
}
}
}
memcpy(pDib->m_lpImage,lpImage,nSizeImage);
delete[]lpImage;
return TRUE;
}
//DEL BOOL CDibImage::Fourier(LPSTR lpDIBBits, LONG lWidth, LONG lHeight)
//DEL {
//DEL
//DEL }
/*************************************************************************
* 函数名称:
* FFT()
* 参数:
* complex<double> * TD - 指向时域数组的指针
* complex<double> * FD - 指向频域数组的指针
* r -2的幂数,即迭代次数
* 返回值:
* 无。
* 说明:
* 该函数用来实现快速付立叶变换。
************************************************************************/
//DEL VOID CDibImage::FFT(complex<double> * TD, complex<double> * FD, int r)
//DEL {
//DEL const double PI = 3.1415926535;
//DEL
//DEL LONG count; // 付立叶变换点数
//DEL int i,j,k; // 循环变量
//DEL int bfsize,p;
//DEL double angle; // 角度
//DEL complex<double> *W,*X1,*X2,*X;
//DEL
//DEL count = 1 << r; // 计算付立叶变换点数
//DEL
//DEL // 分配运算所需存储器
//DEL W = new complex<double>[count / 2];
//DEL X1 = new complex<double>[count];
//DEL X2 = new complex<double>[count];
//DEL
//DEL // 计算加权系数
//DEL for(i = 0; i < count / 2; i++)
//DEL {
//DEL angle = -i * PI * 2 / count;
//DEL W[i] = complex<double> (cos(angle), sin(angle));
//DEL }
//DEL
//DEL // 将时域点写入X1
//DEL memcpy(X1, TD, sizeof(complex<double>) * count);
//DEL
//DEL // 采用蝶形算法进行快速付立叶变换
//DEL for(k = 0; k < r; k++)
//DEL {
//DEL for(j = 0; j < 1 << k; j++)
//DEL {
//DEL bfsize = 1 << (r-k);
//DEL for(i = 0; i < bfsize / 2; i++)
//DEL {
//DEL p = j * bfsize;
//DEL X2[i + p] = X1[i + p] + X1[i + p + bfsize / 2];
//DEL X2[i + p + bfsize / 2] = (X1[i + p] - X1[i + p + bfsize / 2])
//DEL * W[i * (1<<k)];
//DEL }
//DEL }
//DEL X = X1;
//DEL X1 = X2;
//DEL X2 = X;
//DEL }
//DEL
//DEL // 重新排序
//DEL for(j = 0; j < count; j++)
//DEL {
//DEL p = 0;
//DEL for(i = 0; i < r; i++)
//DEL {
//DEL if (j&(1<<i))
//DEL {
//DEL p+=1<<(r-i-1);
//DEL }
//DEL }
//DEL FD[j]=X1[p];
//DEL }
//DEL
//DEL delete W;
//DEL delete X1;
//DEL delete X2;
//DEL }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -