Program Framework for processing BMP Images

Source: Internet
Author: User
Tags bmp image

This is a dialog box-based MFC program named moduleforprocess. (Name the program, just to facilitate future description)

---------------------------------
First, in moduleforprocessdlg. in H, write # define dibfiletype (Word) ('M' <8) | 'B'), and then add some data and function MEMBERS TO THE cmoduleforprocessdlg class. The details are as follows:

// Moduleforprocessdlg. h: header file
//

# Pragma once

//----------------------------------
// Some define
//
# Define dibfiletype (Word) ('M' <8) | 'B ')

// Cmoduleforprocessdlg dialog box
Class cmoduleforprocessdlg: Public cdialog
{
// Construct
Public:
Cmoduleforprocessdlg (cwnd * pparent = NULL); // standard Constructor

// Dialog box data
Enum {IDD = idd_moduleforprocess_dialog };

Protected:
Virtual void dodataexchange (cdataexchange * PDX); // supported by DDX/DDV

// Implementation
Protected:
Hicon m_hicon;

// Message ing function generated
Virtual bool oninitdialog ();
Afx_msg void onsyscommand (uint NID, 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 of 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 changed bits put in

Bitmapinfoheader m_bmiheader;

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 functions are automatically generated using the wizard.

Afx_msg void onbnclickedsavechg ();
Afx_msg void onbnclickedshowchaned ();
Afx_msg void onbnclickedprocess ();
};

----------------------------------------------------------------------

It is now in moduleforprocessdlg. cpp, and only the changed items are marked below

// Remember to initialize member functions, especially when pointers are involved. 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); // device context used for plotting

Sendmessage (wm_iconerasebkgnd, reinterpret_cast <wparam> (DC. getsafehdc (), 0 );

// Center the icon in the work rectangle
Int cxicon = getsystemmetrics (sm_cxicon );
Int cyicon = getsystemmetrics (sm_cyicon );
Crect rect;
Getclientrect (& rect );
Int x = (rect. Width ()-cxicon + 1)/2;
Int y = (rect. Height ()-cyicon + 1)/2;

// Draw the icon
DC. drawicon (X, Y, m_hicon );
}
Else
{
If (m_lpdibbitsorg)
{
Showorgimg ();
}
If (m_lpdibbitschg)
{
Showchgimg ();
}
Cdialog: onpaint ();
}
}

The following function is used to open a BMP file and save the data in the file to two memory areas for convenient modification and use. This is a button response function.

