TVSKIN源代码阅读日记(四)--- 图片解析和相关类

来源:互联网 发布:淘宝闲鱼客户端 编辑:程序博客网 时间:2024/06/11 00:00

涉及到的类CEZBitmap

类定义:

class CEZBitmap : public CBitmap, public CEZInformation
{
public:
    _bstr_t name;
public:
    CEZBitmap( HBITMAP hBitmap = NULL ) : CBitmap(hBitmap)
    {}
    ~CEZBitmap()
    {}

    // setup bitmap
    BOOL LoadBitmap( WCHAR *filename, char *idName, int x, int y, int w, int h);
    BOOL LoadBitmap( WCHAR *filename, char *idName );

};

 

主要功能函数:

BOOL CEZBitmap::LoadBitmap( WCHAR *filename, char *idName )
{

    HDC        hdcDes    = NULL;
    BYTE *pFile = NULL;
    BYTE *pImage = NULL;
    BITMAPFILEHEADER* pBMPFileHeader = NULL;

    // Source bmp
    pFile = pakLoadImage( filename );
  

    pBMPFileHeader = (BITMAPFILEHEADER *)pFile;
    pImage = pBMPFileHeader->bfOffBits + pFile;
    BITMAPINFO* pBMPInfo =(BITMAPINFO*)(pFile + sizeof(BITMAPFILEHEADER) );

    int cxDib = 0;
    int cyDib = 0;
    if( pBMPInfo->bmiHeader.biSize == sizeof(BITMAPCOREHEADER) )
    {
        cxDib = ((BITMAPCOREHEADER *) pBMPInfo)->bcWidth;
        cyDib = ((BITMAPCOREHEADER *) pBMPInfo)->bcHeight;
    }
    else
    {
        cxDib = pBMPInfo->bmiHeader.biWidth;
        cyDib = pBMPInfo->bmiHeader.biHeight;
    }
 
    HDC hDC = ::GetDC(g_hMainWnd);
    m_hBitmap = CreateCompatibleBitmap( hDC, cxDib, cyDib );

    hdcDes = CreateCompatibleDC(hDC);
    SelectObject( hdcDes, m_hBitmap );

    SetDIBitsToDevice( hdcDes, 0, 0, cxDib, cyDib,  0, 0, 0, cyDib, pImage, pBMPInfo, DIB_RGB_COLORS );
    DeleteDC( hdcDes );
    DeleteDC( hDC );

    name = _bstr_t(filename);
    this->SetID( idName );

    return S_OK;
}

 

Well,there are a lot of useful type i used many times, but i did not know the details about this type definition. Today, look reference to MSND for VS2005 to study the technology articles.

 

First: HDC

Second: BITMAPFILEHEADER

Third: BITMAPINFO / BITMAPCOREINFO

Forth: BITMAPINFOHEADER / BITMAPCOREHEADER

Fifth:  CreateCompatibleBitmap

Sixth: CreateCompatibleDC

Seventh: SelectObject

Eighth: SetDIBitsToDevice

 

BITMAPFILEHEADER

The BITMAPFILEHEADER structure contains information about the type, size, and layout of a file that contains a DIB.

typedef struct tagBITMAPFILEHEADER {
WORD bfType;
DWORD bfSize;
WORD bfReserved1;
WORD bfReserved2;
DWORD bfOffBits; }BITMAPFILEHEADER, *PBITMAPFILEHEADER;

Members

bfType
Specifies the file type, must be BM.
bfSize
Specifies the size, in bytes, of the bitmap file.
bfReserved1
Reserved; must be zero.
bfReserved2
Reserved; must be zero.
bfOffBits
Specifies the offset, in bytes, from the beginning of the BITMAPFILEHEADER structure to the bitmap bits.

Remarks

A BITMAPINFO or BITMAPCOREINFO structure immediately follows the BITMAPFILEHEADER structure in the DIB file. For more information, see Bitmap Storage.

 

BITMAPINFO

The BITMAPINFO structure defines the dimensions and color information for a DIB.

typedef struct tagBITMAPINFO {
BITMAPINFOHEADER bmiHeader;
RGBQUAD bmiColors[1]; } BITMAPINFO, *PBITMAPINFO;

 

Members

bmiHeader
Specifies a BITMAPINFOHEADER structure that contains information about the dimensions of color format.

 

