php質量壓縮圖檔 - stu80143/gitNote GitHub Wiki

php質量壓縮圖檔

常見格式

副檔名為

  1. jpg/jpeg
  2. gif
  3. png
  4. bmp

基本上php對於前三種都有內建的函數可以直接使用,能進行品質壓縮的 只有jpg/jpeg & png

並且bmp並沒有函數,當然bmp的函數到了php 7 >= 7.2.0 就有了, 不需要用下面這麼麻煩的方法,但是如果是之前的php版本, 就需要特別做處理,幸好已經有寫好的function可以使用了

<?php
function myImageCreateFromBmp($pic){
    if (! $f1 = fopen($pic, "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'] < 16777216 && $BMP['colors'] != 65536) {
        $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 < $BMP['width']) {
            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) << 3) + 7;
                $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;

}
?>

注意一下,這邊回傳的是image的resource,還要再做處理才能直接輸出

<?php
//$pic是圖片的路徑
$res = myImageCreateFromBmp($pic);
//將bmp檔案轉成jpeg並且品質為50,數字越高品質越好 1~100
imagejpeg($res, $savePath, 50);
?>

其他三種檔案類型

大致上都是長下面這樣,像是造樣造句的感覺

<?php 
$res = imagecreatefromgif($imgPath);
imagejpeg($res, $savePath , 50);
?>