Void cmoduleforprocessdlg: onbnclickedopenorg ()
{
// Todo: add the control notification handler code here
Cfiledialog DLG (true, "BMP", "*. BMP ");

If (DLG. domodal () = idok)
{
Cfile file;

Cfileexception Fe;

// Failed to open the file
If (! File. Open (DLG. getpathname (), cfile: moderead | cfile: sharedenywrite, & Fe ))
{
Afxmessagebox (text ("failed to open the file "));
// Return
Return;
}

//--------------------------------------------------------
// If the file is successfully opened, read the file
//

// Step0 :---------------------------------
// If you have read images, release the memory.
If (m_lpdibbitsorg)
{
: Globalunlock (static_cast : Globalfree (static_cast // If the following used, there will be wrong, don't know the reason
// Closehandle (m_hdiborg );

M_lpdibbitsorg = NULL;
}

// Step 1 :------------------------------
// Try to read the dib File Header
//
// Bitmap File Header
Bitmapfileheader bmfheader;

If (file. Read (lpstr) & bmfheader, sizeof (bmfheader ))! = Sizeof (bmfheader ))
{
// The size is incorrect.
MessageBox (text ("read bitmapfileheader Uncorrect "));
Return;
}

// Determine whether it is a Dib object and check whether the first two bytes are BM
If (bmfheader. bftype! = Dibfiletype)
{
// Non-dib object, return null
MessageBox (text ("not a bitmap file! "));
Return;
}

// Step 2 ------------------------------------
// Read bitmapinfoheader m_bmiheader
//
If (file. Read (lpstr) & m_bmiheader, sizeof (m_bmiheader ))! = Sizeof (m_bmiheader ))
{
// Have the wrong size
MessageBox (text ("read bitmapinfoheader Uncorrect! "));
Return;
}

// Step 3 ------------------------------------
// Read the data into the memory
//
M_size = static_cast <DWORD> (file. getlength ()-sizeof (bitmapfileheader)-sizeof (bitmapinfoheader ));

// Allocate memory for Data
M_hdiborg = (handle): globalalloc (gmem_moveable | gmem_zeroinit, m_size );
If (m_hdiborg = NULL)
{
MessageBox (text ("alloc memory failed! "));
Return;
}

// Lock Dib
M_lpdibbitsorg = (lpstr): globallock (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 :---------------------
// Make sure to release the original memory before reallocation
//
If (m_lpdibbitschg)
{
: Globalunlock (static_cast : Globalfree (static_cast // The following used, there will be wrong, don't 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 * 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 );
}

//------------------------------------------------------------
// 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_bytespaceperline = m_byteperline-(24 * m_width + 7)/8;

}

The following is a function used to save the memory image to a BMP image. It looks awkward because it still opens the file dialog box, but there is no problem in general.

Void cmoduleforprocessdlg: onbnclickedsavechg ()
{
// Todo: add the control notification handler code here
Cfiledialog DLG (true, "BMP", "*. BMP ");

If (DLG. domodal () = idok)
{
// Write out a BMP file
//
Handle HF = createfile (DLG. getpathname (), generic_write, file_assist_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 the bitmap file
BFH. bfsize = sizeof (bitmapfileheader) + sizeof (bitmapinfoheader) + m_size;
// Set the location of the bitmap Pixel
BFH. bfoffbits = sizeof (bitmapfileheader) + sizeof (bitmapinfoheader );

DWORD dwwritten = 0;
Writefile (HF, & BFH, sizeof (BFH), & dwwritten, 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), & dwwritten, null );

// And the bits themselfs
Writefile (HF, m_lpdibbitschg, m_size, & dwwritten, null );

Closehandle (HF );
}
}

The following code modifies the image data in the memory. As an example, it is easy to convert a 24-bit image into a grayscale image. It demonstrates two methods to get the pixel value of each point, of which the comment is another method. Pay attention to the sorting of RGB.

Void cmoduleforprocessdlg: onbnclickedprocess ()
{
// Todo: add the control notification handler code here
Byte rcolor, gcolor, bcolor;

Byte changecolor;

//------------------------------------------
// Method 1
//
Lpstr lpbufferorg = m_lpdibbitsorg;
Lpstr lpbufferchg = m_lpdibbitschg;

For (INT I = 0; I <m_height; I ++)
{
For (Int J = 0; j <m_width; j ++)
{
Bcolor = * lpbufferorg;
Gcolor = * (lpbufferorg + 1 );
Rcolor = * (lpbufferorg + 2 );

Changecolor = (rcolor + gcolor + bcolor)/3;

* Lpbufferchg = changecolor;
* (Lpbufferchg + 1) = changecolor;
* (Lpbufferchg + 2) = changecolor;

Lpbufferorg + = 3;
Lpbufferchg + = 3;
}
Lpbufferorg + = m_bytespaceperline;
Lpbufferchg + = m_bytespaceperline;
}

/*//-------------------------------------------------------------
// Method 2
//
For (INT I = 0; I <m_height; I ++)
{
For (Int J = 0; j <m_width; j ++)
{
Bcolor = * (m_lpdibbitsorg + (m_Height-i-1) * m_byteperline + J * 3 );
Gcolor = * (m_lpdibbitsorg + (m_Height-i-1) * m_byteperline + J * 3 + 1 );
Rcolor = * (m_lpdibbitsorg + (m_Height-i-1) * m_byteperline + J * 3 + 2 );

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;
}
}*/
}

The following shows the data stored in the memory. Here, the data in the memory block used for modification is displayed.

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 );
}

The following shows the raw data of the images 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 self-defined functions. They are used as auxiliary functions to directly read data from the memory and display the data to the corresponding area of the screen. This will be faster.

In this way, a template program for processing BMP images is complete. To perform other image processing, such as image enhancement, you can add code in cmoduleforprocessdlg: onbnclickedprocess.

 

 

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.