bmiColors
The bmiColors member contains one of the following:
  • An array of RGBQUAD. The elements of the array that make up the color table.
  • An array of 16-bit unsigned integers that specifies indexes into the currently realized logical palette. This use of bmiColors is allowed for functions that use DIBs. When bmiColors elements contain indexes to a realized logical palette, they must also call the following bitmap functions:

    CreateDIBitmap

    CreateDIBPatternBrush

    CreateDIBSection

    The iUsage parameter of CreateDIBSection must be set to DIB_PAL_COLORS.

The number of entries in the array depends on the values of the biBitCount and biClrUsed members of the BITMAPINFOHEADER structure.

The colors in the bmiColors table appear in order of importance. For more information, see the Remarks section.

 

Remarks

A DIB consists of two district parts: A BITMAPINFO structure describing the dimensions and colors of bitmap, and an array of bytes defining pixels of the bitmap. The bits in the array are packed together, but each scan line must be padded with zeroes to end on a LONG data-type boundary. If the height of the bitmap is positive, the bitmap is a bottom-up DIB and its origin is the lower-left corner. If the height is negative, the bitmap is a top-down DIB and its origin is the upper left corner.

A bitmap is packed when the bitmap array immediately follows the BITMAPINFO header. Packed bitmaps are referenced by a single pointer. For packed bitmaps, the biClrUsed member must be set to an even number when using the DIB_PAL_COLORS mode so that the DIB bitmap array starts on a DWORD boundary.

Note  The bmiColors member should not contain palette indexes if the bitmap is to be stored in a file or transferred to another application.

Unless the application has exclusive use and control of the bitmap, the bitmap color table should contain explicit RGB values.

 

BITMAPCOREINFO

The BITMAPCOREINFO structure defines the dimensions and color information for a DIB.

typedef struct _BITMAPCOREINFO {
BITMAPCOREHEADER bmciHeader;
RGBTRIPLE bmciColors[1];
} BITMAPCOREINFO, *PBITMAPCOREINFO;

 

Members:

bmciHeader
Specifies a BITMAPCOREHEADER structure that contains information about the dimensions and color format of a DIB.
bmciColors
Specifies an array of RGBTRIPLE structures that define the colors in the bitmap.

Remarks:

A DIB consists of two parts: a BITMAPCOREINFO structure describing the dimensions and colors of the bitmap, and an array of bytes defining the pixels of the bitmap. The bits in the array are packed together, but each scan line must be padded with zeroes to end on a LONG boundary. The origin of the bitmap is the lower-left corner.

The bcBitCount member of the BITMAPCOREHEADER structure determines the number of bits that define each pixel and the maximum number of colors in the bitmap. This member can be one of the following values.

 

valuemeaning1The bitmap is monochrome, and the bmciColors member contains two entries. Each bit in the bitmap array represents a pixel. If the bit is clear, the pixel is displayed with the color of the first entry in the bmciColors table; if the bit is set, the pixel has the color of the second entry in the table.4The bitmap has a maximum of 16 colors, and the bmciColors member contains up to 16 entries. Each pixel in the bitmap is represented by a 4-bit index into the color table. For example, if the first byte in the bitmap is 0x1F, the byte represents two pixels. The first pixel contains the color in the second table entry, and the second pixel contains the color in the sixteenth table entry.8The bitmap has a maximum of 256 colors, and the bmciColors member contains up to 256 entries. In this case, each byte in the array represents a single pixel.24The bitmap has a maximum of 2 (24) colors, and the bmciColors member is NULL. Each three-byte triplet in the bitmap array represents the relative intensities of blue, green, and red, respectively, for a pixel.

 

The colors in the bmciColors table should appear in order of importance.

Alternatively, for functions that use DIBs, the bmciColors member can be an array of 16-bit unsigned integers that specify indexes into the currently realized logical palette, instead of explicit RGB values. In this case, an application using the bitmap must call the DIB functions (CreateDIBitmap, CreateDIBPatternBrush, and CreateDIBSection) with the iUsage parameter set to DIB_PAL_COLORS.

Note  The bmciColors member should not contain palette indexes if the bitmap is to be stored in a file or transferred to another application. Unless the application has exclusive use and control of the bitmap, the bitmap color table should contain explicit RGB values.

 

BITMAPINFOHEADER

The BITMAPINFOHEADER structure contains information about the dimensions and color format of a DIB.

typedef struct tagBITMAPINFOHEADER{
DWORD biSize;
LONG biWidth;
LONG biHeight;
WORD biPlanes;
WORD biBitCount;
DWORD biCompression;
DWORD biSizeImage;
LONG biXPelsPerMeter;
LONG biYPelsPerMeter;
DWORD biClrUsed;
DWORD biClrImportant; } BITMAPINFOHEADER, *PBITMAPINFOHEADER;

