www.pudn.com > raushon.rar > DibApiTestView.cpp
// DibApiTestView.cpp : implementation of the CDibApiTestView class
//
#include "stdAfx.h"
#include "DibApiTest.h"
#include "DibApiTestDoc.h"
#include "DibApiTestView.h"
#include "ConvertDLG.h"
#include "LinalChange.h"
#include "DlgGeoZoom.h"
#include "dlgGeoRota.h"
#include "DlgGeoTran.h"
#define DIB_HEADER_MARKER ((WORD) ('M' << 8) | 'B')
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CDibApiTestView
IMPLEMENT_DYNCREATE(CDibApiTestView, CScrollView)
BEGIN_MESSAGE_MAP(CDibApiTestView, CScrollView)
//{{AFX_MSG_MAP(CDibApiTestView)
ON_COMMAND(Convert, OnConvert)
ON_COMMAND(PointInvert, OnPointInvert)
ON_COMMAND(ID_Ditong, OnDitong)
ON_COMMAND(ID_Gaotong, OnGaotong)
ON_COMMAND(ID_Menuitem, OnMenuitem)
ON_COMMAND(ID_GeomZoom, OnGeomZoom)
ON_COMMAND(ID_Rotate, OnRotate)
ON_COMMAND(ID_Translation, OnTranslation)
ON_COMMAND(ID_zhuanzhi, Onzhuanzhi)
ON_COMMAND(ID_FDImage, OnFDImage)
ON_COMMAND(ID_DKImage, OnDKImage)
ON_COMMAND(ID_ImageDownScan, OnImageDownScan)
ON_COMMAND(IDM_ViewIntensity, OnViewIntensity)
//}}AFX_MSG_MAP
// Standard printing commands
ON_COMMAND(ID_FILE_PRINT, CScrollView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT, CScrollView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW, CScrollView::OnFilePrintPreview)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CDibApiTestView construction/destruction
CDibApiTestView::CDibApiTestView()
{
// TODO: add construction code here
}
CDibApiTestView::~CDibApiTestView()
{
}
BOOL CDibApiTestView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
return CScrollView::PreCreateWindow(cs);
}
/////////////////////////////////////////////////////////////////////////////
// CDibApiTestView drawing
void CDibApiTestView::OnDraw(CDC* pDC)
{
// 显示等待光标
BeginWaitCursor();
CDibApiTestDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc); //
// 获取DIB
HDIB hDIB = pDoc->GetHDIB();
// 判断DIB是否为空
if (hDIB != NULL)
{
LPSTR lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) hDIB);
// 获取DIB宽度
pDoc->m_width = (int) ::DIBWidth(lpDIB);
int cxDIB = (int) ::DIBWidth(lpDIB);
// 获取DIB高度
pDoc->m_height = (int) ::DIBHeight(lpDIB);
int cyDIB = (int) ::DIBHeight(lpDIB);
::GlobalUnlock((HGLOBAL) hDIB);
CRect rcDIB;
rcDIB.top = rcDIB.left =0;
rcDIB.right = cxDIB+rcDIB.top;
rcDIB.bottom = cyDIB+rcDIB.left;
CRect rcDest;
rcDest = rcDIB;
// 定义滚动条的滚动范围
CSize csSroll;
csSroll.cx = rcDIB.right;
csSroll.cy = rcDIB.bottom;
SetScrollSizes(MM_TEXT, csSroll);
::PaintDIB(pDC->m_hDC, &rcDest, pDoc->GetHDIB(),
&rcDIB, pDoc->GetDocPalette());
}
// 恢复正常光标
EndWaitCursor();
// TODO: add draw code for native data here
}
void CDibApiTestView::OnInitialUpdate()
{
CScrollView::OnInitialUpdate();
CSize sizeTotal;
// TODO: calculate the total size of this view
sizeTotal.cx = sizeTotal.cy = 100;
SetScrollSizes(MM_TEXT, sizeTotal);
}
/////////////////////////////////////////////////////////////////////////////
// CDibApiTestView printing
BOOL CDibApiTestView::OnPreparePrinting(CPrintInfo* pInfo)
{
// default preparation
return DoPreparePrinting(pInfo);
}
void CDibApiTestView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add extra initialization before printing
}
void CDibApiTestView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add cleanup after printing
}
/////////////////////////////////////////////////////////////////////////////
// CDibApiTestView diagnostics
#ifdef _DEBUG
void CDibApiTestView::AssertValid() const
{
CScrollView::AssertValid();
}
void CDibApiTestView::Dump(CDumpContext& dc) const
{
CScrollView::Dump(dc);
}
CDibApiTestDoc* CDibApiTestView::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CDibApiTestDoc)));
return (CDibApiTestDoc*)m_pDocument;
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CDibApiTestView message handlers
void CDibApiTestView::OnConvert()
{
CConvertDLG m_dlg;//????????????
if(m_dlg.DoModal()==IDOK)
{
UpdateData(true);
//?RAW????
CFile file_raw,file_bmp;
CFileException fe;
HDIB m_hDIB;
if (!file_raw.Open(m_dlg.m_RAW, CFile::modeReadWrite | CFile::shareDenyNone|CFile::typeBinary, &fe))
{
return ;
}
DWORD dwBitsSize = file_raw.GetLength();
m_hDIB=(HDIB) ::GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, dwBitsSize);//????????
if (m_hDIB== 0)
{
return ;
}
LPSTR pDIB = (LPSTR) ::GlobalLock((HGLOBAL) m_hDIB);//????????????
unsigned char*p;
//??:???i=1????,????0
p=(unsigned char *)pDIB;
for(int i=1;i<=m_dlg.m_height;i++)
{
//???--???????????--(-bmpinfo.biWidth)
if(m_dlg.m_Color==0)//???256????
file_raw.Seek(m_dlg.m_width*(-i),CFile::end);
else
file_raw.Seek(m_dlg.m_width*3*(-i),CFile::end);
{
if(m_dlg.m_Color==0)
{
file_raw.Read(pDIB,sizeof(BYTE)*m_dlg.m_width);
pDIB+=m_dlg.m_width;
}
else
{
file_raw.Read(pDIB,sizeof(BYTE)*3*m_dlg.m_width);
for(int j=0;j<3*m_dlg.m_width;j++)
{
unsigned char tempR=*(pDIB+j);
unsigned char tempG=*(pDIB+j+1);
unsigned char tempB=*(pDIB+j+2);
*(pDIB+j+2)=tempB;
*(pDIB+j)=tempG;
*(pDIB+j+1)=tempR;
}
pDIB+=3*m_dlg.m_width;
}
}
}
pDIB=(char *)p;
//?????
if (!file_bmp.Open(m_dlg.m_BMP, CFile::modeCreate|CFile::modeWrite |CFile::shareDenyNone, &fe))
{
return ;
}
// SaveDIB(m_HDib,file_bmp);
//???
///////////////////////////////////////////////////////////
SetCursor(LoadCursor(NULL,IDC_WAIT));
//?????
BITMAPFILEHEADER bmfHdr; // Header for Bitmap file
//??????
BITMAPINFOHEADER bmpinfo; // Pointer to DIB info structure
//????????
bmfHdr.bfType = DIB_HEADER_MARKER; // "BM"
if(m_dlg.m_Color==0)
{
bmfHdr.bfSize = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*256+dwBitsSize;
bmfHdr.bfOffBits = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*256;
}
if(m_dlg.m_Color==1)
{
bmfHdr.bfSize = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+dwBitsSize;
bmfHdr.bfOffBits = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);
}
bmfHdr.bfReserved1 = 0;
bmfHdr.bfReserved2 = 0;
//????????
////////////////////////////////////////////////////
long bits=8*m_dlg.m_width;
bmpinfo.biHeight=m_dlg.m_height;
bmpinfo.biWidth=m_dlg.m_width;
bmpinfo.biSize=(DWORD)sizeof(BITMAPINFOHEADER);//40
bmpinfo.biPlanes=(WORD)1;
if(m_dlg.m_Color==0)
bmpinfo.biBitCount=(WORD)8;//24
if(m_dlg.m_Color==1)
bmpinfo.biBitCount=(WORD)24;//24
bmpinfo.biCompression=BI_RGB;//?????
bmpinfo.biSizeImage=WIDTHBYTES(bits)*m_dlg.m_height;
bmpinfo.biXPelsPerMeter=0;
bmpinfo.biYPelsPerMeter=0;
bmpinfo.biClrUsed=0;//256
bmpinfo.biClrImportant=0;
//?????
////////////////////////////////////////////////////
RGBQUAD pPal[256];
for( i=0;i<256;i++)
{
pPal[i].rgbBlue=i;
pPal[i].rgbGreen=i;
pPal[i].rgbRed=i;
pPal[i].rgbReserved=0;
}
////////////////////////////////////////////////////
//???:??????????????????
////////////////////////////////////////////////////
//----------------------------------------------------------------
TRY
{
//?????
file_bmp.Write(&bmfHdr, sizeof(BITMAPFILEHEADER));
//????????
file_bmp.Write(&bmpinfo, sizeof(BITMAPINFOHEADER));
if(m_dlg.m_Color==0)
file_bmp.Write(pPal, sizeof(RGBQUAD)*256);
file_bmp.WriteHuge(pDIB,dwBitsSize);
}
CATCH (CException, e)
{
SetCursor(LoadCursor(NULL,IDC_ARROW));
::GlobalUnlock((HANDLE)m_hDIB);
return;
}
END_CATCH
//------------------------------------------------------------
file_bmp.Close();
SetCursor(LoadCursor(NULL,IDC_ARROW));
::GlobalUnlock((HANDLE)m_hDIB);
return;
}
// TODO: Add your command handler code here
}
void CDibApiTestView::OnPointInvert()
{
// TODO: Add your command handler code here
int max=255,min=0;
CLinalChange m_dlgc;
if(m_dlgc.DoModal()==IDOK)
{
CDibApiTestDoc *pDoc=GetDocument();
HDIB hDib=pDoc->m_hDIB;
if(hDib!=NULL)
{
LPSTR lpdib=(LPSTR)GlobalLock((HGLOBAL)hDib);
int width=DIBWidth(lpdib);
int height=DIBHeight(lpdib);
LPSTR lpDibBits=FindDIBBits(lpdib);
int bitcount=((LPBITMAPINFOHEADER)lpdib)->biBitCount;
if(bitcount==8)
{
for(int i=0;im_hDIB;
if (hDIB==NULL)
return;
LPSTR lpDIB=(LPSTR)GlobalLock((HGLOBAL)hDIB);
int width=DIBWidth(lpDIB);
int height=DIBHeight(lpDIB);
LPSTR lpDIBBits=FindDIBBits(lpDIB);
int bitcount=((LPBITMAPINFOHEADER)lpDIB)->biBitCount;
// 给模板数组赋初值
PixelValue[0]=0.1;
PixelValue[1]=0.1;
PixelValue[2]=0.1;
PixelValue[3]=0.1;
PixelValue[4]=0.2;
PixelValue[5]=0.1;
PixelValue[6]=0.1;
PixelValue[7]=0.1;
PixelValue[8]=0.1;
LPSTR lpNewDIBBits;
HLOCAL hNewDIBBits;
unsigned char* lpSrc;
unsigned char* lpDst;
long i,j,k,l;
double fResult;
long lLineBytes= WIDTHBYTES(width*8);
hNewDIBBits = LocalAlloc(LHND, lLineBytes*height);
lpNewDIBBits = (char * )LocalLock(hNewDIBBits);
memcpy(lpNewDIBBits, lpDIBBits, lLineBytes * height);
for(i = iTempMY; i 255)
{
* lpDst = 255;
}
else if(fResult<0) fResult=0;
else
{
* lpDst = (unsigned char) (fResult + 0.5);
}
}
}
memcpy(lpDIBBits, lpNewDIBBits, lLineBytes*height);
LocalUnlock(hNewDIBBits);
LocalFree(hNewDIBBits);
// return TRUE;
InvalidateRect(NULL,TRUE);
}
void CDibApiTestView::OnGaotong()
{
CDibApiTestDoc* pDoc=GetDocument();
int iTempH;
int iTempW;
int iTempMX;
int iTempMY;
float PixelValue[9];
HDIB hDIB;
hDIB=pDoc->m_hDIB;
if (hDIB==NULL)
return;
LPSTR lpDIB=(LPSTR)GlobalLock((HGLOBAL)hDIB);
int width=DIBWidth(lpDIB);
int height=DIBHeight(lpDIB);
LPSTR lpDIBBits=FindDIBBits(lpDIB);
int bitcount=((LPBITMAPINFOHEADER)lpDIB)->biBitCount;
iTempW = 3; // 拉普拉斯模板参数
iTempH = 3;
iTempMX = 1;
iTempMY = 1;
PixelValue[0] = -1.0;
PixelValue[1] = -1.0;
PixelValue[2] = -1.0;
PixelValue[3] = -1.0;
PixelValue[4] = 9.0;
PixelValue[5] = -1.0;
PixelValue[6] = -1.0;
PixelValue[7] = -1.0;
PixelValue[8] = -1.0;
LPSTR lpNewDIBBits;
HLOCAL hNewDIBBits;
unsigned char* lpSrc;
unsigned char* lpDst;
long i,j,k,l;
float fResult;
long lLineBytes= WIDTHBYTES(width*8);
hNewDIBBits = LocalAlloc(LHND, lLineBytes*height);
lpNewDIBBits = (char * )LocalLock(hNewDIBBits);
memcpy(lpNewDIBBits, lpDIBBits, lLineBytes * height);
for(i = iTempMY; i 255)
{
* lpDst = 255;
}
else
{
* lpDst = (unsigned char) (fResult + 0.5);
}
}
}
memcpy(lpDIBBits, lpNewDIBBits, lLineBytes*height);
LocalUnlock(hNewDIBBits);
LocalFree(hNewDIBBits);
InvalidateRect(NULL,TRUE);
}
void CDibApiTestView::OnMenuitem()
{
CDibApiTestDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
LPSTR pdib=(LPSTR)::GlobalLock((HGLOBAL)pDoc->m_hDIB);
LPBITMAPINFOHEADER lpbmi;
lpbmi = (LPBITMAPINFOHEADER)pdib;
LPSTR pstart;
pstart=::FindDIBBits(pdib);
int size;
int width;
width=((8) + 31) / 32 * 4;
size=lpbmi->biSizeImage;
long t1,t2,t3;
int i;
long a;
for(i=0;it3)
{
a=t2;t2=t3;t3=a;
pstart[i+1]=(char)t2;
}
pstart[i+1]=(char)t2;
}
else
{
a=t1;t1=t2;t2=a;
if(t2>t3)
{
a=t2;t2=t3;t3=a;
pstart[i+1]=(char)t2;
}
pstart[i+1]=(char)t2;
}
}
InvalidateRect(NULL,TRUE);
}
//缩放
void CDibApiTestView::OnGeomZoom()
{
CDibApiTestDoc *pDoc=GetDocument();
LPSTR lpDIB;
lpDIB=(LPSTR)::GlobalLock((HGLOBAL)pDoc->GetHDIB());
if(::DIBNumColors(lpDIB)!=256)
{
MessageBox("现在只支持256色图象的缩放,请确定再继续!",
"系统提示",MB_ICONINFORMATION|MB_OK);
::GlobalUnlock((HGLOBAL)pDoc->GetHDIB());
return;
}
float fXZoomRatio;
float fYZoomRatio;
CDlgGeoZoom dlgPara;
dlgPara.m_XZoom=0.5;
dlgPara.m_YZoom=0.5;
if(dlgPara.DoModal()!=IDOK)
{
return;
}
fXZoomRatio=dlgPara.m_XZoom;
fYZoomRatio=dlgPara.m_YZoom;
//创建新的DIB
HDIB hNewDIB=NULL;
BeginWaitCursor();
hNewDIB=(HDIB)::ZoomDIB(lpDIB,fXZoomRatio,fYZoomRatio);
//判断缩放是否成功
if(hNewDIB!=NULL)
{
//替换DIB,同时释放旧DIB对象
pDoc->ReplaceHDIB(hNewDIB);
//更新DIB大小和调色板
pDoc->InitDIBData();
//设置标记
pDoc->SetModifiedFlag(TRUE);
//重新设置滚动视图大小
SetScrollSizes(MM_TEXT,pDoc->GetDocSize());
//更新视图
pDoc->UpdateAllViews(NULL);
}
else
{
//提示用户
MessageBox("分配内存失败!",
"系统提示",MB_ICONINFORMATION|MB_OK);
}
::GlobalUnlock((HGLOBAL)pDoc->GetHDIB());
EndWaitCursor();
}
//旋转
void CDibApiTestView::OnRotate()
{
CDibApiTestDoc *pDoc=GetDocument();
LPSTR lpDIB;
lpDIB=(LPSTR)::GlobalLock((HGLOBAL)pDoc->GetHDIB());
if(::DIBNumColors(lpDIB)!=256)
{
MessageBox("现在只支持256色图象的缩放,请确定再继续!",
"系统提示",MB_ICONINFORMATION|MB_OK);
::GlobalUnlock((HGLOBAL)pDoc->GetHDIB());
return;
}
int iRotateAngle;
CdlgGeoRota dlgPara;
dlgPara.m_iRotateAngle=90;
if(dlgPara.DoModal()!=IDOK)
{
return;
}
//获取用户设定的旋转角度
iRotateAngle=dlgPara.m_iRotateAngle;
//创建新DIB
HDIB hNewDIB=NULL;
BeginWaitCursor();
//调用RotateDIB()函数旋转DIB
hNewDIB=(HDIB)::RotateDIB(lpDIB,iRotateAngle);
//判断旋转是否成功
if(hNewDIB!=NULL)
{
//替换DIB,同时释放旧DIB对象
pDoc->ReplaceHDIB(hNewDIB);
//更新DIB大小和调色板
pDoc->InitDIBData();
//设置标记
pDoc->SetModifiedFlag(TRUE);
//重新设置滚动视图大小
SetScrollSizes(MM_TEXT,pDoc->GetDocSize());
//更新视图
pDoc->UpdateAllViews(NULL);
}
else
{
//提示用户
MessageBox("分配内存失败!",
"系统提示",MB_ICONINFORMATION|MB_OK);
}
::GlobalUnlock((HGLOBAL)pDoc->GetHDIB());
EndWaitCursor();
}
//平移
void CDibApiTestView::OnTranslation()
{
CDibApiTestDoc *pDoc=GetDocument();
LPSTR lpDIB;//指向DIB的指针
LPSTR lpDIBBits;//指向DIB像素的指针
//锁定DIB
lpDIB=(LPSTR)::GlobalLock((HGLOBAL)pDoc->GetHDIB());
if(::DIBNumColors(lpDIB)!=256)
{
MessageBox("现在只支持256色图象的缩放,请确定再继续!",
"系统提示",MB_ICONINFORMATION|MB_OK);
::GlobalUnlock((HGLOBAL)pDoc->GetHDIB());
return;
}
LONG lXOffset;
LONG lYOffset;
CDlgGeoTran dlg;
dlg.m_Xoffset=50;
dlg.m_Yoffset=50;
if(dlg.DoModal()!=IDOK)
{
return;
}
lXOffset=dlg.m_Xoffset;
lYOffset=dlg.m_Yoffset;
BeginWaitCursor();
lpDIBBits=::FindDIBBits(lpDIB); //lpDIB为指向DIB的指针
//调用TranslationDIB()
if(::TranslationDIB(lpDIBBits,::DIBWidth(lpDIB),::DIBHeight(lpDIB),lXOffset,lYOffset))
{
//设置标记
pDoc->SetModifiedFlag(TRUE);
//更新视图
pDoc->UpdateAllViews(NULL);
}
else
{
//提示用户
MessageBox("分配内存失败!",
"系统提示",MB_ICONINFORMATION|MB_OK);
}
::GlobalUnlock((HGLOBAL)pDoc->GetHDIB());
EndWaitCursor();
}
//转置
void CDibApiTestView::Onzhuanzhi()
{
CDibApiTestDoc *pDoc=GetDocument();
LPSTR lpDIB;
lpDIB=(LPSTR)::GlobalLock((HGLOBAL)pDoc->GetHDIB());
if(::DIBNumColors(lpDIB)!=256)
{
MessageBox("现在只支持256色图象的缩放,请确定再继续!",
"系统提示",MB_ICONINFORMATION|MB_OK);
::GlobalUnlock((HGLOBAL)pDoc->GetHDIB());
return;
}
BeginWaitCursor();
if(::TransposeDIB(lpDIB))
{
//设置标记
pDoc->SetModifiedFlag(TRUE);
//更新DIB大小和调色板
pDoc->InitDIBData();
//重新设置滚动视图大小
SetScrollSizes(MM_TEXT,pDoc->GetDocSize());
//更新视图
pDoc->UpdateAllViews(NULL);
}
else
{
//提示用户
MessageBox("分配内存失败!",
"系统提示",MB_ICONINFORMATION|MB_OK);
}
::GlobalUnlock((HGLOBAL)pDoc->GetHDIB());
EndWaitCursor();
}
/********************************************************************************
"浮雕"图象效果是指图像的前景前向凸出背景.所谓的"浮雕"概念是指标绘图像上的一个像素
和它左上方的那个像素之间差值的一种处理过程,为了使图像保持一定的亮度并呈现灰色,
我在处理过程中为这个差值加了一个数值为128的常量。需要读者注意的是,当设置一个
像素值的时候,它和它左上方的像素都要被用到,为了避免用到已经设置过的像素,应该从
图像的右下方的像素开始处理
********************************************************************************/
void CDibApiTestView::OnFDImage()
{
HANDLE datahandle;//用来存放图像数据的句柄;
LPBITMAPINFOHEADER lpBi;
CDibApiTestDoc *pDoc=GetDocument();//得到文挡指针
unsigned char *pData; //指向原始图像数据的指针;
unsigned char *data;//指向处理后图像数据的指针;
//拷贝存放已经读取的图像文件数据句柄
lpBi=(LPBITMAPINFOHEADER)GlobalLock((HGLOBAL)pDoc->GetHDIB());//获取图像信息头
pData=(unsigned char *)FindDIBBits((LPSTR)lpBi);
//设置标记
pDoc->SetModifiedFlag(TRUE);
datahandle=GlobalAlloc(GMEM_SHARE,WIDTHBYTES(lpBi->biWidth*8)*lpBi->biHeight);
//声明一个缓冲区用来暂存处理后的图像数据
data=(unsigned char *)GlobalLock((HGLOBAL)datahandle);//得到该缓冲区的指针
BeginWaitCursor();
int i,j,buf;
for(i=lpBi->biHeight; i>=2; i--) //从图像右下角开始对图像的各个像素进行“浮雕”处理
for(j=lpBi->biWidth; j>=2; j--)
{
buf=*(pData+(lpBi->biHeight-i)*WIDTHBYTES(lpBi->biWidth*8)+j)-
*(pData+(lpBi->biHeight-i+1)*WIDTHBYTES(lpBi->biWidth*8)+j-1)+128;
if(buf>255) buf=255;
if(buf<0) buf=0;
*(data+(lpBi->biHeight-i)*WIDTHBYTES(lpBi->biWidth*8)+j)=(unsigned char)buf;
}
for( j=0; j<=lpBi->biHeight; j++)
for( i=0; i<=lpBi->biWidth; i++)//重新写回原始图像的数据缓冲区;
*(pData+j*WIDTHBYTES(lpBi->biWidth*8)+i)=*(data+j*WIDTHBYTES(lpBi->biWidth*8)+i);
pDoc->m_hDIB =pDoc->GetHDIB();//将处理过的图像数据写回pDoc中的图像缓冲区
::GlobalUnlock((HGLOBAL)pDoc->GetHDIB());//解锁、释放缓冲区
::GlobalUnlock((HGLOBAL)datahandle);
::GlobalFree((HGLOBAL)datahandle);
pDoc->UpdateAllViews(NULL);
EndWaitCursor();
}
/********************************************************************************
"雕刻"图像与之相反,它是通过取一个像素和它右下方的像素之间的差值并加上一个常数,
这里我也取128,经过这样处理,就可以得到"雕刻"图像,这时候图像的前景凹陷进背景之中
。同样需要读者注意的是为了避免重复使用处理过的图像像素,处理图像时要从图像的左上
方的像素开始处理。
********************************************************************************/
void CDibApiTestView::OnDKImage()
{
HANDLE datahandle;//用来存放图像数据的句柄;
LPBITMAPINFOHEADER lpBi;
CDibApiTestDoc *pDoc=GetDocument();//得到文挡指针
unsigned char *pData; //指向原始图像数据的指针;
unsigned char *data;//指向处理后图像数据的指针;
//拷贝存放已经读取的图像文件数据句柄
lpBi=(LPBITMAPINFOHEADER)GlobalLock((HGLOBAL)pDoc->GetHDIB());//获取图像信息头
pData=(unsigned char *)FindDIBBits((LPSTR)lpBi);
pDoc->SetModifiedFlag(TRUE);datahandle=GlobalAlloc(GMEM_SHARE,WIDTHBYTES(lpBi->biWidth*8)*lpBi->biHeight);
data=(unsigned char *)GlobalLock((HGLOBAL)datahandle);//得到该缓冲区的指针
BeginWaitCursor();
int i,j,buf;
for(i=lpBi->biHeight; i>=2; i--) //从图像右下角开始对图像的各个像素进行“浮雕”处理
for(j=lpBi->biWidth; j>=2; j--)
{
buf=*(pData+(lpBi->biHeight-i)*WIDTHBYTES(lpBi->biWidth*8)+j)-
*(pData+(lpBi->biHeight-i-1)*WIDTHBYTES(lpBi->biWidth*8)+j+1)+128;//"雕刻"处理
if(buf>255) buf=255;
if(buf<0) buf=0;
*(data+(lpBi->biHeight-i)*WIDTHBYTES(lpBi->biWidth*8)+j)=(BYTE)buf;
}
for( j=0; j<=lpBi->biHeight; j++)
for( i=0; i<=lpBi->biWidth; i++)//重新写回原始图像的数据缓冲区;
*(pData+j*WIDTHBYTES(lpBi->biWidth*8)+i)=*(data+j*WIDTHBYTES(lpBi->biWidth*8)+i);
pDoc->m_hDIB =pDoc->GetHDIB();//将处理过的图像数据写回pDoc中的图像缓冲区
::GlobalUnlock((HGLOBAL)pDoc->GetHDIB());//解锁、释放缓冲区
::GlobalUnlock((HGLOBAL)datahandle);
::GlobalFree((HGLOBAL)datahandle);
pDoc->UpdateAllViews(NULL);
EndWaitCursor();
}
void CDibApiTestView::OnImageDownScan()
{
CDibApiTestDoc *pDoc=GetDocument();
HDIB hdib;
CClientDC pDC(this);
hdib=pDoc->m_hDIB;//获取图像数据句柄;
BITMAPINFOHEADER *lpDIBHdr;//位图信息头结构指针;
BYTE *lpDIBBits;//指向位图像素灰度值的指针;
HDC hDC=pDC.GetSafeHdc();//获取当前设备上下文的句柄;
lpDIBHdr=( BITMAPINFOHEADER *)GlobalLock(hdib);//得到图像的位图头信息;
lpDIBBits=(BYTE*)lpDIBHdr+sizeof(BITMAPINFOHEADER)+256*sizeof(RGBQUAD);
//获取指向图像像素值
SetStretchBltMode(hDC,COLORONCOLOR);
//显示图像;
for(int i=0;ibiHeight;i++)
{
SetDIBitsToDevice(hDC,0,0,lpDIBHdr->biWidth,lpDIBHdr->biHeight,
0, 0,0, i,lpDIBBits,(LPBITMAPINFO)lpDIBHdr,DIB_RGB_COLORS);
Sleep(100);//延迟;
}
GlobalUnlock(hdib);
return;
/* CBrush brush(crWhite);//定义一个"白色"的刷子;
CBrush *oldbrush=pDC->SelectObject(&brush);
for(i=0;ibiHeight;i++)
{
pDC->Rectangle(0,0,lpDIBHdr->biWidth,lpDIBHdr->biHeight);
Sleep(50);
}
*/
}
void CDibApiTestView::OnViewIntensity()
{
// 查看当前图像灰度直方图
// 获取文档
CDibApiTestDoc* pDoc = GetDocument();
long i,j;
int nNs_Y[256];
memset(nNs_Y,0,sizeof(nNs_Y));
// 指向DIB的指针
LPSTR lpDIB;
// 指向DIB象素指针
LPSTR lpDIBBits;
// 锁定DIB
lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) pDoc->GetHDIB());
// 找到DIB图像象素起始位置
lpDIBBits = ::FindDIBBits(lpDIB);
// 判断是否是8-bpp位图(这里为了方便,只处理8-bpp位图,其它的可以类推)
if (::DIBNumColors(lpDIB) != 256)
{
// 提示用户
MessageBox("目前只支持查看256色位图灰度直方图!", "系统提示" , MB_ICONINFORMATION | MB_OK);
// 解除锁定
::GlobalUnlock((HGLOBAL) pDoc->GetHDIB());
// 返回
return;
}
// 更改光标形状
BeginWaitCursor();
long lWidth=::DIBWidth(lpDIB);
long lHeight=::DIBHeight(lpDIB);
long lLineBytes=WIDTHBYTES(lWidth*8);
for(i=0;iGetHDIB());
// 恢复光标
EndWaitCursor();
///////////直方图显示部分
CString str;
// 最大计数
LONG lMaxCount = 0;
// 设备上下文
CPaintDC dc(this);
CDC* pDC =GetDC();
CRect clientRect;
GetClientRect(&clientRect);
int cx = clientRect.Width();
int cy = clientRect.Height();
pDC->Rectangle(0,0,cx,cy);
// 创建画笔对象
CPen* pPenRed = new CPen;
// 红色画笔
pPenRed->CreatePen(PS_SOLID,1,RGB(255,0,0));
// 创建画笔对象
CPen* pPenBlue = new CPen;
// 蓝色画笔
pPenBlue->CreatePen(PS_SOLID,1,RGB(0,0, 255));
// 创建画笔对象
CPen* pPenGreen = new CPen;
// 绿色画笔
pPenGreen->CreatePen(PS_DOT,1,RGB(0,255,0));
// 选中当前红色画笔,并保存以前的画笔
CGdiObject* pOldPen = pDC->SelectObject(pPenRed);
// 绘制坐标轴
pDC->MoveTo(cx/3+10,cy/3+10);
// 垂直轴
pDC->LineTo(cx/3+10,cy/3+280);
// 水平轴
pDC->LineTo(cx/3+320,cy/3+280);
// 写X轴刻度值
str.Format("0");
pDC->TextOut(cx/3+10, cy/3+283, str);
str.Format("50");
pDC->TextOut(cx/3+60, cy/3+283, str);
str.Format("100");
pDC->TextOut(cx/3+110, cy/3+283, str);
str.Format("150");
pDC->TextOut(cx/3+160, cy/3+283, str);
str.Format("200");
pDC->TextOut(cx/3+210, cy/3+283, str);
str.Format("255");
pDC->TextOut(cx/3+265, cy/3+283, str);
// 绘制X轴刻度
for (i = 0; i < 256; i += 5)
{
if ((i & 1) == 0)
{
// 10的倍数
pDC->MoveTo(cx/3+i + 10, cy/3+280);
pDC->LineTo(cx/3+i + 10, cy/3+284);
}
else
{
// 10的倍数
pDC->MoveTo(cx/3+i + 10, cy/3+280);
pDC->LineTo(cx/3+i + 10, cy/3+282);
}
}
// 绘制X轴箭头
pDC->MoveTo(cx/3+315,cy/3+275);
pDC->LineTo(cx/3+320,cy/3+280);
pDC->LineTo(cx/3+315,cy/3+285);
// 绘制Y轴箭头
pDC->MoveTo(cx/3+10,cy/3+10);
pDC->LineTo(cx/3+5,cy/3+15);
pDC->MoveTo(cx/3+10,cy/3+10);
pDC->LineTo(cx/3+15,cy/3+15);
// 各个灰度值的计数,重置计数为0
// LONG m_lCount[256]={0};
// 计算最大计数值
for (i = 0; i <= 255; i ++)
{
// 判断是否大于当前最大值
if (nNs_Y[i] > lMaxCount)
{
// 更新最大值
lMaxCount = nNs_Y[i];
}
}
// 输出最大计数值
pDC->MoveTo(cx/3+10, cy/3+25);
pDC->LineTo(cx/3+14, cy/3+25);
str.Format("%d", lMaxCount);
pDC->TextOut(cx/3+11, cy/3+26, str);
// 更改成绿色画笔
pDC->SelectObject(pPenGreen);
// 更改成蓝色画笔
pDC->SelectObject(pPenBlue);
// 判断是否有计数
if (lMaxCount > 0)
{
// 绘制直方图
for (i = 0; i <=255; i++)
{
pDC->MoveTo(cx/3+i + 10, cy/3+280);
pDC->LineTo(cx/3+i + 10, cy/3+281 - (int) (nNs_Y[i]* 256 / lMaxCount));
}
}
// 恢复以前的画笔
pDC->SelectObject(pOldPen);
// 删除新的画笔
delete pPenRed;
delete pPenBlue;
delete pPenGreen;
//更新视图
//pDoc->UpdateAllViews(NULL);
}