Multimedia graphic image technology

xiaoxiao2021-03-06  79

3 multimedia graphic image technology

Now we tell the most important and core technologies in Windows multimedia - graphics technology. For Windows graphic image technologies, including basic GDI draws pairs such as points, lines, rectangles, images, and bitmap files, which are broadcasted to use the movie files that use Windows image graphics technology.

We mainly tell the BMP file implementation process, palette applications, and some BMP image synthesis techniques, such as airmut technology, BMP animation technology, etc.

BMP file structure

The BMP file consists of several parts: file header, bitmap information head, palette, data area. Below this picture shows the BMP file structure:

The necessary conditions for Windows bitmaps display:

We analyze a Windows API function:

Int setDibitStodevice (HDC, UXDEST, UYDEST, UWIDTH, UHEIGHT, UXSRC, UYSRE,

USTARTSCAN, CSCANLINES, LPVBITS, LPBMI, FUCOLORUSE

Check out the tenth, eleven parameters of this function LPVBITS, LPBMI. Where lpvbits indicate the address of the BMP data in memory, LPBMI points to a BitmapInfo data structure, as long as there are two parameters, a BMP bitmap is determined. Everyone can see the vast majority of Windows graphic image browsing software can analyze the file format, such as JPG, GIF, PCX, TIF, etc., all build a data buffer in memory, and establish one according to graphic image format. BitmapInfo's data structure, then written on the screen with the SetDibitStodevice function. We will basically use this way.

Windows palette

Windows's display devices can be displayed thousands of colors, but the number of colors that can be displayed at the same screen is not thousands of species on the same screen. We divide the display device into monochrome, sixteen colors, two hundred Fifty-six colors, enhance color, true color, or divided into 1bit, 4bit, 8bit, 16bit, 24bit, according to the display bit area. Since Windows's theoretical display and actual display are not consistent, you need a solution to solve this problem, this is to use the palette. Why do we use a palette that we don't make a detailed discussion, just a little bit, only hexadecimal and 256 color bitmap need palette.

Below is a method using a palette

First read a bitmap file, then determine the number of color of this bitmap file, if this file is sixteen or two hundred and six colors, then there will be a palette information in this file, read this The palette information, converts this palette information into a logPalette structure, generates a logical palette according to this structure, and then use the SelectPalette function to select the logical palette in the device description table each time you want to display the bitmap. HDC, then use the realizepalette function to implement this palette, use the SelectPalette function after the display is complete, select the old palette, and a palette call process is completed.

Constructing Windows Image Processing Category Library

We assume that this class library contains the following features:

Treatment palette;

Generate logical palette; implement palette; process BMP file

Read BMP images; display images; implement the above "processing palette" function; process FLC animation

Read the FLC animation file; play parameter settings; display images; implement the above "Processing Pattern" function; these assumes that we see the class libraries to be designed to have some public features:

1. Treat a palette;

2. In addition to "1", "2" and "3" contain the necessary conditions for Windows image display: structure

BitmapInfo and a Bitmap data area.

To this end, we first construct a class that handles the palette, which implements the above "processing palette" function. Why handle the palette separately without letting it attach "processing BMP files" or "handling FLC animation", why, in large-scale multimedia programming, there are often dozens or hundreds of BMP images or animations. Only one or two palettes, excessive flooding panels tend to flash during layout, and waste memory spaces, thus being processed separately.

Second, we construct a class that handles DIB images: In this class, the core is two parameters (structural BitmapInfo and a Bitmap data area) and a display function show (). This class is inherited in the palette class because the processing image file must process the palette. And becoming the base class of other image files, as these two structures and functions must be handled by handling the image file.

With these two base classes, we construct other classes on the basis of these two base classes.

// mybmp.h: interface for the mybmp.

//

//

#if! defined (AFX_MYBMP_H___34151075_C57B_11D1_94F8_0000B431BBA1__INCLUDED_)

#define AFX_MYBMP_H__34151075_C57B_11D1_94F8_0000B431BBA1__INCLUDED_

#iF _MSC_VER> = 1000

#pragma overce

#ENDIF / / _MSC_VER> = 1000

#define falsereturn {_lclose (hfile); return 0;}

#define imagecolors (x, y) (1 << ((x) * (y))))))

/ / Single line BMP data bytes

#define dword_wbytes (x) ((((x) 31 ul >> 5) << 2)

#define min (a, b) (((a) <(b))? (a): (b))

#ifdef Win32

#define BMPDATABYTE

#ELSE

#define bmpdatabyte_huge

#ENDIF

// #include "test.cpp"

#define palversion 0x0300

#define dib_StorageWidth (x) ((x 3) & ~ 3)

#define widthbytes (i) ((i 31) / 32 * 4)

#define maxpalette256 / * max. # supported paste entries * /

#define maxloadflcnumber255

Class Palette

{

Private:

HPALETTE HOLDPAL;

protected:

HPALETTE HPAL;

PUBLIC:

Palette () {memset (this, 0, sizeof (palette));

~ Palette () {if (hpal) deleteObject (hpal);

HPALETTE CREATEPAL (BitmapInfo *);

HPALETTE CREATEPAL (LPLOGPALETTE PAL);

HPALETTE getPal () {return hPal;}

UINT setPal (HDC);

Void ResetPal (HDC);

}

Class MyDib: Public Palette

{

protected:

Hglobalhdata;

Struct

{

BitmapInfoheaderb;

RGBQUADR [256];

} P;

PUBLIC:

LPbitmapInfo lpinfo;

LpbitmapInfoheader lpinfohead;

MYDIB ();

~ Mydib ();

Int show (HDC, INT, INT, INT, INT, INT, DWORD);

Inline Int Show (HDC HDC, INT X1, INT Y1, INT X2, INT Y2,

INT X3, INT Y3, INT X4, INT Y4)

{Return SHOW (HDC, X1, Y1, X2, Y2, X3, Y3, X4, Y4, SRCCOPY);

Inline Int Show (HDC HDC, INT X, INT Y)

{Return SHOW (HDC, X, Y, 0, 0, 0, 0, 0, 0, SRCCOPY);

Inline Int Show (HDC HDC)

{Return SHOW (HDC, 0, 0, 0, 0, 0, 0, 0, Srccopy);

Show (MyDIB *, Int, int, int, int, int, int, byte, byte, byte,

Byte, Byte, Byte;

Show (MyDIB *, int, int, int, int, int, register

Byte, register byte;

}

Class Bmp: Public MyDIB

{

PUBLIC:

INT OPEN (LPCSTR, INT);

INT inline open (lpcstr name) {return open (name, 0);}

}

#ndif //! defined (AFX_MYBMP_H___34151075_C57B_11D1_94F8_0000B431BBA1__INCLUDED_)

// mybmp.cpp: Implementation of the mybmp class.

//

//

#include "stdafx.h"

#include "mybmp.h"

#ifdef _Debug

#undef this_file

Static char this_file [] = __ file__;

#define new debug_new

#ENDIF

//

// construction / destruction

//

//

// Class Palette

//

UINT PALETTE :: SetPal (HDC HDC)

{

IF (HPAL)

{

SelectPalette (HDC, HPAL, 0);

RETURN REALIZEPALETTTE (HDC);

}

Else Return False;

}

Void Palette :: ResetPal (HDC HDC)

{

IF (Holdpal)

{

SelectPalette (HDC, Holdpal, 0);

Holdpal = 0;

}

}

HPALETTE PALETTE :: CreatePal (LPLOGPALETTE PAL)

{

IF (hpal) deleteObject (HPAL);

IF (PAL_> PALNUMENTRIES <= 256) HPAL = CREATEPALETTE (PAL);

Return HPAL;

}

//

// Class Dibpalette

//

HPALETTE PALETTE :: CreatePal (BitmapInfo * Info)

{

Struct

{

Word Palversion; Word PalNumentries;

Paletteentry Palpalent [256];

} P;

LPLOGPALETTE PAL = (LPLOGPALETTE) & P;

PAL_> paRversion = 0x300;

PAL_> PALNUMENTRIES =

/*Min*/( (Word )ImageColors (Info_nmberbmiheader.bibitcount, 1)) ;//, info_>bmiheader.biClrused;

For (int i = 0; i panelnutentries; i )

{

PAL_> PALPALENTRY [I] .pered = info_> bmicolors [i] .rgbred;

PAL_> Palpalent [i] .pegreen =

INFO_> Bmicolors [i] .rgbgreen;

PAL_> PALPALENTRY [I] .peblue = info_> bmicolors [i] .rgbblue;

PAL_> PALPALENTRY [I] .peflags = pc_nocollapse;

}

Return Palette :: CreatePal (PAL);

}

//

// mydib class

//

MYDIB :: MYDIB ()

{

MEMSET (this, 0, sizeof (bmp));

Lpinfo = (lpbitmapinfo) & p;

LPINFOHEAD = (lpbitmapinfohead) & p;

}

MYDIB :: ~ MYDIB ()

{

IF (HDATA) GlobalFree (HDATA);

}

INT MYDIB :: Show (HDC HDC, INT X1, INT Y1, INT X2, INT Y2, INT X3,

Int Y3, INT X4, INT Y4, DWORD ROP)

{

IF (x2 <= 0) x2 = (int) LPINFOHEAD_> BIWIDTH X2;

IF (Y2 <= 0) Y2 = (int) LPINFOHEAD_> BIHEIGHT Y2;

IF (x4 <= 0) x4 = (int) LPINFOHEAD_> BIWIDTH X4;

IF (Y4 <= 0) Y4 = (int) LPINFOHEAD_> BIHEIGHT Y4;

// if (w_hp) setPalette (HDC);

BMPDATA * DATA = (BMPDATA *) GlobalLock (HDATA);

// int i = stretchdibits (HDC, X1, Y1, X2, Y2, X3, Y3, X4, Y4,

Data, Info, DIB_RGB_COLORS, ROP

INT i = stretchdibits (HDC, X1, Y1, X2, Y2, X3,

(int) LPINFOHEAD_> Biheight_Y3_Y4, X4, Y4, DATA, LPINFO,

DIB_RGB_COLORS, ROP);

GlobalUnlock (HDATA);

Return I;

}

Int MyDib :: Show (MyDIB * DIB, INT X1, INT Y1, INT X2, INT Y2, INT X3, INT Y3,

BYTE R1, BYTE G1, BYTE B1, BYTE R2, BYTE G2, BYTE B2)

{

Register DWORD C1 = ((DWORD) R1) << 16) ((DWORD) G1) << 8) B1;

Register DWORD C2 = ((DWORD) R2) << 16) ((DWORD) G2) << 8) B2; Register DWORD C;

Register DWORD * RQ = (DWORD *) P.R;

IF (! DIB_> HDATA)

{

Memcpy (DIB, this, sizeof (mydib));

DIB_> LPINFO = (LPbitMapInfo) & (DIB_> P);

DIB_> LPINFOHEAD = (LPbitmapInfoHeader) & (DIB_> P);

DIB_> LPINFOHEAD_> BIWIDTH = X2 X1;

DIB_> LPINFOHEAD_> BIHEIGHT = Y2 Y1;

DWORD SIZE = DIB_> LPINFOHEAD_> BIWIDTH

* DIB_> LPINFOHEAD_> BIHEIGHT

* ImageColors (DIB_> LPINFOHEAD_> BIBITCOUNT, 1) / 8;

DIB_> HDATA = GlobalAlloc (GMEM_FIXED, SIZE);

}

X2 = min (x2, (int) DIB_> LPINFOHEAD_> BIWIDTH _X1);

Y2 = min (Y2, (int) DIB_> LPINFOHEAD_> BIHEIGHT_Y1);

BMPDATA * DATA1 = (BMPDATA *) Globalock (HDATA);

BMPDATA * DATA2 = (BMPDATA *) GlobalLock (DIB_> HDATA);

DWORD W1 = DWORD_WBYTES (LPInfohead_> BIWIDTH

* LPINFOHEAD_> BIBITCOUNT);

DWORD W2 = DWORD_WBYTES (DIB_> LPINFOHEAD_> BIWIDTH

* DIB_> LPINFOHEAD_> BIBITCOUNT);

Data1 = (w1 * (lpinfohead_> biheight_y3_y2)

X3 * LPINFOHEAD_> BIBITCOUNT / 8);

DATA2 = (w2 * (dib_> lpinfohead_> biheight_y1_y2)

X1 * DIB_> LPINFOHEAD_> BIBITCUNT / 8);

For (int J = 0; j

{

For (Register Int i = 0; i

{

C = * (RQ * (DATA1 I));

IF ((C C2) || ((Word) C <(Word) C1)

|| (WORD) C> (Word) C2)

|| (BYTE) C <(byte) C1)

|| (BYTE) C> (Byte) C2)) * (DATA2 I) = * (DATA1 I);

}

DATA1 = W1;

DATA2 = W2;

}

GlobalUnlock (HDATA);

GlobalUnlock (DIB_> HDATA);

Return True;

}

Int MyDib :: Show (MyDib * Dib, Int x1, int y1, int x2, int y2, int x3,

Int Y3, Register Byte X, Register Byte Y)

{

Register BmpData D;

IF (! DIB_> HDATA)

{

Memcpy (DIB)); DIB_> LPINFO = (LPBITMAPINFO) & (DIB_> P);

DIB_> LPINFOHEAD = (LPbitmapInfoHeader) & (DIB_> P);

DIB_> LPINFOHEAD_> BIWIDTH = X2 X1;

DIB_> LPINFOHEAD_> BIHEIGHT = Y2 Y1;

DWORD SIZE = (DIB_> LPINFOHEAD_> BIWIDTH 1)

* DIB_> LPINFOHEAD_> BIHEIGHT

* DIB_> LPINFOHEAD_> BIBITCOUNT / 8;

// ImageColors (DIB_> LPINFOHEAD_> BIBITCOUNT, 1) / 8;

DIB_> HDATA = GlobalAlloc (GMEM_FIXED, SIZE);

}

X2 = min (x2, (int) DIB_> LPINFOHEAD_> BIWIDTH _X1);

Y2 = min (Y2, (int) DIB_> LPINFOHEAD_> BIHEIGHT_Y1);

BMPDATA * DATA1 = (BMPDATA *) Globalock (HDATA);

BMPDATA * DATA2 = (BMPDATA *) GlobalLock (DIB_> HDATA);

DWORD W1 = DWORD_WBYTES (LPInfohead_> BIWIDTH

* LPINFOHEAD_> BIBITCOUNT);

DWORD W2 = DWORD_WBYTES (DIB_> LPINFOHEAD_> BIWIDTH

* DIB_> LPINFOHEAD_> BIBITCOUNT);

Data1 = (w1 * (lpinfohead_> biheight_y3_y2)

X3 * LPINFOHEAD_> BIBITCOUNT / 8);

DATA2 = (w2 * (dib_> lpinfohead_> biheight_y1_y2)

X1 * DIB_> LPINFOHEAD_> BIBITCUNT / 8);

For (int J = 0; j

{

For (Register Int i = 0; i

{

D = * (DATA1 I);

IF ((D y)) * (DATA2 I) = D;

}

DATA1 = W1;

DATA2 = W2;

}

GlobalUnlock (HDATA);

GlobalUnlock (DIB_> HDATA);

Return True;

}

//

// Class BMP

//

INT BMP :: Open (LPCSTR File, Int Sty) // style: 0: Enable Hpal 1: DISNABLE HPAL

{

BitmapfileHeader FileHead;

INT i; //, j, k;

Hfilehfile;

DWordubytes;

DWORDSIZE;

Hfile = _Lopen (file, of_read);

IF (hfile == hfile_error) return 0;

// read the file header

i = _lread (Hfile, & Filehead, Sizeof (BitmapfileHeader);

IF (i == hfile_error) falsereturn; // goto bmp_false_end;

T //Type=FileHead.BFTYPE; // read information head

I = sizeof (BitmapInfoHeader) sizeof (rgbquad) * 256;

_Lread (HFile, Lpinfohead, i);

// Establish a palette

IF (! style "CREATEPAL (LPInfo);

Ubytes = _llseek (HFILE, 0, 2);

IF (FileHead.BFSize> ubytes) falsereturn; // goto bmp_false_end;

IF (HDATA) GlobalFree (HDATA);

SIZE = ubytes_filehead.bfoffbits;

HDATA = GlobalAlloc (GMEM_FIXED, SIZE);

BMPDATA * DATA = (BMPDATA *) GlobalLock (HDATA);

// read data

_llseek (Hfile, FileHead.Bfoffbits, 0);

For (; _ Lread (Hfile, Data, RBLOCK) == RBLOCK; DATA = RBLOCK;

GlobalUnlock (HDATA);

_lclose (hfile);

Return True;

}

In the MyBmp.h file, we define three classes: Class Palette,

Class Dibpalette, class mydib. Where Palette is the base class. Dibpalette inherited the class Palette, and the class MYDIB inherited the class Dibpalette.

Class Palette:

In this class, we define two member variables HPAL and HOLDPAL, seven member functions. These seven member function functions are as follows: two of them are constructor and destructive functions, two functions createpal, respectively.

(BitMapInfo *), createPal (LPLOGPALETTE) Complete the role of constructing palette according to the specified parameters, a function setpal (HDC) implements palette, a function resetpal (HDC) recovery palette, a function getPal () get coloring board.

Class mydib:

In this class, we define two core member variables P and HData, where P is a custom structure, which contains a bmpinfo header information and a palette, HDATA is a handle pointing to a piece of data in memory, two other The parameters LPINFO and LPINFOHEAD are actually pointing to the pointer to the structure P. The core of the four member functions show () is an API function setDibitStodevice (). Their functions are displayed on the screen based on the structural P and handle HDATA.

Class BMP:

In this class, we only define two member functions Open, and their function is to open a BMP file and fill the file content into the parameters of its base class. As we mentioned in the multimedia programming, we need to use a public palette, but sometimes you need private palette, so the second parameter in the open function specifies this difference, and if the parameter is 0, it constructs your own HPAL. Otherwise, your HPAL is invalid.

Case Analysis

In this example, we will transfer a BMP file and display it on the screen, and the program process is as follows:

Create a dialog attribute application, then join the source file "mybmp.h" and "mybmp.cpp" provided in the CD, and add "#include" mybmp.h "in the file" Showbmpdlg.h "," Add a member variable "BMP BMP" in the class "cshowbmpdlg" definition to read the file "1.BMP" in the member function of class "cshowbmpdlg" onnitdialog () "" BMP.Open " Add the following palette in onpaint () to implement function and display function bmp.setpal (dc.m_hdc)

bmp.show (dc.m_hdc)

bmp.resetpal (dc.m_hdc)

Note SetPal () and resetPal () To pair, setPal () is used before show (), resetpal () after Show (). Compile and run.

4 image synthesis

If you want to achieve an animation, such as a mouse run from the left side of the screen, the general book is called: First, make a mouse picture, and then draw a black and white mouse mask picture. First, the screen is processed by a mask diagram, and then processes the mouse picture with a mask, and finally put the treated mice on the screen, and the three Bitblt functions are handled before and after. And so that the process will flash significantly on the screen. To stop flashing, you must first make a compatible DC, first copy the screen picture to the compatible DC, and then copy the mouse after compatibility with the DC. It is necessary to use five Bitblt functions before and after. The picture is relatively small, if the picture is very big, that speed is simply "Today, this computer, the human face is red, and the people don't know where, the mouse is still slowly crawling." Is there any other solution?

How to achieve transparent bitmap

The most stupid approach: Directly draw a setpixel function by point on the screen. General method: use the Bitblt function to make at least three operations. The fastest way: write screen directly. The most cost-effective approach: write the data buffer directly.

Discussion in four ways:

For programmers who first engage in image processing, it seems that the way to draw past is the first choice. However, it is true that this is the slowest method in the world. It is the most ideal animation effect that it implements it. "Last year, tears Today, it streams to the mouth. " Bitblt: The previous introduction has been introduced here. Direct Write Screen: This method is more used in this way, programming in a Windows environment, only WING WING can only be implemented in Windows 3.1 environments, and functions CREATEDIBSECTION () or use MicrosoftDirectX functions in Win95 or NT. This way we will introduce them. Not discussed here. Write data buffer: This method is smaller for environmental requirements, no external software, compatible with 3.1 and 95, NT, speed can also, its principle is similar to the direct write screen, and can be easily ported to direct written mode Go in. We will introduce this method here.

Read and write data buffer:

Everyone may still remember the class mydib introduced in the previous, there are two parameters, one is the BMP information head, one is the BMP data area, whether everyone can imagine how to modify the BMP data area, then display the image? ? This data area is the data buffer we have to use.

Transparent bitmap

To achieve a transparent bitmap, you must first have two pictures, one as a source diagram, one as a destination bitmap, the programmer should post the source chart to the destination chart, and to indicate what color to block the off For this reason, we add a function on the class mydib (MyDIB * Dib, Int x1, int y1, int x2, int y2, int x3, int y3, byte r1, byte g1, byte b1, byte r2, byte G2, BYTE B2), this function is a bit similar to the Bitblt function, it means: copy the data in the self-buffer to the buffer of class DIB, where from RGB (R1, G1, B1) to RGB The color of (R2, G2, B2) is transparent color, X1, Y1, X2, Y2, X3, Y3 are the target coordinate, copy range, source coordinate, and the meaning is the same as Bitblt. During the implementation of the show function, we first calculate the source data to be changed, the target data address, and then analyze if the data color to be copied belongs to the color, if it is a screen color, no copy data, otherwise copy. Another transparent bitmap method

Transparent color is a relatively simple implementation, but sometimes there is another way of implementation, which is to specify the color index mode, we can specify a certain number to a certain number in a palette to a certain number transparent color . Therefore, in Class MyDIB, add a function show (MyDIB * DIB, INT X1, INT Y1, INT X2, INT Y2, INT X3, INT Y3, REGISTER BYTE X, Register Byte Y), the principle of this function and the previous The way is similar, but it is only four parameters than the previous way, and it is changed from color specified transparencies to specify transparent colors with color index.

Transparent bitmap refresh speed

Change the speed of the data buffer mode, or Bitblt speed fast? If the Bitblt is fast, the previous heart is not a rolling Yangtze River, for this, we must use an instance to analyze, establish a dialog-based program named TP, join the source program mybmp.cpp and mybmp. h Add #include "mybmp.h" in the TPDLG.H file header, add two member variables BMP1 and BMP2 in class CTPDLG. When the window is initialized, set the timer, open the file "1.BMP", "2.BMP", complete the copy and refresh process, compile and run the program during the timer message response process. We can see a "allTIME" parameter that shows that the refresh 256 bitmap needs to be about 20_21 seconds. Now Note Frequency Function BMP1.SHOW ((MYDIB *) & BMP2, 0, 0, 640, 480, 0, 0, 0, 0, 0, I, I, I), and then Refresh 256 positions It takes about 15_16 seconds, which is the time required to use the function StretchDibits. It can be seen that a transparent bitmap completion time is equivalent to a four bitblt time, the three Bitblt time (difference effects) of the Bitblt method, and the five Bitblt time (good effect) is much better. Of course, this is much better than the direct written screen.

Now replace the bottom function to BMP1.SHOW ((MyDib *) & bmp2, 0, 0, 640, 480, 0, 0, 0, i), we are not surprised to see the current time to refresh 256 bitmap is 16_17 seconds, almost Think, the buffer reading and writing time has been

It can be ignored.

Figure 5.3

Case Analysis

In this example, we have to achieve an animation, a background is a great good person, with a dog in front of it ran to run. The material needs five pictures, including one, four animation. We analyze its implementation: In class cmoviedlg, we first define five images with statement BMP BMP [5], and then define a temporary picture with statement MYDIB TEMP. After the dialog initialization process function, the five bitmaps are read, and the timer is one hundred milliseconds, and the operation procedure in the timer response function is as follows: First write the background to the temporary picture, and then the puppy penetrate white Write Into the temporary picture, and finally write the temporary picture on the screen.

Figure 5.4

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

New Post(0)