Members

Specifies the number of bytes required by the structure.
biWidth
Specifies the width of the bitmap, in pixels.

Windows 98/Me, Windows 2000/XP: If biCompression is BI_JPEG or BI_PNG, the biWidth member specifies the width of the decompressed JPEG or PNG image file, respectively.

 

biHeight
Specifies the height of the bitmap, in pixels. If biHeight is positive, the bitmap is a bottom-up DIB and its origin is the lower-left corner. If biHeight is negative, the bitmap is a top-down DIB and its origin is the upper-left corner.

If biHeight is negative, indicating a top-down DIB, biCompression must be either BI_RGB or BI_BITFIELDS. Top-down DIBs cannot be compressed.

Windows 98/Me, Windows 2000/XP: If biCompression is BI_JPEG or BI_PNG, the biHeight member specifies the height of the decompressed JPEG or PNG image file, respectively.

 

biPlanes
Specifies the number of planes for the target device. This value must be set to 1.
biBitCount
Specifies the number of bits-per-pixel. The biBitCount member of the BITMAPINFOHEADER structure determines the number of bits that define each pixel and the maximum number of colors in the bitmap. This member must be one of the following values.

……

biSizeImage
Specifies the size, in bytes, of the image. This may be set to zero for BI_RGB bitmaps.

Windows 98/Me, Windows 2000/XP: If biCompression is BI_JPEG or BI_PNG, biSizeImage indicates the size of the JPEG or PNG image buffer, respectively.

 

biXPelsPerMeter
Specifies the horizontal resolution, in pixels-per-meter, of the target device for the bitmap. An application can use this value to select a bitmap from a resource group that best matches the characteristics of the current device.
biYPelsPerMeter
Specifies the vertical resolution, in pixels-per-meter, of the target device for the bitmap.
biClrUsed
Specifies the number of color indexes in the color table that are actually used by the bitmap. If this value is zero, the bitmap uses the maximum number of colors corresponding to the value of the biBitCount member for the compression mode specified by biCompression.

If biClrUsed is nonzero and the biBitCount member is less than 16, the biClrUsed member specifies the actual number of colors the graphics engine or device driver accesses. If biBitCount is 16 or greater, the biClrUsed member specifies the size of the color table used to optimize performance of the system color palettes. If biBitCount equals 16 or 32, the optimal color palette starts immediately following the three DWORD masks.

When the bitmap array immediately follows the BITMAPINFO structure, it is a packed bitmap. Packed bitmaps are referenced by a single pointer. Packed bitmaps require that the biClrUsed member must be either zero or the actual size of the color table.

 

biClrImportant
Specifies the number of color indexes that are required for displaying the bitmap. If this value is zero, all colors are required.

Remarks

The BITMAPINFO structure combines the BITMAPINFOHEADER structure and a color table to provide a complete definition of the dimensions and colors of a DIB. For more information about DIBs, see Device-Independent Bitmaps and BITMAPINFO.

 

BITMAPCOREHEADER

The BITMAPCOREHEADER structure contains information about the dimensions and color format of a DIB.

typedef struct tagBITMAPCOREHEADER {
DWORD bcSize;
WORD bcWidth;
WORD bcHeight;
WORD bcPlanes;
WORD bcBitCount; } BITMAPCOREHEADER, *PBITMAPCOREHEADER;

 

Members

bcSize
Specifies the number of bytes required by the structure.
bcWidth
Specifies the width of the bitmap, in pixels.
bcHeight
Specifies the height of the bitmap, in pixels.
bcPlanes
Specifies the number of planes for the target device. This value must be 1.
bcBitCount
Specifies the number of bits-per-pixel. This value must be 1, 4, 8, or 24.

Remarks

The BITMAPCOREINFO structure combines the BITMAPCOREHEADER structure and a color table to provide a complete definition of the dimensions and colors of a DIB. For more information about specifying a DIB, see BITMAPCOREINFO.

An application should use the information stored in the bcSize member to locate the color table in a BITMAPCOREINFO structure, using a method such as the following:

pColor = ((LPBYTE) pBitmapCoreInfo +         (WORD) (pBitmapCoreInfo -> bcSize)) 
 
Device-Independent Bitmaps

