This is a dialog-based MFC program, and the program is ModuleForProcess. (Speaking the name of the program, just to describe some convenient for future)
-------------------------------- First, write #define dibfiletype (Word) in ModuleForProcessDlg.h. 'M' << 8) | 'b'), then add some data members and function members to the CMODULEforProcessDLG class. details as follows:
// moduleforprocessdlg.h: header file //
#pragma overce
// ---------------------------------- // Some Define // # define dibfiletype (Word) 'M' << 8) | 'b')
// cmoduleforprocessdlg dialog CMODULEFORPROCESSDLG: public cdialog {// Construction public: cmoduleforprocessdlg (cwnd * pparent = null); // Standard constructor
// Dialog Box Data ENUM {IDD = IDD_MODULEFORPROCESS_DIALOG};
Protected: Virtual Void DodataExchange (CDataExchange * PDX); // DDX / DDV Support
// Realize Protected: hicon m_hicon;
// message mapping function generated virtual BOOL OnInitDialog (); afx_msg void OnSysCommand (UINT nID, LPARAM lParam); afx_msg void OnPaint (); afx_msg HCURSOR OnQueryDragIcon (); DECLARE_MESSAGE_MAP () public: afx_msg void OnBnClickedOpenorg ();
/ / -------------------------------------------------------------------------------------------- ------------ // Data MEMBER / / PUBLIC: LPSTR M_LPDIBBITSORG; // The Place ORIGINAL BITS LPSTR M_LPDIBBITSCHG; // The Place of Changed Bits
Handle m_hdiborg; // the hglobal of the memory where the original bits put in handle m_hdibchg; // The Hglobal of the memory where the change bits put in
BitmapInfoHeader M_Bmihead;
DWORD M_SIZE; // THE Size of the Data
INT M_WIDTH; // The Width of the Bitmap, To Use IT, Just Handy Int M_HEIGHT; // The Height of the Bitmap, To Use IT, Just Handy DWORD M_BYTEPERLINE; // The Real Numbers of Bits in One Line, Just For Handy DWORD M_BYTESPACEPERLINE; // The Non Use Number of Bits in One Line, Just for Handy
/ / -------------------------------------------------------------------------------------------- -------- // Function Member Void Showorgimg (Void); // Show The Original Image Void Showchgimg (Void); // Show The Image Which Has ChangeD // The following function is automatically generated with the wizard of
AFX_MSG Void OnbnclickedSavechg (); AFX_MSG Void OnbnclickedShowchaned (); AFX_MSG Void OnbnclickedProcess ();
-------------------------------------------------- --------------------
Now is in ModuleForProcessDlg.cpp, then the changed place will be labeled // Remember the member function, especially when it comes to the pointer, it must be initialized, otherwise there will be a big problem.
CmoduleForProcessDlg :: CmoduleForProcessDlg (CWnd * pParent / * = NULL * /): CDialog (CmoduleForProcessDlg :: IDD, pParent), m_lpDibbitsChg (NULL), m_lpDibbitsOrg (NULL), m_Height (0), m_Width (0), m_byteSpacePerLine (0) , M_byteperline (0) {m_hicon = AFXGetApp () -> loadicon (idR_mainframe);
Void cmoduleforprocessdlg :: onpaint () {if (isiconic ()) {cPaintDC DC (this); // Used to draw the device context
SendMessage (WM_ICONERASEBKGND, Reinterpret_cast
// Make the icon in the working rectangle in the working rectangle = getSystemMetrics (SM_CXICON); int Cyicon = getSystemMetrics (SM_CYICON); CRECT RECT; GetClientRect (& Re); int x = (Rect.width () - CXICON 1) / 2; INT Y = (Rect.height () - Cyicon 1) / 2;
// Draw icon Dc.drawicon (x, y, m_hicon);} else {if (m_lpdibbitsorg) {showorgimg ();} if (m_lpdibbitschg) {showchgimg ();} cdialog :: onpaint ();}}
The following function is implemented to open a BMP file, then save the data in the file to the two memory area, which is convenient for modifying. This is a button response function
Void cmoduleforprocessdlg :: OnBnclicKedopenorg () {// Todo: Add control notification handler code CFiledialog DLG (True, "BMP", "*. BMP");
IF (DLG.Domodal () == iDok) {cfile file;
CfileException Fe;
// Open the file failed if (! File.open (dlg.getpathname (), cfile :: moderad | cfile :: SharednyWrite, & Fe) {AFXMESSAGEBOX (Text ("Open File Failed")); // Return Return;} / / -------------------------------------------------------------------------------------------- -------- // If the file is successfully opened, start reading the file //
// Step0: ------------------------------- // If you have read the picture, you have to release if IF ( m_lpDibbitsOrg) {:: GlobalUnlock (static_cast
m_lpdibbitsorg = null;}
// Step1: ------------------------------ // Try to read DIB file head // // bitmap file header BitmapfileHeader Bmfheader;
IF (file.read ((lpstr) & bmfheader, sizeof (bmfheader)) = sizeof (bmfheader)) {// size is not MESSAGEBOX (Text ("Read BitmapFileHeader UncorRect)); Return;}
/ / Judgment Whether it is a DIB object, check whether the two bytes are BM if (BMFHeader.bfType! = DibfiletyPE) {// Non-DIB object, return NULL MessageBox (Text ("not a bitmap file!")); Return }
// step2 ---------------------------------- // read bitmapinfoheader m_bmiheader // if (file. Read ((lpstr) & m_bmiheader, sizeof (m_bmihead))! = Sizeof (m_bmihead)) {// Have The Wrong Size MessageBox (Text ("Read BitmapInfoHeader UncoRrect!)); Return;}
// Step3 ------------------------------------ // read the data inTo the memory // m_size = static_cast
/ / Distributing memory m_hdiborg = (Handle) :: GMEM_MOVEABLE | GMEM_ZEROINIT, M_SI = NULL) {MessageBox (Text ("Alloc Memory Failed!"); Return; M_LPDibbitsorg = (LPST) :: Globalock ((hglobal) m_hdiborg;
// Now Read The Data from The File INTO THE MEMORY IF (file.read (m_lpdibbitsorg, m_size)! = m_size) {// if Don't Read Correct MessageBox (Text ("Read The Data WRONG!");::: : GlobalUnlock ((hglobal) m_hdiborg; :: GlobalFree ((hglobal) m_hdiborg; return;} // ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ ------------------------------------- // Now show the bitmap out on the screen // cwnd * PWnd = getdlgitem (IDC_ORGIMG); CDC * THEDC = PWND-> getdc (); CRECT Rect; PWND-> getClientRect (& Rect);
StretchDIBits (theDC-> m_hDC, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, 0,0, m_bmiHeader.biWidth, m_bmiHeader.biHeight, m_lpDibbitsOrg, (LPBITMAPINFO) & m_bmiHeader, DIB_RGB_COLORS, SRCCOPY);
/ / -------------------------------------------------------------------------------------------- -------------------- // Now Copy The Original Data Into Another Memory Play and show it out //
// Step0: --------------------- // Be sure to release the original memory // if (m_lpdibbitschg) {:: globalunlock (static_castnlock
CWND * PWNDCHG = getdlgitem (IDC_chgimg); cdc * hasDcchg = PWNDCHG-> getdc (); CRECT RectChg; PWNDCHG-> getClientRect (& RectCHG);
StretchDIBits (theDCChg-> m_hDC, rectChg.left, rectChg.top, rectChg.right-rectChg.left, rectChg.bottom-rectChg.top, 0,0, m_bmiHeader.biWidth, m_bmiHeader.biHeight, m_lpDibbitsChg, (LPBITMAPINFO) & m_bmiHeader, DIB_RGB_COLORS, SRCCOPY);} // ------------------------------------------------------------------------------------------------------------------------ ------------------ // Now Just for Handy, To Store Some Date // m_HEight = m_bmiheader.biheight; m_width = m_bmiheader.biwidth;
m_byteperline = (24 * m_width 31) / 32 * 4; m_bytesspaceperline = m_Byteperline- (24 * m_width 7) / 8;
} The following is a function that saves the image in the memory into a BMP image, which is a bit awkward because of the dialog box, but the total is no problem.
Void cmoduleforprocessdlg :: OnbnclicKedsavechg () {// Todo: This add control notification handler code CFiledialog DLG (True, "BMP", "*. BMP");
IF (dlg.domodal () == idok) {// Write out a bmp file // handle hf = createfile (Dlg.getPathname (), generic_write, file_share_read, null, create_always, null, null; if (HF == INVALID_HANDLE_VALUE) RETURN;
// Write out the file header // bitmapfileHeader Bfh; Memset (& BFH, 0, SIZEOF (BitmapFileHeader)); bfh.bftype = 'mb'; // Set the size of bitmap file BFH.BFSIZE = SizeOf (BitmapfileHeader) Sizeof (BitMapInfoHeader) m_size; // Set the position of the bit image Bfh.bfoffbits = sizeof (BitmapFileHeader) Sizeof (BitmapInfoHeader);
DWORD dwritten = 0; Writefile (HF, & BFH, SIZEOF (BFH), & DWWRITEN, NULL
// and the bitmap format // BITMAPINFOHEADER bih; memset (& bih, 0, sizeof (BITMAPINFOHEADER)); bih.biSize = sizeof (BITMAPINFOHEADER); bih.biWidth = m_Width; bih.biHeight = m_Height; bih.biPlanes = 1; BIH.BIBITCOUNT = 24;
Writefile (HF, & BIH, SIZEOF (BIH), & DWWRITEN, NULL
// and the bits themselfs Writefile (HF, M_LPDibbitschg, M_SIZE, & DWWRITEN, NULL); CloseHandle (HF);}}
Below is a code for modifying image data in the memory. As an example, it is simply simple to turn the 24-bit image into a grayscale image. The method of acquiring each pixel value is demonstrated, wherein the comment is another method. Pay attention to the sorting problem of RGB.
Void cmoduleforprocessdlg :: OnbnclickedProcess () {// Todo: Add control notification handler code Byte Rcolor, gcolor, bcolor;
BYTE CHANGECOLOR;
// ----------------------------------------- //Method 1 // LPSTR lpbufferorg = m_lpdibbitsorg; lpstr lpbufferchg = m_lpdibbitschg;
For (int i = 0; i ) {for (int J = 0; j ChangeColor = (rcolor gcolor bcolor) / 3; * lpbufferchg = changecolor; * (lpbufferchg 1) = changeColor; * (lpbufferchg 2) = ChangeColor; LPBufferorg = 3; lpbufferchg = 3;} lpbufferorg = m_bytespaceperPerLine; lpbufferchg = m_bytespaceperline;} / * / / ---------------------------------------------- --------------- //Method 2 // for (int i = 0; i ChangeColor = (rcolor gcolor bcolor) / 3; * (M_lpDibbitsChg (m_Height-i-1) * m_bytePerLine j * 3) = changeColor; * (m_lpDibbitsChg (m_Height-i-1) * m_bytePerLine j * 3 1) = changeColor; * (m_lpDibbitsChg (m_Height-i- 1) * m_byteperline j * 3 2) = changecolor;}} * /} Here is the data stored in memory, which is displayed in the memory block used to modify the data. void CmoduleForProcessDlg :: ShowChgImg (void) {CWnd * pWndChg = GetDlgItem (IDC_CHGIMG); CDC * theDCChg = pWndChg-> GetDC (); CRect rectChg; pWndChg-> GetClientRect (& rectChg); StretchDIBits (theDCChg-> m_hDC, rectChg.left , rectChg.top, rectChg.right-rectChg.left, rectChg.bottom-rectChg.top, 0,0, m_bmiHeader.biWidth, m_bmiHeader.biHeight, m_lpDibbitsChg, (LPBITMAPINFO) & m_bmiHeader, DIB_RGB_COLORS, SRCCOPY);} Below is the original data of the image stored in the memory. Void cmoduleforprocessdlg :: Showorgimg (void) {CWND * PWND = getdlgitem (idc_orgimg); cdc * thedc = pwnd-> getdc (); cRect Rect; PWND-> getClientRect (& RECT); StretchDIBits (theDC-> m_hDC, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, 0,0, m_bmiHeader.biWidth, m_bmiHeader.biHeight, m_lpDibbitsOrg, (LPBITMAPINFO) & m_bmiHeader, DIB_RGB_COLORS, SRCCOPY); The last two functions are the functions of their own definitions, as auxiliary, read data directly from the memory and display the corresponding area of the screen, which will be relatively fast. In this way, it is very simple, and a template program for processing BMP images is completed. If you want to handle images, such as image enhancement, etc., you can add code in cmoduleforprocessdlg :: OnBnClickedProcess ().