php質量壓縮圖檔 - stu80143/gitNote GitHub Wiki
php質量壓縮圖檔
常見格式
副檔名為
- jpg/jpeg
- gif
- png
- 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);
?>