✓ Http://blog.csdn.net/tongyue/archive/2007/07/30/1716572.aspx
How to compress GIF images and compress images
We know that bitmap files and Icon files record image information in pixels. Such records generate very large files called uncompressed files, it can be used on a single machine. it is undesirable to spread it online. How can we further compress images? GIF is a common compression technology and a popular image file format on the Internet.
GIF compression standard:
As a compression standard, GIF is widely supported by many software companies, including Microsoft. GIF is available in two versions: gif87a and gif89a, and is an early animation format.
How is gif compressed? It first converts an image into an 8-bit 256-color image (or 128-color, 64-color, 32-color, 16-color, 8-color, 4-color, or 2-color ), taking the 256 color as an example, an 8-bit binary information is required for a pixel, that is, one byte. Then, based on the pixel arrangement rules in the image, GIF creates a color-like arrangement table, which uses 9-bit integer values to represent the arrangement rules of pixels, achieve the goal of compression (its name is LZW CompressionAlgorithm). It sounds hard to understand. I will give an example later. Finally, when saving the data to the file, add a nine-digit integer (in the range of 0 ~ 511) convert to an 8-bit byte value and save it to the GIF file.
Color Sorting table:
Assume that there is a series of image pixel streams (stored in the byte value type Buf () array) for GIF compression, the first 20 of these data streams, that is, Buf (0 )~ The values of BUF (19) are:
8 8 8 8 99 99 8 8 8 8
8 8 8 99 99 8 99 8 99 8
The first value of the data stream is recorded in the Information Section of the file, and the actual computation starts from the second one:
OperationProgramCode:
(Bint (0) = 256)
SP = right $ ("00" & Buf (0), 3)
Icode = Buf (0)
For I = 1 to 19
...
...
SB = right $ ("00" & Buf (I), 3)
SP = sp & sb
On Error resume next
Whether the required members have been saved in the icode = coltable (SP) 'Set
If err <> 0 then' is not found
N = coltable. Count
Coltable. Add N + 258, SP 'add members and Indexes
J = J + 1
Bint (j) = icode' Save the converted value to the integer set to be saved
SP = sb
Icode = Buf (I)
Err. Clear
End if
Next
The variable changes during the operation are as follows:
Buf () No. coltable bint () Value
Member Index
256
1 258 008008 8
3 259 008008008 258
4 260 008099 8
5 261 099099 99
6 262 099008 99
9 263 008008008008 259
13 264 008008008008099 263
15 265 099099008 261
17 266 008099008 260
260
As shown in the above calculation results, several problems can be explained:
1. the file is compressed, and 20 bytes are compressed into 10 9-bit integers, because the color rules are saved in the set of color arrangement tables, A value can be used to represent the information of several pixels at the same time.
2. the size of the compressed file is related to the size of the image (the length of the pixel stream). The complexity of the image also affects the size of the compressed file, the simpler the image (the larger the block with the same color), the smaller the compressed file.
3. To ensure that the converted integer value cannot exceed 9 digits, the color sorting table can only contain 256 ~ 511, And because 256,257 is retained as a special sign, only 258 ~ is actually available ~ 511 a total of 254, if more than, it is necessary to clear the old table, re-establish (256 is the sign of re-initializing the color arrangement table, 257 is the sign of the end of the pixel Stream)
4. It must be noted that when converting a 256-Color Pixel stream, unlike a bitmap, it starts from the upper left corner of the image and performs a downward scan. If you use an API function to obtain the pixel stream, you must rearrange the stream.
GIF compression features:
Before GIF compression, the image must be converted to an image of less than 256 colors. Therefore, the quality of the image is greatly reduced. However, from the preceding compression results, each value in the pixel stream of the original image can be accurately traced and saved. That is to say, when the GIF is decompressed, each pixel on the image can be accurately restored (if the source image is 256 colors, the image is taken as an image ). Therefore, GIF compression is also called lossless compression. This compression can accurately reflect the clear edge of the image. If the image is based on text scanning, GIF compression is definitely the best choice.
GIF file composition:
The GIF file consists of the following parts:
Version File Header System color palette [secondary information] image header information Image Compression information ending mark
(6 bytes) (7 bytes) (8 bytes) (11 bytes) (255 + 255 + + n) bytes) (2 bytes)
Version: gif89a or gif87a
Auxiliary Information: this information is available only in GIF Transparent Display or GIF animated files. It is also set to implement these features.
System color palette: In bitmap and Icon files, each color is 4 bytes, and in GIF files, each color is 3 bytes.
Image compression information: because the size of the information after image compression is related to the complexity of the image itself, it is not like a bitmap. As long as you know the size of the image, you can calculate the file size, the file size must be known until all the pixel streams are compressed. Therefore, the image compression information in a GIF file is in the unit of 254 bytes and applied backward (each unit is preceded by a byte to indicate the length of the unit, the actual size of each unit is 255 bytes), and the last unit is applied for in actual size.
End mark: 0 59 is used as the end mark of the file.
Programming example:
To Compress GIF files, use VB6 to create a project named "bnptogif" and scalemode = 3-pixel. A text box is used to enter the file name to be opened or the file name to be saved; two buttons, three labels, and two image boxes. picture2 is used to display the File compression progress, width: 400, height: 13. Picture1 is used to display open bitmap. Options include visible = false, autoredraw = true, autosize = true, scalemode = 3-pixel, and borderstyle = 0-none.
The "save" button is Enabled = false at the beginning. After you press "open" to open the bitmap file entered in text1, it becomes available, click to convert the original bitmap to a 256-color GIF file (automatically change the extension name or save it as the re-input file name in text1)
Program code
Option explicit
Private type rgbtriple 'color palette
Rgbred as byte
Rgbgreen as byte
Rgbblue as byte
End type
Private type gifscreendescriptor 'file Header
Logical_screen_width as integer 'image width
Logical_screen_height as integer 'image height
Flags as byte indicates the quality of the file (the color in the color palette ).
Background_color_index as byte 'saves the value of the first pixel in the pixel stream
Pixel_aspect_ratio as byte 'is 0
End type
'In the file header, the flags value is 256 in 231 colors, 128 in 198 colors, 165 in 64 colors, 132 in 32 colors, 227 in 16 colors, 194 in 8 colors, and 161 in 4 colors.
Private type gifimagedescriptor 'image information Header
Imageseparator as byte 'is 44
Left as integer 'left
Top as integer 'Right
Width as integer 'width
Height as integer 'height
Format as byte 'is 0
Data as byte is the number of digits occupied by each pixel.
End type
Private type gifimageend' end flag
Dat1 as byte is 0
Dat2 as byte is 59
End type
Private const gif89a = "gif89a"
Dim coltable as new collection 'is used to sort colors during LZW compression.
Dim bitpos and bitval as byte are used for bit location during bit operation and converted byte values, and the value is written to gfbyt (p255 ).
Dim p255 as long 'total number of bytes written to the file (positioning)
Dim gfbyt () as byte 'refers to the byte stream written to the file
Dim Buf () as byte 'image pixel stream (256 colors or less)
Dim BPOs (12) as long 'is used to compare the numbers of 1, 2, 4, 8 ....
Dim fname as string
'Segment gfbyt () (254 for segments) and write the file
Private sub putbyte ()
Dim I, K as integer
Dim J as long
K = int (p255/254)
Dim SZ () as byte
Redim SZ (k)
SZ (K) = p255 mod 254
For I = k-1 to 0 step-1: SZ (I) = 254: Next
K = 0
For J = 0 to p255
If J mod 254 = 0 then put #1, SZ (k): K = k + 1
Put #1, gfbyt (j)
Next
End sub
'Write the compressed Table value to gfbyt ()
'When the color is 256, the table value is an integer with a variable length (9-12 digits), 256 is used to clear the old table, 257 is used to end the image, and the table items are 3837 in
'In the case of four colors, the table value is an integer with a variable length (3-12 digits), 4 is to clear the old table, 5 is to end the image, and the table items are 6-4089 in total
Private sub addbyte (byval bval as long, byval vlen as byte)
Dim I as byte
For I = 0 to vlen-1
If (bval and BPOs (I) Then bitval = bitval + BPOs (bitpos)
Bitpos = bitpos + 1
If bitpos = 8 then
Bitpos = 0
Gfbyt (p255) = bitval
Bitval = 0
P255 = p255 + 1
Redim preserve gfbyt (p255) 'apply for another byte and keep the original data
Gfbyt (p255) = 0
End if
Next
End sub
Private sub commandementclick ()
Fname = text1.text
If right (fname, 3) <> "BMP" then label3.caption = "the file is not a. BMP file": Exit sub
If Dir (fname) = "" Then label3.caption = "the file does not exist": Exit sub
Picture1.picture = loadpicture (fname)
Command2.enabled = true
End sub
Private sub command2_click ()
'Check whether the file name is correct
Fname = text1.text
Dim I, j as integer
Dim PW, pH as integer
I = instr (1, fname ,"/")
Do while I> 0: J = I: I = instr (1, fname, "/"): loop
If Dir (mid (fname, 1, J), vbdirectory) = "" Then label3.caption = "the file path does not exist": Exit sub
If right (fname, 4) <> ". GIF" then fname = mid (fname, 1, Len (fname)-4) & ". GIF"
Doevents
Jindu 10
'Convert the image to 256 colors and store it in the Buf () pixel stream.
Dim R, G, B, Ra, Ga, Ba, lindex as integer
Dim Col as long
Dim K, KK as long
PH = picture1.height-1
PW = picture1.width-1
Kk = (Ph + 1) * (PW + 1)-1
Redim Buf (kk) as byte
'The calculation method used for conversion must be consistent with the algorithm used to create a color palette.
For I = 0 to pH
For J = 0 to pw
Col = picture1.point (J, I)
If cola = 16777215 then
Buf (K) = 215
Else
B = int (COL/65536)
Col = col-B * 65536
G = int (COL/256)
R = Col mod 256.
Ra = CINT (R/51)
GA = CINT (G/51)
BA = CINT (B/51)
Buf (K) = ba * 36 + GA * 6 + RA
End if
K = k + 1
Next
Next
Doevents
Jindu 50
'Write a GIF File
Dim SCR as gifscreendescriptor
Dim IM as gifimagedescriptor
Dim gifpalette (0 to 255) as rgbtriple
Dim Gend as gifimageend
Dim sprefix as string
Dim sbyte as string
Dim intcode as integer
Dim ncount as byte
'Create up to 216 colors in the system color palette. The calculation method for converting 256 colors in front must be consistent with the method used here!
For B = 0 to 255 step 51
For G = 0 to 255 step 51
For r = 0 to 255 step 51
Gifpalette (lindex). rgbblue = B
Gifpalette (lindex). rgbgreen = G
Gifpalette (lindex). rgbred = r
Lindex = lindex + 1
Next
Next
Next
SCR. Back ground_color_index = 215
SCR. Flags = 231
SCR. pixel_aspect_ratio = 0
SCR. logical_screen_width = picture1.width
SCR. logical_screen_height = picture1.height
Im. imageseparator = 44
Im. Data = 8
Im. format = 0
Im. Height = picture1.height
Im. width = picture1.width
'Write the GIF File Header
Open fname for binary as #1
Put #1, gif89a
Put #1, SCR
Put #1, gifpalette
Put #1, Im
'Perform GIF compression, from Buf () to gfbyt ()
Dim L as integer
Redim gfbyt (0)
Gfbyt (0) = 0
L = 9
Addbyte 256, l
Sprefix = right $ ("00" & Buf (0), 3)
Intcode = Buf (0)
R = 0
For k = 1 to bufsize-1
Sbyte = right $ ("00" & Buf (K), 3)
Sprefix = sprefix & sbyte
On Error resume next
Intcode = coltable (sprefix)
If err <> 0 then
Ncount = coltable. Count
If ncount = 3837 then
Addbyte intcode, l
Set coltable = nothing
Set coltable = new collection
Addbyte 256, l
L = 9
Sprefix = sbyte
Intcode = Buf (k)
Goto 10
End if
Coltable. Add ncount + 258, sprefix
If getlen (ncount + 257)> L then l = L + 1' increase the number of bytes as needed
Addbyte intcode, l
Sprefix = sbyte
Intcode = Buf (k)
Err. Clear
End if
10:
Next
Addbyte intcode, l' write the last compressed Value
Ncount = coltable. Count
If ncount> 3837 then addbyte 256, 9
Addbyte 257, 9' write end flag
Putbyte' Write File
Gend. dat1 = 0
Gend. dat2 = 59
Put #1, Gend
Close #1
Erase Buf
Erase gfbyt
Label3.caption = "successfully written" & fname & "file"
Jindu 100.
End sub
Private sub jindu (byval vol as integer) 'is used to display the progress
Picture2.cls
Label2.caption = vol & "%"
Picture2.line (0, 0)-step (Vol * 4, 13), BF
Doevents
End sub
Private function getlen (byval bval as long) as byte
Select case bval
Case 0, 1
Getlen = 1
Case is <4
Getlen = 2
Case is <8
Getlen = 3
Case is <16
Getlen = 4
Case is <32
Getlen = 5
Case is <64
Getlen = 6
Case is <128
Getlen = 7
Case is <256
Getlen = 8
Case is <512
Getlen = 9
Case is <1024
Getlen = 10
Case is <2048
Getlen = 11
Case else
Getlen = 12
End select
End Function
Private sub form_load ()
Text1.text = app. Path & "\ yeye.bmp"
Dim I as integer
For I = 0 to 12: BPOs (I) = 2 ^ I: Next 'initialize the number of bit operations
End sub
Programming example: e-book format (4-color GIF ):
The color of the system color palette directly affects the quality of the converted image and the size of the compressed file. If the image is based on text scanning, I can use two colors (black and white) for compression to obtain the maximum compression ratio without affecting image reading. In the file header, flags = 161 (4 colors). In the color palette, set only one color (255,255,255). The remaining three colors are not assigned (, 0 ), when converting the pixel stream of an image, convert it to 2 colors to achieve the highest compression rate. Many e-books now use this format (4-color GIF) compression.
I used a B4 (1150*800 pixels) image with around 1000 characters for 4-color GIF compression. Let's look at the following group of numbers: the 24-Bit Bitmap is about 2630 K, the 256-color GIF is about 45 K, and the 4-color GIF is about 24 K. It can be seen that the maximum compression ratio of a 4-color GIF image can be obtained, which is about 100: 1, and the image quality is very good. It is still clear after the image viewing tool is scaled up several times. This is also the reason why GIF became the exclusive e-book kingdom. Here is another example to show how to compress a 4-color GIF image.
Add a command3 in the previous program and write the code:
Private sub command3_click ()
'Check whether the file name is correct
Fname = text1.text
Dim I, j as integer
Dim PW, pH as integer
I = instr (1, fname ,"/")
Do while I> 0: J = I: I = instr (1, fname, "/"): loop
If Dir (mid (fname, 1, J), vbdirectory) = "" Then label3.caption = "the file path does not exist": Exit sub
If right (fname, 4) <> ". GIF" then fname = mid (fname, 1, Len (fname)-4) & ". GIF"
Doevents
Jindu 10
'Convert the image to 256 colors and store it in the Buf () pixel stream.
Dim Col as long
Dim K, KK as long
PH = picture1.height-1
PW = picture1.width-1
Kk = (Ph + 1) * (PW + 1)-1
Redim Buf (kk) as byte
'The calculation method used for conversion must be consistent with the algorithm used to create a color palette.
For I = 0 to pH
For J = 0 to pw
Col = picture1.point (J, I)
If cola = 16777215 then
Buf (K) = 1' only two colors, black and white
Else
Buf (K) = 0
End if
K = k + 1
Next
Next
Doevents
Jindu 50
'Write a GIF File
Dim SCR as gifscreendescriptor
Dim IM as gifimagedescriptor
Dim gifpalette (3) as rgbtriple
Dim Gend as gifimageend
Dim sprefix as string
Dim sbyte as string
Dim intcode as long
Dim ncount as long
Gifpalette (0). rgbblue = 0
Gifpalette (0). rgbgreen = 0
Gifpalette (0). rgbred = 0
Gifpalette (1). rgbblue = 255
Gifpalette (1). rgbgreen = 255
Gifpalette (1). rgbred = 255
SCR. background_color_index = 0
SCR. Flags = 161
SCR. pixel_aspect_ratio = 0
SCR. logical_screen_width = pw
SCR. logical_screen_height = Ph
Im. imageseparator = 44
Im. Data = 2
Im. format = 0
Im. Height = Ph
Im. width = pw
'Write the GIF File Header
Open fname for binary as #1
Put #1, gif89a
Put #1, SCR
Put #1, gifpalette
Put #1, Im
Dim L as integer
'Perform GIF compression, from Buf () to gfbyt ()
Redim gfbyt (0)
Gfbyt (0) = 0
L = 3
Addbyte 4, L
Sprefix = CSTR (BUF (0 ))
Intcode = Buf (0)
For k = 1 to bufsize-1
Sbyte = Buf (k)
Sprefix = sprefix & sbyte
On Error resume next
Intcode = coltable (sprefix)
If err <> 0 then
Ncount = coltable. Count
If ncount = 4089 then' the table value is nine characters long and the old table is cleared.
Addbyte intcode, l
'Note! The "4" sign added when the table is re-colored should be written into 12 bits, instead of three bits.
'Is 000000000100
Addbyte 4, L
Set coltable = nothing
Set coltable = new collection
L = 3
Ncount = 0
Sprefix = Buf (k)
Intcode = Buf (k)
Goto 10
End if
Coltable. Add ncount + 6, sprefix
If getlen (ncount + 5)> L then l = L + 1' increase the number of bytes as needed
Addbyte intcode, l
Sprefix = sbyte
Intcode = Buf (k)
Err. Clear
End if
10:
Next
Addbyte intcode, l' write the last compressed Value
'Write files
Addbyte 5, L
Putbyte
Gend. dat1 = 0
Gend. dat2 = 59
Put #1, Gend
Close #1
Erase Buf
Erase gfbyt
Label3.caption = "successfully written" & fname & "file"
Jindu 100.
End sub
Tong Yue, Ji tou Elementary School, Hua 'an County, Fujian Province
Tongyue2007@126.com
May 1, 2007
This article from the csdn blog, reproduced please indicate the source: http://blog.csdn.net/tongyue/archive/2007/07/30/1716572.aspx
Http://zh.wikipedia.org/zh-tw/GIF