您好,欢迎访问一九零五行业门户网

仿GD读取bmp函数

最近在工作中需要把bmp图片转成jpg图片,但无奈的是网上能找到的bmp转gd的类或函数或多或少都有些问题。其中绝大多数在处理16位bmp图片时要么全黑全粉,要么干脆转换不出,其余有些根本不支持32位的bmp图片。
最后我终于在php的官网上找到了解决方法。原来网上流传最广的一个仿gd的imagecreatefrombmp函数是一个有问题的版本,无法正确处理16位bmp图片,但好在官网上有人给出了修正方法,修正好的代码如下: /** * bmp 创建函数 * @author simon * @modified by 天心流水 * @param string $filename path of bmp file * @example who use,who knows * @return resource of gd */ function imagecreatefrombmp( $filename ) { if ( !$f1 = fopen( $filename, rb ) ) return false; $file = unpack( vfile_type/vfile_size/vreserved/vbitmap_offset, fread( $f1, 14 ) ); if ( $file['file_type'] != 19778 ) return false; $bmp = unpack( 'vheader_size/vwidth/vheight/vplanes/vbits_per_pixel' . '/vcompression/vsize_bitmap/vhoriz_resolution' . '/vvert_resolution/vcolors_used/vcolors_important', fread( $f1, 40 ) ); $bmp['colors'] = pow( 2, $bmp['bits_per_pixel'] ); if ( $bmp['size_bitmap'] == 0 ) $bmp['size_bitmap'] = $file['file_size'] - $file['bitmap_offset']; $bmp['bytes_per_pixel'] = $bmp['bits_per_pixel'] / 8; $bmp['bytes_per_pixel2'] = ceil( $bmp['bytes_per_pixel'] ); $bmp['decal'] = ($bmp['width'] * $bmp['bytes_per_pixel'] / 4); $bmp['decal'] -= floor( $bmp['width'] * $bmp['bytes_per_pixel'] / 4 ); $bmp['decal'] = 4 - (4 * $bmp['decal']); if ( $bmp['decal'] == 4 ) $bmp['decal'] = 0; $palette = array(); if ($bmp['colors'] { $palette = unpack('v'.$bmp['colors'], fread($f1,$bmp['colors']*4)); } $img = fread( $f1, $bmp['size_bitmap'] ); $vide = chr( 0 ); $res = imagecreatetruecolor( $bmp['width'], $bmp['height'] ); $p = 0; $y = $bmp['height'] - 1; while( $y >= 0 ){ $x = 0; while( $x if ( $bmp['bits_per_pixel'] == 32 ){ $color = unpack( v, substr( $img, $p, 3 ) ); $b = ord(substr($img, $p,1)); $g = ord(substr($img, $p+1,1)); $r = ord(substr($img, $p+2,1)); $color = imagecolorexact( $res, $r, $g, $b ); if ( $color == -1 ) $color = imagecolorallocate( $res, $r, $g, $b ); $color[0] = $r*256*256+$g*256+$b; $color[1] = $color; } elseif ( $bmp['bits_per_pixel'] == 24 ) { $color = unpack( v, substr( $img, $p, 3 ) . $vide ); } elseif ( $bmp['bits_per_pixel'] == 16 ){ $color = unpack(v,substr($img,$p,2)); $blue = (($color[1] & 0x001f) $green = (($color[1] & 0x03e0) >> 2) + 7; $red = (($color[1] & 0xfc00) >> 7) + 7; $color[1] = $red * 65536 + $green * 256 + $blue; } elseif ( $bmp['bits_per_pixel'] == 8 ){ $color = unpack( n, $vide . substr( $img, $p, 1 ) ); $color[1] = $palette[$color[1] + 1]; } elseif ( $bmp['bits_per_pixel'] == 4 ){ $color = unpack( n, $vide . substr( $img, floor( $p ), 1 ) ); if ( ($p * 2) % 2 == 0 ) $color[1] = ($color[1] >> 4); else $color[1] = ($color[1] & 0x0f); $color[1] = $palette[$color[1] + 1]; } elseif ( $bmp['bits_per_pixel'] == 1 ){ $color = unpack( n, $vide . substr( $img, floor( $p ), 1 ) ); if ( ($p * 8) % 8 == 0 ) $color[1] = $color[1] >> 7; elseif ( ($p * 8) % 8 == 1 ) $color[1] = ($color[1] & 0x40) >> 6; elseif ( ($p * 8) % 8 == 2 ) $color[1] = ($color[1] & 0x20) >> 5; elseif ( ($p * 8) % 8 == 3 ) $color[1] = ($color[1] & 0x10) >> 4; elseif ( ($p * 8) % 8 == 4 ) $color[1] = ($color[1] & 0x8) >> 3; elseif ( ($p * 8) % 8 == 5 ) $color[1] = ($color[1] & 0x4) >> 2; elseif ( ($p * 8) % 8 == 6 ) $color[1] = ($color[1] & 0x2) >> 1; elseif ( ($p * 8) % 8 == 7 ) $color[1] = ($color[1] & 0x1); $color[1] = $palette[$color[1] + 1]; }else return false; imagesetpixel( $res, $x, $y, $color[1] ); $x++; $p += $bmp['bytes_per_pixel']; } $y--; $p += $bmp['decal']; } fclose( $f1 ); return $res;}
复制代码
其它类似信息

推荐信息