photoshowview.cpp
来自「VS2005图像处理程序的源代码」· C++ 代码 · 共 1,106 行 · 第 1/2 页
CPP
1,106 行
}
CView::OnMouseMove(nFlags, point);
}
void CphotoshowView::OnLButtonDown(UINT nFlags, CPoint point)
{
m_psMove = point;
CView::OnLButtonDown(nFlags, point);
}
BOOL CphotoshowView::OnEraseBkgnd(CDC* pDC)
{
return TRUE;
}
BOOL CphotoshowView::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
if (m_bHeightOut || m_bWidhtOut)
{
SetCursor(::LoadCursor(NULL, IDC_SIZEALL));
return TRUE;
}
else
return CView::OnSetCursor(pWnd, nHitTest, message);
}
void CphotoshowView::FixOffset(void)
{
if (m_nPos < 0 || m_nPos >= m_nPicNum)
return;
Image image(GetFilePath(m_nPos));
if ( image.GetLastStatus() != Ok )
return;
m_bHeightOut = false;
m_bWidhtOut = false;
CSize imgSize = GetShowPicSize(image);
CRect rect;
GetClientRect(rect);
if (imgSize.cx > rect.Width())
{
m_nXXMax = imgSize.cx - rect.Width();
m_bWidhtOut = true;
}
if (imgSize.cy > rect.Height())
{
m_nYYMax = imgSize.cy - rect.Height();
m_bHeightOut = true;
}
}
void CphotoshowView::OnPointHistogram()
{
if(m_nPos==-1){
MessageBox(L"请先打开图像文件!");
return;
}
CHistogramDlg dlg;
ResetImage();
dlg.DoModal();
}
void CphotoshowView::ResetImage()
{
m_nTempWidth = m_nPicWidth;
m_nTempHeight = m_nPicHeight;
int sizeofbuffer = m_nTempWidth * m_nTempHeight * 4;
SAFE_DELETE (m_pImageTempBuffer);
m_pImageTempBuffer = new BYTE[sizeofbuffer];
memcpy(m_pImageTempBuffer, m_pImageBuffer, sizeofbuffer);
}
/******************************************************************************
* 作用: 将指定路径的图像信息提取到数组中
* 参数:
* strPath 图像文件地址
******************************************************************************/
bool CphotoshowView::GetImageBuffer(CString& strPath)
{
CString fileNameExt = strPath.Right(3);
string filePath = (LPCSTR)CStringA(strPath);
if (fileNameExt == "jpg" || fileNameExt == "JPG")
{
FILE *fp;
fp = fopen(filePath.c_str(), "rb");
JpegDecoder dec(fp);
fclose(fp);
m_nPicWidth = m_nTempWidth = dec.GetWidth();
m_nPicHeight = m_nTempHeight = dec.GetHeight();
dec.GetJPEGBuffer(m_nPicWidth, m_nPicHeight,&m_pImageBuffer);
int sizeb = m_nPicWidth * m_nPicHeight * 4;
m_pImageTempBuffer = (BYTE*)malloc(sizeb);
memcpy(m_pImageTempBuffer, m_pImageBuffer, sizeb);
}
if (fileNameExt == "bmp" || fileNameExt == "BMP")
{
MyDib* dib = new MyDib(strPath);
int b = dib->GetBitsPerPixel();
m_nPicWidth = m_nTempWidth = dib->GetWidth();
m_nPicHeight = m_nTempHeight = dib->GetHeight();
int sizeofbuffer = m_nPicWidth * m_nPicHeight * 4;
m_pImageTempBuffer = (BYTE *)malloc(sizeofbuffer);
m_pImageBuffer = (BYTE *)malloc(dib->GetBodySize());
memcpy(m_pImageBuffer, dib->GetBits(), dib->GetBodySize());
SAFE_DELETE (dib);
if ( b != 24 && b != 32 && b != 8 )
{
free(m_pImageTempBuffer);
free(m_pImageBuffer);
MessageBox(L"本程序仅能处理24位与32位彩色图和8位灰度图!");
return false;
}
if (b == 32)
{
for(unsigned int i = 0; i < m_nPicWidth * 4; i += 4)
{
for (unsigned int j = 0; j < m_nPicHeight / 2; j++)
{
swap(m_pImageBuffer[j*m_nPicWidth*4+i], m_pImageBuffer[(m_nPicHeight-j-1)*m_nPicWidth*4+i]);
swap(m_pImageBuffer[j*m_nPicWidth*4+i+1], m_pImageBuffer[(m_nPicHeight-j-1)*m_nPicWidth*4+i+1]);
swap(m_pImageBuffer[j*m_nPicWidth*4+i+2], m_pImageBuffer[(m_nPicHeight-j-1)*m_nPicWidth*4+i+2]);
swap(m_pImageBuffer[j*m_nPicWidth*4+i+3], m_pImageBuffer[(m_nPicHeight-j-1)*m_nPicWidth*4+i+3]);
}
}
memcpy(m_pImageTempBuffer, m_pImageBuffer, sizeofbuffer);
}
if (b == 24)
{
int externWidth;
externWidth = m_nPicWidth * 3;
if(externWidth % 4 != 0)
externWidth = 4 - externWidth % 4;
else
externWidth = 0;
int k = 0;
for (int n = m_nPicHeight - 1; n >= 0; n--)
{
for (UINT m = 0; m < m_nPicWidth * 3; m += 3)
{
m_pImageTempBuffer[k] = m_pImageBuffer[n*(m_nPicWidth*3+externWidth)+m]; //blue
m_pImageTempBuffer[k+1] = m_pImageBuffer[n*(m_nPicWidth*3+externWidth)+m+1];//green
m_pImageTempBuffer[k+2] = m_pImageBuffer[n*(m_nPicWidth*3+externWidth)+m+2];//red
m_pImageTempBuffer[k+3] = 255;
k += 4;
}
}
free(m_pImageBuffer);
m_pImageBuffer = (BYTE *)malloc(sizeofbuffer);
memcpy(m_pImageBuffer, m_pImageTempBuffer, sizeofbuffer);
}
if (b==8) {
int externWidth;
externWidth = m_nPicWidth;
if(externWidth%4!=0)
externWidth=4-externWidth%4;
else
externWidth=0;
int k = 0;
for (int n=m_nPicHeight-1; n>=0; n--) {
for (UINT m=0; m<m_nPicWidth; m+=1) {
m_pImageTempBuffer[k] =m_pImageBuffer[n*(m_nPicWidth+externWidth)+m];//blue
m_pImageTempBuffer[k+1]=m_pImageBuffer[n*(m_nPicWidth+externWidth)+m];//green
m_pImageTempBuffer[k+2]=m_pImageBuffer[n*(m_nPicWidth+externWidth)+m];//red
m_pImageTempBuffer[k+3]=0;
k+=4;
}
}
free(m_pImageBuffer);
m_pImageBuffer = (BYTE*)malloc(sizeofbuffer);
memcpy(m_pImageBuffer, m_pImageTempBuffer, sizeofbuffer);
}
}
return true;
}
void CphotoshowView::FreeImageBuffer(void)
{
if (m_pImageBuffer != NULL)
{
free(m_pImageBuffer);
m_pImageBuffer = NULL;
}
if (m_pImageTempBuffer != NULL)
{
free(m_pImageTempBuffer);
m_pImageTempBuffer = NULL;
}
}
void CphotoshowView::OnPointLinetran()
{
if(m_nPos==-1){
MessageBox(L"请先打开图像文件!");
return;
}
CLineTranDlg dlg;
ResetImage();
dlg.DoModal();
}
void CphotoshowView::OnFileSave()
{
if (m_nPos == -1)
{
MessageBox(L"工作区中未加载图片文件!", L"photoshow", MB_ICONWARNING);
return;
}
if (m_pImageTempBuffer == NULL)
{
MessageBox(L"没有可以保存的文件!", L"photoshow", MB_ICONWARNING);
return;
}
CFileDialog SaveDlg( FALSE, L"bmp", L"未命名", OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT | OFN_NOCHANGEDIR, L"图像文件格式(*.bmp) |*.bmp||", NULL);
if(SaveDlg.DoModal() == IDOK)
{
CString tempname = SaveDlg.GetPathName();
string savePath = (LPCSTR)CStringA(tempname);
WriteBufferToBMP(m_pImageTempBuffer, m_nTempWidth, m_nTempHeight, savePath.c_str());
tempname.ReleaseBuffer();
MessageBox(L"文件已成功保存!");
}
}
void CphotoshowView::WriteBufferToBMP(BYTE *im_buffer, WORD X_bitmap, WORD Y_bitmap, const char* BMPname)
{
SWORD x,y;
RGB *pixel;
BM_header BH;
FILE *fp_bitmap;
DWORD im_loc_bytes;
BYTE nr_fillingbytes, i;
BYTE zero_byte=0;
fp_bitmap=fopen(BMPname,"wb");
if (fp_bitmap==NULL)
{
AfxMessageBox(L"错误! 文件无法创建.", MB_ICONWARNING);
return;
}
if (X_bitmap%4!=0) nr_fillingbytes=4-((X_bitmap*3L)%4);
else nr_fillingbytes=0;
BH.BMP_id = 'M'*256+'B'; fwrite(&BH.BMP_id,2,1,fp_bitmap);
BH.size=54+Y_bitmap*(X_bitmap*3+nr_fillingbytes);fwrite(&BH.size,4,1,fp_bitmap);
BH.zero_res = 0; fwrite(&BH.zero_res,4,1,fp_bitmap);
BH.offbits = 54; fwrite(&BH.offbits,4,1,fp_bitmap);
BH.biSize = 0x28; fwrite(&BH.biSize,4,1,fp_bitmap);
BH.Width = X_bitmap; fwrite(&BH.Width,4,1,fp_bitmap);
BH.Height = Y_bitmap; fwrite(&BH.Height,4,1,fp_bitmap);
BH.biPlanes = 1; fwrite(&BH.biPlanes,2,1,fp_bitmap);
BH.biBitCount = 24; fwrite(&BH.biBitCount,2,1,fp_bitmap);
BH.biCompression = 0; fwrite(&BH.biCompression,4,1,fp_bitmap);
BH.biSizeImage = 0; fwrite(&BH.biSizeImage,4,1,fp_bitmap);
BH.biXPelsPerMeter = 0xB40; fwrite(&BH.biXPelsPerMeter,4,1,fp_bitmap);
BH.biYPelsPerMeter = 0xB40; fwrite(&BH.biYPelsPerMeter,4,1,fp_bitmap);
BH.biClrUsed = 0; fwrite(&BH.biClrUsed,4,1,fp_bitmap);
BH.biClrImportant = 0; fwrite(&BH.biClrImportant,4,1,fp_bitmap);
im_loc_bytes=(DWORD)im_buffer+((DWORD)Y_bitmap-1)*X_bitmap*4;
for (y=0;y<Y_bitmap;y++)
{
for (x=0;x<X_bitmap;x++)
{
pixel=(RGB *)im_loc_bytes;
fwrite(pixel, 3, 1, fp_bitmap);
im_loc_bytes+=4;
}
for (i=0;i<nr_fillingbytes;i++)
fwrite(&zero_byte,1,1,fp_bitmap);
im_loc_bytes-=2L*X_bitmap*4;
}
fclose(fp_bitmap);
}
void CphotoshowView::OnPointLog()
{
if (m_nPos == -1)
{
MessageBox(L"请先打开图像文件!");
return;
}
CLogTranDlg dlg;
ResetImage();
dlg.DoModal();
}
void CphotoshowView::OnPointThreshold()
{
if ( m_nPos == -1)
{
MessageBox(L"请先打开图像文件!");
return;
}
CThresholdDlg dlg;
ResetImage();
dlg.DoModal();
}
void CphotoshowView::OnPointEqualize()
{
if(m_nPos==-1)
{
MessageBox(L"请先打开图像文件!");
return;
}
GrayEqualize(m_pImageBuffer, m_pImageTempBuffer, m_nPicWidth, m_nPicHeight);
CPreviewDlg dlg;
dlg.m_nType = 2; // 对话框在关闭时提示是否保存
dlg.DoModal();
ResetImage();
}
void CphotoshowView::OnGeoMove()
{
if(m_nPos==-1)
{
MessageBox(L"请先打开图像文件!");
return;
}
CMoveTranDlg dlg;
ResetImage();
dlg.DoModal();
}
void CphotoshowView::OnGeoMirror()
{
if (m_nPos == -1)
{
MessageBox(L"请先打开图像文件!");
return;
}
CMirTranDlg dlg;
ResetImage();
dlg.DoModal();
}
void CphotoshowView::OnGeoZoom()
{
if (m_nPos == -1)
{
MessageBox(L"请先打开图像文件!");
return;
}
CZoomDlg dlg;
dlg.DoModal();
}
void CphotoshowView::OnGeoRotate()
{
if (m_nPos == -1)
{
MessageBox(L"请先打开图像文件!");
return;
}
CRotateDlg dlg;
dlg.DoModal();
}
void CphotoshowView::OnImproveSmooth()
{
if (m_nPos == -1)
{
MessageBox(L"请先打开图像文件!");
return;
}
ResetImage();
SmoothCl(m_pImageBuffer, m_pImageTempBuffer, m_nPicWidth, m_nPicHeight, 10);
CPreviewDlg dlg;
dlg.m_nType = 2;
dlg.DoModal();
}
void CphotoshowView::OnImproveSmoothg()
{
if (m_nPos == -1)
{
MessageBox(L"请先打开图像文件!");
return;
}
ResetImage();
SmoothGaussCl(m_pImageBuffer, m_pImageTempBuffer, m_nPicWidth, m_nPicHeight);
CPreviewDlg dlg;
dlg.m_nType = 2;
dlg.DoModal();
}
void CphotoshowView::OnImproveMedian()
{
if (m_nPos == -1)
{
MessageBox(L"请先打开图像文件!");
return;
}
ResetImage();
SmoothMedianCl(m_pImageBuffer, m_pImageTempBuffer, m_nPicWidth, m_nPicHeight, 7);
CPreviewDlg dlg;
dlg.m_nType = 2;
dlg.DoModal();
}
void CphotoshowView::OnImproveSharp()
{
if (m_nPos == -1)
{
MessageBox(L"请先打开图像文件!");
return;
}
ResetImage();
SharpLaplacianCl(m_pImageBuffer, m_pImageTempBuffer, m_nPicWidth, m_nPicHeight);
CPreviewDlg dlg;
dlg.m_nType = 2;
dlg.DoModal();
}
void CphotoshowView::OnImproveSobel()
{
if (m_nPos == -1)
{
MessageBox(L"请先打开图像文件!");
return;
}
ResetImage();
int w = m_nPicWidth;
int h = m_nPicHeight;
BYTE* imageS1 = new BYTE[w*h*4];
BYTE* imageS2 = new BYTE[w*h*4];
SideSobel(m_pImageBuffer, imageS1, w, h, true);
SideSobel(imageS1, imageS2, w, h, true);
Subtract(imageS1, imageS2, w, h);
ToTwoValue(imageS1, m_pImageTempBuffer, w, h, 100);
delete[] imageS1;
delete[] imageS2;
CPreviewDlg dlg;
dlg.m_nType = 2;
dlg.DoModal();
}
void CphotoshowView::OnFilterNegative()
{
if (m_nPos == -1)
{
MessageBox(L"请先打开图像文件!");
return;
}
ResetImage();
Negative(m_pImageBuffer, m_pImageTempBuffer, m_nPicWidth, m_nPicHeight);
CPreviewDlg dlg;
dlg.m_nType = 2;
dlg.DoModal();
}
void CphotoshowView::OnFilterEmboss()
{
if (m_nPos == -1)
{
MessageBox(L"请先打开图像文件!");
return;
}
ResetImage();
Emboss(m_pImageBuffer, m_pImageTempBuffer, m_nPicWidth, m_nPicHeight);
CPreviewDlg dlg;
dlg.m_nType = 2;
dlg.DoModal();
}
void CphotoshowView::OnFilterBw()
{
if (m_nPos == -1)
{
MessageBox(L"请先打开图像文件!");
return;
}
ResetImage();
ColorToBW(m_pImageBuffer, m_pImageTempBuffer, m_nPicWidth, m_nPicHeight);
CPreviewDlg dlg;
dlg.m_nType = 2;
dlg.DoModal();
}
void CphotoshowView::OnFilterMosaic()
{
if (m_nPos == -1)
{
MessageBox(L"请先打开图像文件!");
return;
}
//计算像素数组的长度
int sum = m_nPicWidth * m_nPicHeight * 4;
memcpy(m_pImageTempBuffer, m_pImageBuffer, sum);
//通过degree来控制马赛克化的程度
unsigned int degree = 3;
//调用马赛克处理函数对像素数组进行处理
Mosaic(m_pImageBuffer, m_pImageTempBuffer, m_nPicWidth, m_nPicHeight, degree);
CPreviewDlg dlg;
dlg.m_nType = 2;
dlg.DoModal();
}
void CphotoshowView::OnFilterSketch()
{
if (m_nPos == -1)
{
MessageBox(L"请先打开图像文件!");
return;
}
ResetImage();
LaplacianB(m_pImageBuffer, m_pImageTempBuffer, m_nPicWidth, m_nPicHeight);
CPreviewDlg dlg;
dlg.m_nType = 2;
dlg.DoModal();
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?