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 + -
显示快捷键?