📄 dib.cpp
字号:
// set to m_hDib
Destroy();
m_hDib = hNewDib;
// return
return UpdateInternal();
}
BOOL CDib::FilteRGB(int nIndex)
{
HDIB hNewDib = FilteRGBfromDIB(m_hDib, nIndex);
if (! hNewDib)
return FALSE;
// set to m_hDib
Destroy();
m_hDib = hNewDib;
// return
return UpdateInternal();
}
BOOL CDib::ColorQuantize(int nColorBits)
{
HDIB hNewDib;
if (nColorBits > 8)
hNewDib = ConvertDIBFormat(m_hDib, nColorBits, NULL);
else
{
int nColors = 1<<nColorBits;
hNewDib = ColorQuantizeDIB(m_hDib, nColorBits, nColors);
}
if (! hNewDib)
return FALSE;
Destroy();
m_hDib = hNewDib;
return UpdateInternal();
}
BOOL CDib::ChangeToGrayscale(int nMethod, double fRedWeight, double fGreenWeight, double fBlueWeight)
{
HPALETTE hPal = ConvertToGrayscale(m_hDib, nMethod, fRedWeight, fGreenWeight, fBlueWeight);
if (hPal == NULL)
return FALSE;
// set new palette
if (m_pPalette != NULL)
delete m_pPalette;
m_pPalette = new CPalette;
m_pPalette->Attach(hPal);
// rebuild bitmap
return UpdateInternal();
}
BOOL CDib:: RegionSegAdaptive()
{
//遍历图象的纵坐标
int y;
//遍历图象的横坐标
int x;
//图象的长宽大小
int nWidth = GetWidth(); ;
int nHeight = GetHeight() ;
//图像在计算机在存储中的实际大小
//CSize sizeImageSave = pDib->GetDibSaveDim();
//图像在内存中每一行象素占用的实际空间
int nSaveWidth = GetWidthBytes();
//图像数据的指针
LPBYTE lpDIB = (LPBYTE)GlobalLock(m_hDib);
if (! lpDIB)
{
GlobalUnlock(m_hDib);
return NULL;
}
LPBYTE lpImage = FindDIBBits(lpDIB);
GlobalUnlock(m_hDib);
// 局部阈值
int nThd[2][2] ;
// 子图象的平均值
int nLocAvg ;
// 对左上图像逐点扫描:
nLocAvg = 0 ;
// y方向
for(y=0; y<nHeight/2 ; y++ )
{
// x方向
for(x=0; x<nWidth/2 ; x++ )
{
nLocAvg += lpImage[y*nSaveWidth + x];
}
}
// 计算均值
nLocAvg /= ( (nHeight/2) * (nWidth/2) ) ;
// 设置阈值为子图象的平均值
nThd[0][0] = nLocAvg ;
// 对左上图像逐点扫描进行分割:
// y方向
for(y=0; y<nHeight/2 ; y++ )
{
// x方向
for(x=0; x<nWidth/2 ; x++ )
{
if(lpImage[y*nSaveWidth + x]<nThd[0][0])
lpImage[y*nSaveWidth + x] = 255 ;
else
{
lpImage[y*nSaveWidth + x] = 0 ;
}
}
}
// =============================================
// 对左下图像逐点扫描:
nLocAvg = 0 ;
// y方向
for(y=nHeight/2; y<nHeight ; y++ )
{
// x方向
for(x=0; x<nWidth/2 ; x++ )
{
nLocAvg += lpImage[y*nSaveWidth + x];
}
}
// 计算均值
nLocAvg /= ( (nHeight - nHeight/2) * (nWidth/2) ) ;
// 设置阈值为子图象的平均值
nThd[1][0] = nLocAvg ;
// 对左下图像逐点扫描进行分割:
// y方向
for(y=nHeight/2; y<nHeight ; y++ )
{
// x方向
for(x=0; x<nWidth/2 ; x++ )
{
if(lpImage[y*nSaveWidth + x]<nThd[1][0])
lpImage[y*nSaveWidth + x] = 255 ;
else
{
lpImage[y*nSaveWidth + x] = 0 ;
}
}
}
// =============================================
// 对右上图像逐点扫描:
nLocAvg = 0 ;
// y方向
for(y=0; y<nHeight/2 ; y++ )
{
// x方向
for(x=nWidth/2; x<nWidth ; x++ )
{
nLocAvg += lpImage[y*nSaveWidth + x];
}
}
// 计算均值
nLocAvg /= ( (nHeight/2) * (nWidth - nWidth/2) ) ;
// 设置阈值为子图象的平均值
nThd[0][1] = nLocAvg ;
// 对右上图像逐点扫描进行分割:
// y方向
for(y=0; y<nHeight/2 ; y++ )
{
// x方向
for(x=nWidth/2; x<nWidth ; x++ )
{
if(lpImage[y*nSaveWidth + x]<nThd[0][1])
lpImage[y*nSaveWidth + x] = 255 ;
else
{
lpImage[y*nSaveWidth + x] = 0 ;
}
}
}
// =============================================
// 对右下图像逐点扫描:
nLocAvg = 0 ;
// y方向
for(y=nHeight/2; y<nHeight ; y++ )
{
// x方向
for(x=nWidth/2; x<nWidth ; x++ )
{
nLocAvg += lpImage[y*nSaveWidth + x];
}
}
// 计算均值
nLocAvg /= ( (nHeight - nHeight/2) * (nWidth - nWidth/2) ) ;
// 设置阈值为子图象的平均值
nThd[1][1] = nLocAvg ;
// 对右下图像逐点扫描进行分割:
// y方向
for(y=nHeight/2; y<nHeight ; y++ )
{
// x方向
for(x=nWidth/2; x<nWidth ; x++ )
{
if(lpImage[y*nSaveWidth + x]<nThd[1][1])
lpImage[y*nSaveWidth + x] = 255 ;
else
{
lpImage[y*nSaveWidth + x] = 0 ;
}
}
}
// 为了显示方便显示,逻辑1用黑色显示,逻辑0用白色显示
for(y=0; y<nHeight ; y++ )
{
// x方向
for(x=0; x<nWidth ; x++ )
{
lpImage[y*nSaveWidth + x] = 255 - lpImage[y*nSaveWidth + x] ;
}
}
return UpdateInternal();
}
BOOL CDib::ChangeToGray(int nMethod, double fRedWeight, double fGreenWeight, double fBlueWeight)
{ LONG height=GetHeight();
LONG width=GetWidth();
LONG size=GetHeight()*GetWidthBytes()/3+sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*256;
HDIB hnewdib= GlobalAlloc(GHND,size);
LPBYTE pold=(LPBYTE)GlobalLock(m_hDib);
LPBYTE pnew=(LPBYTE)GlobalLock(hnewdib);
memcpy(pnew,pold,sizeof(BITMAPINFOHEADER));
((LPBITMAPINFOHEADER)pnew)->biBitCount=8;
LPBYTE polddata=GetBitsPtr();
RGBQUAD* lprgb=(RGBQUAD*)((LPBYTE)pnew+sizeof(BITMAPINFOHEADER));
for(int k=0;k<256;k++)
{lprgb[k].rgbBlue=k;
lprgb[k].rgbGreen=k;
lprgb[k].rgbRed=k;
lprgb[k].rgbReserved=0;
}
LPBYTE newbyte=(LPBYTE)((LPBYTE)pnew)+sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*256;
for(int j=0;j<height;j++)
{
for(int i=0;i<width;i++)
{
LPBYTE src=polddata+j*GetWidthBytes()+i*3;
LPBYTE dst=newbyte+j*GetWidthBytes()/3+i;
switch (nMethod)
{
case MAXIMUM_GRAY:
{
*dst = max(max(*src,*(src+1)),
*(src+2));
}
break;
case MEAN_GRAY:
{
*dst = (BYTE)((*src+*(src+1)+*(src+2))/3);
}
break;
case WEIGHT_GRAY:
{
*dst = min(255,
(BYTE)((*(src+2))*fRedWeight +
(*(src+1))*fGreenWeight +
(*src)*fBlueWeight));
}
break;
}
}
}
Destroy();
m_hDib=hnewdib;
GlobalUnlock(m_hDib);
return UpdateInternal();
}
BOOL CDib::ZoomDib(float r)
{
LPBYTE lpDIB=(LPBYTE)GlobalLock(m_hDib);
// 源图像的宽度和高度
LONG lWidth;
LONG lHeight;
// 缩放后图像的宽度和高度
LONG lNewWidth;
LONG lNewHeight;
// 缩放后图像的宽度(lNewWidth',必须是4的倍数)
LONG lNewLineBytes;
// 指向源图像的指针
LPBYTE lpDIBBits;
// 指向源象素的指针
LPBYTE lpSrc;
LPBYTE lpSrc1;
// 缩放后新DIB句柄
HDIB hDIB;
// 指向缩放图像对应象素的指针
LPBYTE lpDst;
// 指向缩放图像的指针
LPBYTE lpNewDIB;
LPBYTE lpNewDIBBits;
// 指向BITMAPINFO结构的指针(Win3.0)
LPBITMAPINFOHEADER lpbmi;
// 指向BITMAPCOREINFO结构的指针
LPBITMAPCOREHEADER lpbmc;
// 循环变量(象素在新DIB中的坐标)
LONG i;
LONG j;
// 象素在源DIB中的坐标
LONG i0;
LONG j0;
// 图像每行的字节数
LONG lLineBytes;
// 找到源DIB图像象素起始位置
lpDIBBits = FindDIBBits(lpDIB);
GlobalUnlock(m_hDib);
// 获取图像的宽度
lWidth = DIBWidth(lpDIB);
// 计算图像每行的字节数
lLineBytes = BytesPerLine(lpDIB);
// 获取图像的高度
lHeight = ::DIBHeight(lpDIB);
// 计算缩放后的图像实际宽度
// 此处直接加0.5是由于强制类型转换时不四舍五入,而是直接截去小数部分
lNewWidth = (LONG) (DIBWidth(lpDIB) *r+0.5);
// 计算新图像每行的字节数
int k=DIBBitCount(lpDIB);
lNewLineBytes = WIDTHBYTES(lNewWidth * k);
// 计算缩放后的图像高度
lNewHeight = (LONG) (lHeight * r+0.5);
// 分配内存,以保存新DIB
hDIB = (HDIB) GlobalAlloc(GHND, lNewLineBytes * lNewHeight + *(LPDWORD)lpDIB +PaletteSize(lpDIB));
// 判断是否内存分配失败
if (hDIB == NULL)
{
// 分配内存失败
return NULL;
}
// 锁定内存
lpNewDIB = (BYTE* )::GlobalLock((HGLOBAL) hDIB);
// 复制DIB信息头和调色板
memcpy(lpNewDIB, lpDIB, *(LPDWORD)lpDIB +PaletteSize(lpDIB));
// 找到新DIB象素起始位置
lpNewDIBBits = FindDIBBits(lpNewDIB);
// 获取指针
lpbmi = (LPBITMAPINFOHEADER)lpNewDIB;
lpbmc = (LPBITMAPCOREHEADER)lpNewDIB;
// 更新DIB中图像的高度和宽度
if (IS_WIN30_DIB(lpNewDIB))
{
// 对于Windows 3.0 DIB
lpbmi->biWidth = lNewWidth;
lpbmi->biHeight = lNewHeight;
}
else
{
// 对于其它格式的DIB
lpbmc->bcWidth = (unsigned short) lNewWidth;
lpbmc->bcHeight = (unsigned short) lNewHeight;
}
// 针对图像每行进行操作
for(j = 0; j < lNewHeight; j++)
{
// 针对图像每列进行操作
for(i = 0; i < lNewWidth; i++)
{
// 指向新DIB第j行,第i个象素的指针
// 注意此处宽度和高度是新DIB的宽度和高度
if(k==8)
lpDst = (BYTE*)lpNewDIBBits + lNewLineBytes *j +i;
else
lpDst = (BYTE*)lpNewDIBBits + lNewLineBytes *j +i*3;
float m=(float)i/r;
int mmod=i-((int)m)*r;
float n=(float)j/r;
int nmod=j-((int)n)*r;
if(mmod==0)
{
if(nmod==0)
{
i0=(LONG)m; //case0
j0=(LONG)n;
if (k==8)
{
lpSrc=(BYTE*)lpDIBBits+lLineBytes*j0+i0;
*lpDst=*lpSrc;
}
else
{
lpSrc=(BYTE*)lpDIBBits+lLineBytes*j0+i0*3;
for (int l=0;l<3;l++)
{
*(lpDst+l)=*(lpSrc+l);
}
}
}
else //case 1
{
i0=(LONG)m;
j0=floor(n);
if(k==8)
{
lpSrc=(BYTE*)lpDIBBits+lLineBytes*j0+i0;
lpSrc1=(BYTE*)lpDIBBits+lLineBytes*(j0+1)+i0;
*lpDst=*(lpSrc)+(*(lpSrc1)-*(lpSrc))*(n-j0);
}
else
{ lpSrc=(BYTE*)lpDIBBits+lLineBytes*j0+i0*3;
lpSrc1=(BYTE*)lpDIBBits+lLineBytes*(j0+1)+i0*3;
for (int l=0;l<3;l++)
{
*(lpDst+l)=*(lpSrc+l)+(*(lpSrc1+l)-*(lpSrc+l))*(n-j0);
}
}
}
}
else
{
if(nmod==0) //case 2
{
i0=floor(m);
j0=(LONG)n;
if(k==8)
{ lpSrc=(BYTE*)lpDIBBits+lLineBytes*j0+i0;
lpSrc1=(BYTE*)lpDIBBits+lLineBytes*j0+i0+1;
*(lpDst)=*(lpSrc)+(*(lpSrc1)-*(lpSrc))*(m-i0);
}
else
{
lpSrc=(BYTE*)lpDIBBits+lLineBytes*j0+i0*3;
lpSrc1=(BYTE*)lpDIBBits+lLineBytes*j0+(i0+1)*3;
for (int l=0;l<3;l++)
{
*(lpDst+l)=*(lpSrc+l)+(*(lpSrc1+l)-*(lpSrc+l))*(m-i0);
}
}
}
else //case 3
{
i0=floor(m);
j0=floor(n);
if(k==8)
{
lpSrc=(BYTE*)lpDIBBits+lLineBytes*j0+i0;
lpSrc1=(BYTE*)lpDIBBits+lLineBytes*(j0+1)+i0;
BYTE a=*(lpSrc)+(*(lpSrc1)-*(lpSrc))*(n-j0);
BYTE b=*(lpSrc+1)+(*(lpSrc1+1)-*(lpSrc+1))*(n-j0);
*lpDst=a+(b-a)*(m-i0);
}
else
{
lpSrc=(BYTE*)lpDIBBits+lLineBytes*j0+i0*3;
lpSrc1=(BYTE*)lpDIBBits+lLineBytes*(j0+1)+i0*3;
BYTE a[3];
BYTE b[3];
for (int l=0;l<3;l++)
{
a[l]=*(lpSrc+l)+(*(lpSrc1+l)-*(lpSrc+l))*(n-j0);
b[l]=*(lpSrc+3+l)+(*(lpSrc1+3+l)-*(lpSrc+3+l))*(n-j0);
*(lpDst+l)=a[l]+(b[l]-a[l])*(m-i0);
}
}
}
}
}
}
GlobalUnlock(hDIB);
Destroy();
// 返回
m_hDib=hDIB;
return UpdateInternal();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -