// ImageReadingDoc.cpp : implementation of the CImageReadingDoc class // #include "stdafx.h" #include "ImageReading.h" #include "ImageReadingDoc.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CImageReadingDoc IMPLEMENT_DYNCREATE(CImageReadingDoc, CDocument) BEGIN_MESSAGE_MAP(CImageReadingDoc, CDocument) //{{AFX_MSG_MAP(CImageReadingDoc) ON_COMMAND(IDC_OPENIMAGE, OnOpenimage) ON_COMMAND(IDC_COLOR_TO_GRAY, OnColorToGray) ON_COMMAND(ID_SUB, OnSub) ON_COMMAND(ID_OPENIMAGE2, OnOpenimage2) ON_COMMAND(ID_CHANGE, OnChange) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CImageReadingDoc construction/destruction CImageReadingDoc::CImageReadingDoc() { Image = NULL; Image2 = NULL; Image3 = NULL; } CImageReadingDoc::~CImageReadingDoc() { if(Image) { delete Image; Image = NULL; } if(Image2) { delete Image2; Image2 = NULL; } if(Image3) { delete Image3; Image3 = NULL; } } BOOL CImageReadingDoc::OnNewDocument() { if (!CDocument::OnNewDocument()) return FALSE; // TODO: add reinitialization code here // (SDI documents will reuse this document) return TRUE; } ///////////////////////////////////////////////////////////////////////////// // CImageReadingDoc diagnostics #ifdef _DEBUG void CImageReadingDoc::AssertValid() const { CDocument::AssertValid(); } void CImageReadingDoc::Dump(CDumpContext& dc) const { CDocument::Dump(dc); } #endif //_DEBUG ///////////////////////////////////////////////////////////////////////////// // CImageReadingDoc commands static char BASED_CODE szFilter[] = "Support Image Files (*.bmp *.jpg *.gif *.ico)|*.bmp;*.jpg;*.gif;*.ico|BMP Files (*.bmp)|*.bmp|\ JPEG Files (*.jpg)|*.jpg|GIF Files (*.gif)|*.gif|ICON Files (*.ico)|*.ico||"; void CImageReadingDoc::OnOpenimage() // 開啟圖檔的主要程式 { // 呼叫MFC內建開啟檔案的DIALOG執行,相關資訊參考MSDN CFileDialog filedlg(TRUE, NULL, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, szFilter); // 檢查是否按下OK按鈕,否則跳出 if(filedlg.DoModal() != IDOK) return; // 呼叫CxImage宣告一個記憶體指標以提供相關影像解碼動作 if(Image) delete Image; Image = new CxImage(); CString Temp; Image->Load(filedlg.GetPathName()); /* *\ 經過上述動作,o_ImageUL內以存放解碼後的影像資料,會用到的有 o_ImageUL->GetWidth() => 獲得影像寬度 o_ImageUL->GetHeight() => 獲得影像高度 o_ImageUL->GetBits() => 主要影像資料 以BYTE儲存);//利用物件本身所提供之成員函數取得一個像素的 R,G,B(指標用法) o_ImageUL->GetDIB() => 影像HEADER,FOR 秀圖的時候會需要 o_ImageUL->GetEffWidth() => 影像單一一列的總長度(四的倍數) EffW約為width*3 因為ㄧ個RGB3個BYTE o_ImageUL->GetBpp() => 影像位元數(1,4,8,24) bpp = bit per pixel 其中 o_ImageUL->GetBits() 內的編碼方式以 BYTE 為單位 以 B G R 三組代表影像的單一點 \* */ // 秀圖方法: // 呼叫MFC內建FUNC. Refresh All Views UpdateAllViews(FALSE); } void CImageReadingDoc::OnColorToGray() { // 檢查是否以讀取影像進入記憶體,若無則跳出 if(!Image) return; // 檢查是否是24BITS(彩色),若不是則跳出 if(Image->GetBpp() != 24) return; // 指標直接指向影像資料的記憶體位置 BYTE *p_Image = Image->GetBits(); int i, j, k, BPP = Image->GetBpp() / 8; for(i=0; i < Image->GetHeight(); i++, p_Image+=Image->GetEffWidth()) for(j=0, k=0; j < Image->GetWidth(); j++, k+=BPP){ p_Image[k] = p_Image[k + 1] = p_Image[k + 2] = (p_Image[k] + p_Image[k + 1] + p_Image[k + 2]) / 3; if(p_Image[k] >=128){ p_Image[k] = p_Image[k + 1] = p_Image[k + 2] =255; } else { p_Image[k] = p_Image[k + 1] = p_Image[k + 2] =0; } } // 呼叫MFC內建FUNC. Refresh All Views UpdateAllViews(FALSE); } void CImageReadingDoc::OnOpenimage2() { // 呼叫MFC內建開啟檔案的DIALOG執行,相關資訊參考MSDN CFileDialog filedlg(TRUE, NULL, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, szFilter); // 檢查是否按下OK按鈕,否則跳出 if(filedlg.DoModal() != IDOK) return; // 呼叫CxImage宣告一個記憶體指標以提供相關影像解碼動作 if(Image2) delete Image2; Image2 = new CxImage(); CString Temp; Image2->Load(filedlg.GetPathName()); UpdateAllViews(FALSE); } void CImageReadingDoc::OnSub() { // TODO: Add your command handler code here } void CImageReadingDoc::OnChange() { if(!Image) return; int BPP,k; BYTE *p_Image = Image->GetBits(); BPP = Image->GetBpp(); BPP/=8; BYTE gray[512][512]; int i,j,a; for(i=0;iGetHeight();i++, p_Image=p_Image+Image->GetEffWidth()) for(j=0,k=0;jGetWidth();j++,k+=BPP) { p_Image[k]=0.299*p_Image[k+2]+0.587*p_Image[k+1]+0.114*p_Image[k]; p_Image[k+2] = p_Image[k+1] = p_Image[k]; gray[i][j]=p_Image[k]; //將彩色的圖轉為灰階,並把資料存入gray陣列中 } p_Image = Image->GetBits(); for(i=1;iGetHeight()-1;i++, p_Image=p_Image+Image->GetEffWidth()) for(j=1,k=0;jGetWidth()-1;j++,k+=BPP) { BYTE a = gray[i-1][j-1]; BYTE b = gray[i][j-1]; BYTE c = gray[i+1][j-1]; BYTE d = gray[i-1][j]; BYTE e = gray[i+1][j]; BYTE f = gray[i-1][j+1]; BYTE g = gray[i][j+1]; BYTE h = gray[i+1][j+1]; unsigned int hor = abs((a+d*2+f) - (c+e*2+h)); unsigned int vert = abs((a+b*2+c) - (f+g*2+h)); unsigned int gxy = hor*hor + vert*vert; if (gxy>22500) p_Image[k] = p_Image[k+1] = p_Image[k+2]= 255; else p_Image[k] = p_Image[k+1] = p_Image[k+2]= 0; } UpdateAllViews(FALSE); }