Heim  >  Artikel  >  Backend-Entwicklung  >  仿GD读取bmp函数

仿GD读取bmp函数

WBOY
WBOYOriginal
2016-07-25 08:49:471227Durchsuche
最近在工作中需要把bmp图片转成jpg图片,但无奈的是网上能找到的bmp转gd的类或函数或多或少都有些问题。其中绝大多数在处理16位bmp图片时要么全黑全粉,要么干脆转换不出,其余有些根本不支持32位的bmp图片。
最后我终于在php的官网上找到了解决方法。原来网上流传最广的一个仿GD的imagecreatefrombmp函数是一个有问题的版本,无法正确处理16位bmp图片,但好在官网上有人给出了修正方法,修正好的代码如下:
  1. /**
  2. * BMP 创建函数
  3. * @author simon
  4. * @modified by 天心流水
  5. * @param string $filename path of bmp file
  6. * @example who use,who knows
  7. * @return resource of GD
  8. */
  9. function imagecreatefrombmp( $filename ) {
  10. if ( !$f1 = fopen( $filename, "rb" ) )
  11. return FALSE;
  12. $FILE = unpack( "vfile_type/Vfile_size/Vreserved/Vbitmap_offset", fread( $f1, 14 ) );
  13. if ( $FILE['file_type'] != 19778 )
  14. return FALSE;
  15. $BMP = unpack( 'Vheader_size/Vwidth/Vheight/vplanes/vbits_per_pixel' . '/Vcompression/Vsize_bitmap/Vhoriz_resolution' . '/Vvert_resolution/Vcolors_used/Vcolors_important', fread( $f1, 40 ) );
  16. $BMP['colors'] = pow( 2, $BMP['bits_per_pixel'] );
  17. if ( $BMP['size_bitmap'] == 0 )
  18. $BMP['size_bitmap'] = $FILE['file_size'] - $FILE['bitmap_offset'];
  19. $BMP['bytes_per_pixel'] = $BMP['bits_per_pixel'] / 8;
  20. $BMP['bytes_per_pixel2'] = ceil( $BMP['bytes_per_pixel'] );
  21. $BMP['decal'] = ($BMP['width'] * $BMP['bytes_per_pixel'] / 4);
  22. $BMP['decal'] -= floor( $BMP['width'] * $BMP['bytes_per_pixel'] / 4 );
  23. $BMP['decal'] = 4 - (4 * $BMP['decal']);
  24. if ( $BMP['decal'] == 4 )
  25. $BMP['decal'] = 0;
  26. $PALETTE = array();
  27. if ($BMP['colors'] {
  28. $PALETTE = unpack('V'.$BMP['colors'], fread($f1,$BMP['colors']*4));
  29. }
  30. $IMG = fread( $f1, $BMP['size_bitmap'] );
  31. $VIDE = chr( 0 );
  32. $res = imagecreatetruecolor( $BMP['width'], $BMP['height'] );
  33. $P = 0;
  34. $Y = $BMP['height'] - 1;
  35. while( $Y >= 0 ){
  36. $X = 0;
  37. while( $X if ( $BMP['bits_per_pixel'] == 32 ){
  38. $COLOR = unpack( "V", substr( $IMG, $P, 3 ) );
  39. $B = ord(substr($IMG, $P,1));
  40. $G = ord(substr($IMG, $P+1,1));
  41. $R = ord(substr($IMG, $P+2,1));
  42. $color = imagecolorexact( $res, $R, $G, $B );
  43. if ( $color == -1 )
  44. $color = imagecolorallocate( $res, $R, $G, $B );
  45. $COLOR[0] = $R*256*256+$G*256+$B;
  46. $COLOR[1] = $color;
  47. } elseif ( $BMP['bits_per_pixel'] == 24 ) {
  48. $COLOR = unpack( "V", substr( $IMG, $P, 3 ) . $VIDE );
  49. } elseif ( $BMP['bits_per_pixel'] == 16 ){
  50. $COLOR = unpack("v",substr($IMG,$P,2));
  51. $blue = (($COLOR[1] & 0x001f) $green = (($COLOR[1] & 0x03e0) >> 2) + 7;
  52. $red = (($COLOR[1] & 0xfc00) >> 7) + 7;
  53. $COLOR[1] = $red * 65536 + $green * 256 + $blue;
  54. } elseif ( $BMP['bits_per_pixel'] == 8 ){
  55. $COLOR = unpack( "n", $VIDE . substr( $IMG, $P, 1 ) );
  56. $COLOR[1] = $PALETTE[$COLOR[1] + 1];
  57. } elseif ( $BMP['bits_per_pixel'] == 4 ){
  58. $COLOR = unpack( "n", $VIDE . substr( $IMG, floor( $P ), 1 ) );
  59. if ( ($P * 2) % 2 == 0 )
  60. $COLOR[1] = ($COLOR[1] >> 4);
  61. else
  62. $COLOR[1] = ($COLOR[1] & 0x0F);
  63. $COLOR[1] = $PALETTE[$COLOR[1] + 1];
  64. } elseif ( $BMP['bits_per_pixel'] == 1 ){
  65. $COLOR = unpack( "n", $VIDE . substr( $IMG, floor( $P ), 1 ) );
  66. if ( ($P * 8) % 8 == 0 )
  67. $COLOR[1] = $COLOR[1] >> 7;
  68. elseif ( ($P * 8) % 8 == 1 )
  69. $COLOR[1] = ($COLOR[1] & 0x40) >> 6;
  70. elseif ( ($P * 8) % 8 == 2 )
  71. $COLOR[1] = ($COLOR[1] & 0x20) >> 5;
  72. elseif ( ($P * 8) % 8 == 3 )
  73. $COLOR[1] = ($COLOR[1] & 0x10) >> 4;
  74. elseif ( ($P * 8) % 8 == 4 )
  75. $COLOR[1] = ($COLOR[1] & 0x8) >> 3;
  76. elseif ( ($P * 8) % 8 == 5 )
  77. $COLOR[1] = ($COLOR[1] & 0x4) >> 2;
  78. elseif ( ($P * 8) % 8 == 6 )
  79. $COLOR[1] = ($COLOR[1] & 0x2) >> 1;
  80. elseif ( ($P * 8) % 8 == 7 )
  81. $COLOR[1] = ($COLOR[1] & 0x1);
  82. $COLOR[1] = $PALETTE[$COLOR[1] + 1];
  83. }else
  84. return FALSE;
  85. imagesetpixel( $res, $X, $Y, $COLOR[1] );
  86. $X++;
  87. $P += $BMP['bytes_per_pixel'];
  88. }
  89. $Y--;
  90. $P += $BMP['decal'];
  91. }
  92. fclose( $f1 );
  93. return $res;
  94. }
复制代码


Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Vorheriger Artikel:网页抓图 Nächster Artikel:为什么要进行网站数据备份