Generate BMP image like GD in PHP
- Function imagebmp (& $ im, $ filename = '', $ bit = 8, $ compression = 0)
- {
- If (! In_array ($ bit, array (1, 4, 8, 16, 24, 32 )))
- {
- $ Bit = 8;
- }
- Else if ($ bit = 32) // todo: 32 bit
- {
- $ Bit = 24;
- }
- $ Bits = pow (2, $ bit );
- // Adjust the color palette
- Imagetruecolortopalette ($ im, true, $ bits );
- $ Width = imagesx ($ im );
- $ Height = imagesy ($ im );
- $ Colors_num = imagecolorstotal ($ im );
- If ($ bit <= 8)
- {
- // Color index
- $ Rgb_quad = '';
- For ($ I = 0; $ I <$ colors_num; $ I ++)
- {
- $ Colors = imagecolorsforindex ($ im, $ I );
- $ Rgb_quad. = chr ($ colors ['blue']). chr ($ colors ['green']). chr ($ colors ['red']). "\ 0 ";
- }
- // Bitmap data
- $ BMP _data = '';
- // Non-compressed
- If ($ compression = 0 | $ bit <8)
- {
- If (! In_array ($ bit, array (1, 4, 8 )))
- {
- $ Bit = 8;
- }
- $ Compression = 0;
- // The number of bytes in each row must be a multiple of 4.
- $ Extra = '';
- $ Padding = 4-ceil ($ width/(8/$ bit) % 4;
- If ($ padding % 4! = 0)
- {
- $ Extra = str_repeat ("\ 0", $ padding );
- }
- For ($ j = $ height-1; $ j> = 0; $ j --)
- {
- $ I = 0;
- While ($ I <$ width)
- {
- $ Bin = 0;
- $ Limit = $ width-$ I <8/$ bit? (8/$ bit-$ width + $ I) * $ bit: 0;
- For ($ k = 8-$ bit; $ k >=$ limit; $ k-= $ bit)
- {
- $ Index = imagecolorat ($ im, $ I, $ j );
- $ Bin | = $ index <$ k;
- $ I ++;
- }
- $ BMP _data. = chr ($ bin );
- }
- $ BMP _data. = $ extra;
- }
- }
- // RLE8 compression
- Else if ($ compression = 1 & $ bit = 8)
- {
- For ($ j = $ height-1; $ j> = 0; $ j --)
- {
- $ Last_index = "\ 0 ";
- $ Same_num = 0;
- For ($ I = 0; $ I <= $ width; $ I ++)
- {
- $ Index = imagecolorat ($ im, $ I, $ j );
- If ($ index! ==$ Last_index | $ same_num> 255)
- {
- If ($ same_num! = 0)
- {
- $ BMP _data. = chr ($ same_num). chr ($ last_index );
- }
- $ Last_index = $ index;
- $ Same_num = 1;
- }
- Else
- {
- $ Same_num ++;
- }
- }
- $ BMP _data. = "\ 0 \ 0 ";
- }
- $ BMP _data. = "\ 0 \ 1 ";
- }
- $ Size_quad = strlen ($ rgb_quad );
- $ Size_data = strlen ($ BMP _data );
- }
- Else
- {
- // The number of bytes in each row must be a multiple of 4.
- $ Extra = '';
- $ Padding = 4-($ width * ($ bit/8) % 4;
- If ($ padding % 4! = 0)
- {
- $ Extra = str_repeat ("\ 0", $ padding );
- }
- // Bitmap data
- $ BMP _data = '';
- For ($ j = $ height-1; $ j> = 0; $ j --)
- {
- For ($ I = 0; $ I <$ width; $ I ++)
- {
- $ Index = imagecolorat ($ im, $ I, $ j );
- $ Colors = imagecolorsforindex ($ im, $ index );
- If ($ bit = 16)
- {
- $ Bin = 0 <$ bit;
- $ Bin | = ($ colors ['red']> 3) <10;
- $ Bin | = ($ colors ['green']> 3) <5;
- $ Bin | = $ colors ['blue']> 3;
- $ BMP _data. = pack ("v", $ bin );
- }
- Else
- {
- $ BMP _data. = pack ("c *", $ colors ['blue'], $ colors ['green'], $ colors ['red']);
- }
- // Todo: 32bit;
- }
- $ BMP _data. = $ extra;
- }
- $ Size_quad = 0;
- $ Size_data = strlen ($ BMP _data );
- $ Colors_num = 0;
- }
- // Bitmap file header
- $ File_header = "BM". pack ("V3", 54 + $ size_quad + $ size_data, 0, 54 + $ size_quad );
- // Bitmap Header
- $ Info_header = pack ("V3v2V *", 0x28, $ width, $ height, 1, $ bit, $ compression, $ size_data, 0, 0, $ colors_num, 0 );
- // Write a file
- If ($ filename! = '')
- {
- $ Fp = fopen ($ filename, "wb ");
- Fwrite ($ fp, $ file_header );
- Fwrite ($ fp, $ info_header );
- Fwrite ($ fp, $ rgb_quad );
- Fwrite ($ fp, $ BMP _data );
- Fclose ($ fp );
- Return true;
- }
- // Browser output
- Header ("Content-Type: image/bmp ");
- Echo $ file_header. $ info_header;
- Echo $ rgb_quad;
- Echo $ BMP _data;
- Return true;
- }
|