Programmers with programming experience know that a large number of bitmaps must be used to make the application's interface beautiful. Currently, popular visual programming tools provide good support for the use of Bitmap.VB,VC,DelphiBy encapsulating bitmap objects, bitmap can be used with good support:VBTwo objects with strong functions are provided:PictureboxAndImageBy using them, it is very easy to load and display bitmaps.DelphiA Bitmap object is also provided:Timage, Its functions and usage andVBInImageSimilar. InVCBy using device-related classesCDCAndGDIObject ClassCbitmapTo complete bitmap operations.
HoweverVCUsed inCbitmapClass mustBMPThe bitmap is loaded into the resource and then passed through the classCbitmapThe member functionCDCClass member functions operate on it. This method has two drawbacks: loading bitmap into resources leads to an increase in executable files, which is not conducive to software release. You can only use limited bitmaps in resources and cannot select other bitmaps. AndBMPThe bitmap file isDiB(Device-independent Bitmap) storage,BMPBitmap is convertedDDB(Device-related Bitmap), ClassCbitmapIs for a seriesDDBOperatedAPIFunctions are encapsulated, which has some limitations.DiBIt can be independent of platform features.
To make up for the two shortcomings of resource bitmap, you must use it directly.BMPBitmap File.VCProvides a way to read and displayBMPBitmap file, but it is quite troublesome to use. UseAPIFunctionGlobalallocAllocate memory and createHdibBitmap handle, all operations can only read and write the memory directly, and thenStrechdibitsAndSetdibstodeviceFunctions are displayed on the screen, which is time-consuming and labor-consuming.
Therefore, the authorCbitmapEncapsulation andDiBStructure, useWin32Creates a function dedicated to operations.BMPFile class, and completely modeled on the classCbitmapImplementation: from ClassCgdiobjectAll interfaces and classes of the new classCbitmap. In this wayCbitmapFor programmers who use class interfaces, there is no difference between the two interfaces.
First, let's give a brief introduction.DiB.DiBBitmap can exist in both memory and file format (BMPFile ). AllDiBThe bitmap information (Bitmapinfo), Including the bitmap information header and color table; bitmap data. For memoryDiBAs long as there are two parts above, andDiBAdd the bitmap file header to the file. Two structures:
DiB Dib
File
Second,
Win32Provides a new functionCreatedibsectionYou can use it to create a storageDiBBit Memory area, you can execute the correspondingGDIOperation, you can directly pointDiBPointer orientation of bit regionsDiBLocation. This is a very useful function, through which we can useDiBSubstitutionDDB.
After learning the relevant knowledge, we can
CgdiobjectDerive an operationBMPFile class:Cbitmapfile.
There are two points worth noting when writing your own classes:
- In
Bitmapfile. hFile definition classCbitmapfile,First, you must declare the classCbitmapfileIs from ClassCgdiobject. Then, use the macro in the class.Declare_dynamic(Cbitmapfile) Indicates that the highest parent class of the new class is a class.CobjectYesMFCClass Library Specification. Then macroDeclare_dynamicIs to declare static functionsFromhandleThe two declarations must be placed at the beginning of the class definition.
In
Bitmapfile. cppAddImplement_dynamic (cbitmapfile, cgdiobject );Indicates classCbitmapfileDirectly derived from ClassCgdiobject.
In
CbitmapfileThe Declaration contains three functions and classes.CbitmapThe definition in is slightly different:
- In
CbitmapfileMediumLoadbitmapThe function parameter isLpctstrType, saving isBMPFile Name.
In
CbitmapfileMediumCreatebitmapParameters are missing in function parameters.NplanesIn the function, the default value is1.
In
CbitmapfileMediumCreatebitmapindirectParameters are added to the function parameters.Lpbits, Pointing to the specified bitmapDiBBit Memory area.
The most important thing in a member function is the function.
Createbitmapindirect And functions Loadbitmap :
- In the Function
CreatebitmapindirectUsing FunctionsCreatedibsectionADCBasicHbitmapHandle and inherit from ClassCgdiobjectFunctionsAttachSet it to a classCgdiobjectHandleM_hobjectAssociation. ThenDiBCopy bitmap data to a functionCreatedibsectionCreatedDiBBit Memory area.
In the Function
LoadbitmapFirst, read the structure from the file with the specified file nameBitmapfileheaderIs the size of the data block, and then the file header flag determines whether the file isBMPBitmap fileBitmapfileheaderMediumBfsizeCompare the size of the saved file with the actual size of the file to determine whether the file is damaged.BitmapfileheaderMediumBfoffbitsAndBitmapfileheaderThe structure size is reduced to calculate the total size of the MAP information header and the color table. A space is dynamically applied to store the information header and the color table information.BitmapfileheaderMediumBfsizeAndBfoffbitsSubtract to calculateDiBThe size of bitmap data. dynamically apply for a space to be saved.DiBBitmap data, and finally call the member functionCreatebitmapindirectTo createDiBBitmap.
In
Onpaint() Draw in eventDiBBitmap methods and usageCbitmapThe method for drawing a bitmap is the same, but note thatCDCClass does not provide a new classCbitmapfilePointer typeDiBBitmapSelectObjectFunction.SelectObjectTo forcibly convert the return typeCbitmapfile *Type.
So far, about the new class
CbitmapfileThere are so many points and issues to be aware of during the compilation.
Attached source file
//
//
File Description: Definition classCbitmapfile, Which is used to readBMPFile, involving reading,
//
Establish and perform a series of common operations.
//
File Name:Bitmapfile. h
//
Time:2017-2-11
//
Author: Jia Yi
//
# Ifndef _ cbitmapfile_h _
# DEFINE _ cbitmapfile_h _
Class cbitmapfile: Public cgdiobject
{
Declare_dynamic (cbitmapfile)
Public:
Static cbitmapfile * Pascal fromhandle (hbitmap );
// Constructors
Cbitmapfile ();
Bool loadbitmap (lpctstr lpszfilename );
Bool createbitmap (INT nwidth, int nheight, uint nbitcount, const void * lpbits );
Bool createbitmapindirect (lpbitmapinfo, const void * lpbits );
// Attributes
Operator hbitmap () const;
Int getbitmap (Bitmap * pbitmap );
Protected:
// Attributes
Int getcolornumber (word wbitcount );
Public:
// Operations
DWORD setbitmapbits (DWORD dwcount, const void * lpbits );
DWORD getbitmapbits (DWORD dwcount, lpvoid lpbits );
// Implementation
Public:
Virtual ~ Cbitmapfile ();
};
# Endif
//
//
File Description: ClassCbitmapfileImplementation of member functions
//
File Name:Bitmapfile. cpp
//
Time:2017-2-11
//
Author: Jia Yi
//
# Include "bitmapfile. H"
# Include <memory. h>
Implement_dynamic (cbitmapfile, cgdiobject );
Cbitmapfile * Pascal cbitmapfile: fromhandle (hbitmap)
{
Return (cbitmapfile *) cgdiobject: fromhandle (hbitmap );
}
Cbitmapfile: cbitmapfile ()
{
}
Bool cbitmapfile: loadbitmap (lpctstr lpszfilename)
{
Cfile file;
If (! File. Open (lpszfilename, cfile: moderead | cfile: sharedenywrite ))
{
MessageBox (null, "BMP file open error! "," Warning ", mb_ OK );
Return false;
}
Bitmapfileheader bfhheader;
File. Read (& bfhheader, sizeof (bitmapfileheader ));
If (bfhheader. bftype! = (Word) ('M' <8) | 'B '))
{
MessageBox (null, "the file is not a BMP file! "," Warning ", mb_ OK );
Return false;
}
If (bfhheader. bfsize! = File. getlength ())
{
MessageBox (null, "the BMP File Header error! "," Warning ", mb_ OK );
Return false;
}
Uint ubmpinfolen = (uint) bfhheader. bfoffbits-sizeof (bitmapfileheader );
Lpbitmapinfo lpbitmap = (lpbitmapinfo) New byte [ubmpinfolen];
File. Read (lpvoid) lpbitmap, ubmpinfolen );
If (* (lpdword) (lpbitmap ))! = Sizeof (bitmapinfoheader ))
{
MessageBox (null, "the BMP is not Windows 3.0 format! "," Warning ", mb_ OK );
Return false;
}
DWORD dwbitlen = bfhheader. bfsize-bfhheader. bfoffbits;
Lpvoid lpbits = new byte [dwbitlen];
File. readhuge (lpbits, dwbitlen );
File. Close ();
Bool bsuccess = createbitmapindirect (lpbitmap, lpbits );
Delete lpbitmap;
Delete lpbits;
If (! Bsuccess)
Return false;
Return true;
}
Bool cbitmapfile: createbitmap (INT nwidth, int nheight, uint nbitcount,
Const void * lpsrcbits)
{
Assert (nbitcount = 1 | nbitcount = 4 | nbitcount = 8
| Nbitcount = 16 | nbitcount = 24 | nbitcount = 32 );
Lpbitmapinfo lpbitmap;
Lpbitmap = (bitmapinfo *) New byte [sizeof (bitmapinfoheader) +
Getcolornumber (nbitcount) * sizeof (rgbquad)];
Lpbitmap-> bmiheader. bisize = sizeof (bitmapinfoheader );
Lpbitmap-> bmiheader. biwidth = nwidth;
Lpbitmap-> bmiheader. biheight = nheight;
Lpbitmap-> bmiheader. bibitcount = nbitcount;
Lpbitmap-> bmiheader. biplanes = 1;
Lpbitmap-> bmiheader. bicompression = bi_rgb;
Lpbitmap-> bmiheader. bisizeimage = 0;
Lpbitmap-> bmiheader. biclrused = 0;
Bool bsuccess = createbitmapindirect (lpbitmap, lpsrcbits );
Delete lpbitmap;
If (! Bsuccess)
Return false;
Return true;
}
Bool cbitmapfile: createbitmapindirect (lpbitmapinfo, const void * lpsrcbits)
{
Deleteobject ();
Lpvoid lpbits;
CDC * Dc = new CDC;
DC-> createcompatibledc (null );
Hbitmap =: createdibsection (DC-> m_hdc, lpbitmapinfo, dib_rgb_colors,
& Lpbits, null, 0 );
Assert (hbitmap! = NULL );
Delete DC;
Attach (hbitmap );
Bitmap BMP;
Getbitmap (& BMP );
DWORD dwcount = (DWORD) BMP. bmwidthbytes * BMP. bmheight;
If (setbitmapbits (dwcount, lpsrcbits )! = Dwcount)
{
MessageBox (null, "Dib build error! "," Warning ", mb_ OK );
Return false;
}
Return true;
}
Cbitmapfile: Operator hbitmap () const
{
Return (hbitmap) (This = NULL? Null: m_hobject );
}
Int cbitmapfile: getbitmap (Bitmap * pbitmap)
{
Assert (m_hobject! = NULL );
Return: GetObject (m_hobject, sizeof (Bitmap), pbitmap );
}
Int cbitmapfile: getcolornumber (word wbitcount)
{
Assert (wbitcount = 1 | wbitcount = 4 | wbitcount = 8
| Wbitcount = 16 | wbitcount = 24 | wbitcount = 32 );
Switch (wbitcount)
{
Case 1:
Return 2;
Case 4:
Return 16;
Case 8:
Return 256;
Default:
Return 0;
}
}
DWORD cbitmapfile: setbitmapbits (DWORD dwcount, const void * lpbits)
{
If (lpbits! = NULL)
{
Bitmap BMP;
Getbitmap (& BMP );
Memcpy (BMP. bmbits, lpbits, dwcount );
Return dwcount;
}
Else
Return 0;
}
DWORD cbitmapfile: getbitmapbits (DWORD dwcount, lpvoid lpbits)
{
If (lpbits! = NULL)
{
Bitmap BMP;
Getbitmap (& BMP );
Memcpy (lpbits, BMP. bmbits, dwcount );
Return dwcount;
}
Else
Return 0;
}
Cbitmapfile ::~ Cbitmapfile ()
{
Cgdiobject: deleteobject ();
}