Processing framework for processing BMP images

xiaoxiao2021-03-06  43

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 (dc.getsafehdc ()), 0);

// 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_hDIBOrg)); :: GlobalFree (static_cast (m_hDIBOrg)); // if the following used, there will be wrong, do not know the reason // CloseHandle (m_hdiborg);

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 (file.getlength () - sizeof (bitmapfilehead) --sizeof (bitmapInfoheader);

/ / 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 (m_hDIBChg)); :: GlobalFree (static_cast (m_hDIBChg)); // the following used, there will be wrong, do not know the reason // CloseHandle (m_hDIBChg); m_lpDibbitsChg = NULL;} m_hDIBChg = (HANDLE) :: GlobalAlloc (GMEM_MOVEABLE | GMEM_ZEROINIT, m_size); m_lpDibbitsChg = (LPSTR) :: GlobalLock ((HGLOBAL) m_hDIBChg); memcpy (m_lpDibbitsChg, m_lpDibbitsOrg, m_size);

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 ().

转载请注明原文地址:https://www.9cbs.com/read-54183.html

New Post(0)