본문 바로가기
프로그래밍/PHP

PHP 이미지 변환 BMP to JPG

by 백룡화검 2009. 12. 9.

Convert BMP to JPG

The PHP GD library contains many wonderful tools for creating images and converting them. Sadly the ability to convert BMP images to JPG is not one of them. Here is a function that I find a little slow, but works well and has suffered several incarnations. If you have a better script, or a modification to for this one, just let us know.

번역
PHP의 GD library는 이미지 변환과 생성과 관련된 좋은 기능들을 많이 가지고 있지만,
유감스럽게도 BMP 이미지를 JPG로 변환하는 기능은 존재하지 않는다.
여기에 있는 함수는 웹 서핑중 발견한 함수로 잘 동작하지만 조금 느린 단점을 가지고 있다.
만약 더 좋은 스크립트를 알고 있거나 보유하고 있다면 알려주기 바란다.
<?php

/**
 *
 * @convert BMP to GD
 *
 * @param string $src
 *
 * @param string|bool $dest
 *
 * @return bool
 *
 */
function bmp2gd($src, $dest = false)
{
   
/*** try to open the file for reading ***/
   
if(!($src_f = fopen($src, "rb")))
    {
        return
false;
    }

/*** try to open the destination file for writing ***/
if(!($dest_f = fopen($dest, "wb")))
    {
        return
false;
    }

/*** grab the header ***/
$header = unpack("vtype/Vsize/v2reserved/Voffset", fread( $src_f, 14));

/*** grab the rest of the image ***/
$info = unpack("Vsize/Vwidth/Vheight/vplanes/vbits/Vcompression/Vimagesize/Vxres/Vyres/Vncolor/Vimportant",
fread($src_f, 40));

/*** extract the header and info into varibles ***/
extract($info);
extract($header);

/*** check for BMP signature ***/
if($type != 0x4D42)
{
    return
false;
}

/*** set the pallete ***/
$palette_size = $offset - 54;
$ncolor = $palette_size / 4;
$gd_header = "";

/*** true-color vs. palette ***/
$gd_header .= ($palette_size == 0) ? "\xFF\xFE" : "\xFF\xFF";
$gd_header .= pack("n2", $width, $height);
$gd_header .= ($palette_size == 0) ? "\x01" : "\x00";
if(
$palette_size) {
$gd_header .= pack("n", $ncolor);
}
/*** we do not allow transparency ***/
$gd_header .= "\xFF\xFF\xFF\xFF";

/*** write the destination headers ***/
fwrite($dest_f, $gd_header);

/*** if we have a valid palette ***/
if($palette_size)
{
   
/*** read the palette ***/
   
$palette = fread($src_f, $palette_size);
   
/*** begin the gd palette ***/
   
$gd_palette = "";
   
$j = 0;
   
/*** loop of the palette ***/
   
while($j < $palette_size)
    {
       
$b = $palette{$j++};
       
$g = $palette{$j++};
       
$r = $palette{$j++};
       
$a = $palette{$j++};
       
/*** assemble the gd palette ***/
       
$gd_palette .= "$r$g$b$a";
    }
   
/*** finish the palette ***/
   
$gd_palette .= str_repeat("\x00\x00\x00\x00", 256 - $ncolor);
   
/*** write the gd palette ***/
   
fwrite($dest_f, $gd_palette);
}

/*** scan line size and alignment ***/
$scan_line_size = (($bits * $width) + 7) >> 3;
$scan_line_align = ($scan_line_size & 0x03) ? 4 - ($scan_line_size & 0x03) : 0;

/*** this is where the work is done ***/
for($i = 0, $l = $height - 1; $i < $height; $i++, $l--)
{
   
/*** create scan lines starting from bottom ***/
   
fseek($src_f, $offset + (($scan_line_size + $scan_line_align) * $l));
   
$scan_line = fread($src_f, $scan_line_size);
    if(
$bits == 24)
    {
       
$gd_scan_line = "";
       
$j = 0;
        while(
$j < $scan_line_size)
        {
           
$b = $scan_line{$j++};
           
$g = $scan_line{$j++};
           
$r = $scan_line{$j++};
           
$gd_scan_line .= "\x00$r$g$b";
        }
    }
    elseif(
$bits == 8)
    {
       
$gd_scan_line = $scan_line;
    }
    elseif(
$bits == 4)
    {
       
$gd_scan_line = "";
       
$j = 0;
        while(
$j < $scan_line_size)
        {
           
$byte = ord($scan_line{$j++});
           
$p1 = chr($byte >> 4);
           
$p2 = chr($byte & 0x0F);
           
$gd_scan_line .= "$p1$p2";
        }
       
$gd_scan_line = substr($gd_scan_line, 0, $width);
    }
    elseif(
$bits == 1)
    {
       
$gd_scan_line = "";
       
$j = 0;
        while(
$j < $scan_line_size)
        {
           
$byte = ord($scan_line{$j++});
           
$p1 = chr((int) (($byte & 0x80) != 0));
           
$p2 = chr((int) (($byte & 0x40) != 0));
           
$p3 = chr((int) (($byte & 0x20) != 0));
           
$p4 = chr((int) (($byte & 0x10) != 0));
           
$p5 = chr((int) (($byte & 0x08) != 0));
           
$p6 = chr((int) (($byte & 0x04) != 0));
           
$p7 = chr((int) (($byte & 0x02) != 0));
           
$p8 = chr((int) (($byte & 0x01) != 0));
           
$gd_scan_line .= "$p1$p2$p3$p4$p5$p6$p7$p8";
        }
   
/*** put the gd scan lines together ***/
   
$gd_scan_line = substr($gd_scan_line, 0, $width);
    }
   
/*** write the gd scan lines ***/
   
fwrite($dest_f, $gd_scan_line);
}
/*** close the source file ***/
fclose($src_f);
/*** close the destination file ***/
fclose($dest_f);

return
true;
}

/**
 *
 * @ceate a BMP image
 *
 * @param string $filename
 *
 * @return bin string on success
 *
 * @return bool false on failure
 *
 */
function ImageCreateFromBmp($filename)
{
   
/*** create a temp file ***/
   
$tmp_name = tempnam("/tmp", "GD");
   
/*** convert to gd ***/
   
if(bmp2gd($filename, $tmp_name))
    {
       
/*** create new image ***/
       
$img = imagecreatefromgd($tmp_name);
       
/*** remove temp file ***/
       
unlink($tmp_name);
       
/*** return the image ***/
       
return $img;
    }
    return
false;
}

/*** example usage ***/

/*** read in the BMP image ***/
$img = ImageCreateFromBmp("test.bmp");
/*** write the new jpeg image ***/
imagejpeg($img, "test/test.jpg");

?>

<!-- display the image -->
<img src="test/test.jpg" alt="new jpg image" />

출처 : http://www.phpro.org/examples/Convert-BMP-to-JPG.html