A device-independent bitmap (DIB) contains a color table. A color table describes how pixel values correspond to RGB color values, which describe colors that are produced by emitting light. Thus, a DIB can achieve the proper color scheme on any device. A DIB contains the following color and dimension information:

  • The color format of the device on which the rectangular image was created.
  • The resolution of the device on which the rectangular image was created.
  • The palette for the device on which the image was created.
  • An array of bits that maps red, green, blue (RGB) triplets to pixels in the rectangular image.
  • A data-compression identifier that indicates the data compression scheme (if any) used to reduce the size of the array of bits.

The color and dimension information is stored in a BITMAPINFO structure, which consists of a BITMAPINFOHEADER structure followed by two or more RGBQUAD structures. The BITMAPINFOHEADER structure specifies the dimensions of the pixel rectangle, describes the device's color technology, and identifies the compression schemes used to reduce the size of the bitmap. The RGBQUAD structures identify the colors that appear in the pixel rectangle.

There are two varieties of DIBs:

  • A bottom-up DIB, in which the origin lies at the lower-left corner.
  • A top-down DIB, in which the origin lies at the upper-left corner.

If the height of a DIB, as indicated by the Height member of the bitmap information header structure, is a positive value, it is a bottom-up DIB; if the height is a negative value, it is a top-down DIB. Top-down DIBs cannot be compressed.

The color format is specified in terms of a count of color planes and color bits. The count of color planes is always 1; the count of color bits is 1 for monochrome bitmaps, 4 for VGA bitmaps, and 8, 16, 24, or 32 for bitmaps on other color devices. An application retrieves the number of color bits that a particular display (or printer) uses by calling the GetDeviceCaps function, specifying BITSPIXEL as the second argument.

The resolution of a display device is specified in pixels-per-meter. An application can retrieve the horizontal resolution for a video display, or printer, by following this three-step process.

  1. Call the GetDeviceCaps function, specifying HORZRES as the second argument.
  2. Call GetDeviceCaps a second time, specifying HORZSIZE as the second argument.
  3. Divide the first return value by the second return value.

The application can retrieve the vertical resolution by using the same three-step process with different parameters: VERTRES in place of HORZRES, and VERTSIZE in place of HORZSIZE.

The palette is represented by an array of RGBQUAD structures that specify the red, green, and blue intensity components for each color in a display device's color palette. Each color index in the palette array maps to a specific pixel in the rectangular region associated with the bitmap. The size of this array, in bits, is equivalent to the width of the rectangle, in pixels, multiplied by the height of the rectangle, in pixels, multiplied by the count of color bits for the device. An application can retrieve the size of the device's palette by calling the GetDeviceCaps function, specifying NUMCOLORS as the second argument.

Windows supports the compression of the palette array for 8-bpp and 4-bpp bottom-up DIBs. These arrays can be compressed by using the run-length encoding (RLE) scheme. The RLE scheme uses 2-byte values, the first byte specifying the number of consecutive pixels that use a color index and the second byte specifying the index. For more information about bitmap compression, see the description of the BITMAPINFOHEADER, BITMAPFILEHEADER, BITMAPV4HEADER, and BITMAPV5HEADER structures.

An application can create a DIB from a DDB by initializing the required structures and calling the GetDIBits function. To determine whether a device supports this function, call the GetDeviceCaps function, specifying RC_DI_BITMAP as the RASTERCAPS flag.

An application that needs to copy a bitmap can use TransparentBlt to copy all pixels in a source bitmap to a destination bitmap except those pixels that match the transparent color.

An application can use a DIB to set pixels on the display device by calling the SetDIBitsToDevice or the StretchDIBits function. To determine whether a device supports the SetDIBitsToDevice function, call the GetDeviceCaps function, specifying RC_DIBTODEV as the RASTERCAPS flag. Specify RC_STRETCHDIB as the RASTERCAPS flag to determine if the device supports StretchDIBits.

An application that simply needs to display a pre-existing DIB can use the SetDIBitsToDevice function. For example, a spreadsheet application can open existing charts and display them in a window by using the SetDIBitsToDevice function. To repeatedly redraw a bitmap in a window, however, the application should use the BitBlt function. For example, a multimedia application that combines animated graphics with sound would benefit from calling the BitBlt function because it executes faster than SetDIBitsToDevice.

 

CreateCompatibleBitmap

The CreateCompatibleBitmap function creates a bitmap compatible with the device that is associated with the specified device context.

HBITMAP CreateCompatibleBitmap(
HDC
hdc, // handle to DC
int nWidth, // width of bitmap, in pixels
int nHeight// height of bitmap, in pixels
);

 

Parameters

hdc
[in] Handle to a device context.
nWidth
[in] Specifies the bitmap width, in pixels.
nHeight
[in] Specifies the bitmap height, in pixels.

Return Values

If the function succeeds, the return value is a handle to the compatible bitmap (DDB).

If the function fails, the return value is NULL.

Windows NT/2000/XP: To get extended error information, call GetLastError.

Remarks

The color format of the bitmap created by the CreateCompatibleBitmap function matches the color format of the device identified by the hdc parameter. This bitmap can be selected into any memory device context that is compatible with the original device.

Because memory device contexts allow both color and monochrome bitmaps, the format of the bitmap returned by the CreateCompatibleBitmap function differs when the specified device context is a memory device context. However, a compatible bitmap that was created for a nonmemory device context always possesses the same color format and uses the same color palette as the specified device context.

Note: When a memory device context is created, it initially has a 1-by-1 monochrome bitmap selected into it. 当内存DC被创建的时候,填充它的是黑白像素的BITMAP。If this memory device context is used in CreateCompatibleBitmap, the bitmap that is created is a monochrome bitmap. To create a color bitmap, use the hDC that was used to create the memory device context, as shown in the following code:

    HDC memDC = CreateCompatibleDC ( hDC );    HBITMAP memBM = CreateCompatibleBitmap ( hDC, nWidth, nHeight );    SelectObject ( memDC, memBM );

If an application sets the nWidth or nHeight parameters to zero, CreateCompatibleBitmap returns the handle to a 1-by-1 pixel, monochrome bitmap.

If a DIB section, which is a bitmap created by the CreateDIBSection function, is selected into the device context identified by the hdc parameter, CreateCompatibleBitmap creates a DIB section.

When you no longer need the bitmap, call the DeleteObject function to delete it.

 

CreateCompatibleDC

 

waterathena例子分析:

UI.XML文件中带有坐标的BITMAP图片的解析:

<bitmap id="main.play.nor" file="image/button/pannel_n.bmp" area="32, 54, 42, 42" />

 

调用函数

BOOL CEZBitmap::LoadBitmap( WCHAR *filename, char *idName, int x, int y, int w, int h)
{

……

HDC hDC = ::GetDC(g_hMainWnd);
m_hBitmap = CreateCompatibleBitmap( hDC, w, h );

hdcDes = CreateCompatibleDC(hDC);
SelectObject( hdcDes, m_hBitmap );

……

SetDIBitsToDevice( hdcDes, 0, 0, w, h,  x, cyDib-(y+h), 0, cyDib, pImage, pBMPInfo, DIB_RGB_COLORS );

……

}

 

 

createcompatibleBitmap()主要是为了MEMORYDC的正确使用,在使用MEMORYDC之前必须要把它和一个具有格式信息的BITMAP绑定。这个BITMAP可以没有任何图像数据,但是需要特定的格式信息。其中设定到目的设备的图像长宽。即为XML文件制定的长宽。

注意:

XML文件中制定的X,Y坐标需要进行变换,填入SetDIBBitsToDevive()函数。

 

 

<bitmap id="main.play.nor" file="image/button/pannel_n.bmp" area="32, 54, 42, 42" />

以UI.XML文件中的一句话为例子:描述了PLAYER按钮所放置的位置。area:32,54,42,42 为整张图片中以左上角为原点(0,0)得到的排列坐标。如下图所示

pannel_n

(坐标系的x,y坐标系增长方向由红色箭头标识)

 

但是我们的SetDIBBitsToDevive()的坐标原点以左下为(0,0),扫描方式是从下向上扫描方式。

那么源文件中PLAY按钮的坐标需要重新计算:图片的真实高度-Play按钮距离图片上方的高度(即XML中的Y坐标)-PLAY按钮在图片中的高度(即XML文件中定义的H);

即下图(?,?)坐标的计算方式。

pannel_n2

(坐标系的X,Y坐标系增长方向由红色箭头标识)

 

 

 

 

 

 

SetDIBitsToDevice( hdcDes, 0, 0, w, h,  x, cyDib-(y+h), 0, cyDib, pImage, pBMPInfo, DIB_RGB_COLORS );

这个语句的解释方式:扫描image/button/pannel_n.bmp整张图,按照从下往上的方式扫描,左下为原点。那么复制该图片的(x, cyDib-(y+h), w,h)区域到目标DC的(0, 0, w, h)区域。

这样一来一个单独的BUTTON 区域就绘制出来了。

原创粉丝点击