编程语言您现在的位置是:首页 > 博客日志 > 编程语言

php图片无损压缩(tinyPNG和imagick的比较)

<a href='mailto:'>微wx笑</a>的头像微wx笑 2019-08-20编程语言 14 0关键字: tinyPNG  imagick  imagecopyresampled  

tinyPNG是有损压缩。看你们公司的需求,要是对图片的质量要求高就用前者;要是对图片大小要求高就用tinyPNG

tinyPNG是有损压缩。看你们公司的需求,要是对图片的质量要求高就用前者;要是对图片大小要求高就用tinyPNG9lS无知


9lS无知

一般无损压缩能压缩到80%~90%左右,你也可以自己直接测试一下9lS无知

Tinypng看图片的色彩丰富程度,有些甚至可以压缩到原来的20%。其实tinypng的压缩算法均衡做的很好,几乎看不出损失的色彩9lS无知

还是那句话,这个测试很快的,得自己判断得出结论9lS无知


9lS无知

imagick9lS无知

ImageMagick9lS无知


9lS无知

imagecopyresampled

php程序中改变图片大小的函数大多数人都想到用imagecopyresized(),不过经过测试比较发现,使用imagecopyresampled()改变的图片质量更高。9lS无知

imagecopyresampled的清晰度虽然比imagecopyresize的高,但是我用了下,还是有损失,没有原图清晰,有谁有更好的解决办法吗?9lS无知


9lS无知

imagecopyresampled 官方文档9lS无知


9lS无知

我发现用php的imagecopyresized把大图片缩成小图片时,图片会变得很模糊,这时候要提升清晰度不如用 imagecopyresampled 代替 imagecopyresized也许会更好。9lS无知

注:压缩有损失是必然的,看的清楚与否实际上就是是否接受这个范围的问题.比如你图像上原图有些点是2px,但是你压缩5倍,那么这些点就会消失。9lS无知

image.png9lS无知


9lS无知

php高清晰度无损图片压缩功能的实现代码

压缩通常是有按比例缩放,和指定宽度压缩的,效果很不错,一个数码相机拍的4M图片,压缩后保持了较高的清晰度和原图宽高值,只有700K。9lS无知

下面是代码(有两个文件,imgcompress.class.php 类,及compress.php)9lS无知

compress.php9lS无知

 <?php
 require_once 'imgcompress.class.php';
 $source = 'test.png';//原图文件名
 $dst_img = 'test_.png';//保存图片的文件名
 $percent = ; #原图压缩,不缩放,但体积大大降低
 $image = (new imgcompress($source,$percent))->compressImg($dst_img);

imgcompress.class.php9lS无知

 <?php
  /**
  * 图片压缩类:通过缩放来压缩。
  * 如果要保持源图比例,把参数$percent保持为即可。
  * 即使原比例压缩,也可大幅度缩小。数码相机M图片。也可以缩为KB左右。如果缩小比例,则体积会更小。
  *
  * 结果:可保存、可直接显示。
  */
 class imgcompress{
   private $src;
   private $image;
   private $imageinfo;
   private $percent = .;
   /**
    * 图片压缩
    * @param $src 源图
    * @param float $percent 压缩比例
    */
   public function __construct($src, $percent=)
   {
     $this->src = $src;
     $this->percent = $percent;
   }
   /** 高清压缩图片
    * @param string $saveName 提供图片名(可不带扩展名,用源图扩展名)用于保存。或不提供文件名直接显示
    */
   public function compressImg($saveName='')
   {
     $this->_openImage();
     if(!empty($saveName)) $this->_saveImage($saveName); //保存
     else $this->_showImage();
   }
   /**
    * 内部:打开图片
    */
   private function _openImage()
   {
     list($width, $height, $type, $attr) = getimagesize($this->src);
     $this->imageinfo = array(
       'width'=>$width,
       'height'=>$height,
       'type'=>image_type_to_extension($type,false),
       'attr'=>$attr
     );
     $fun = "imagecreatefrom".$this->imageinfo['type'];
     $this->image = $fun($this->src);
     $this->_thumpImage();
   }
   /**
    * 内部:操作图片
    */
   private function _thumpImage()
   {
     $new_width = $this->imageinfo['width'] * $this->percent;
     $new_height = $this->imageinfo['height'] * $this->percent;
     $image_thump = imagecreatetruecolor($new_width,$new_height);
     //将原图复制带图片载体上面,并且按照一定比例压缩,极大的保持了清晰度
     imagecopyresampled($image_thump,$this->image,,,,,$new_width,$new_height,$this->imageinfo['width'],$this->imageinfo['height']);
     imagedestroy($this->image);
     $this->image = $image_thump;
   }
   /**
    * 输出图片:保存图片则用saveImage()
    */
   private function _showImage()
   {
     header('Content-Type: image/'.$this->imageinfo['type']);
     $funcs = "image".$this->imageinfo['type'];
     $funcs($this->image);
   }
   /**
    * 保存图片到硬盘:
    * @param string $dstImgName 、可指定字符串不带后缀的名称,使用源图扩展名 。、直接指定目标图片名带扩展名。
    */
   private function _saveImage($dstImgName)
   {
     if(empty($dstImgName)) return false;
     $allowImgs = ['.jpg', '.jpeg', '.png', '.bmp', '.wbmp','.gif'];  //如果目标图片名有后缀就用目标图片扩展名 后缀,如果没有,则用源图的扩展名
     $dstExt = strrchr($dstImgName ,".");
     $sourseExt = strrchr($this->src ,".");
     if(!empty($dstExt)) $dstExt =strtolower($dstExt);
     if(!empty($sourseExt)) $sourseExt =strtolower($sourseExt);
     //有指定目标名扩展名
     if(!empty($dstExt) && in_array($dstExt,$allowImgs)){
       $dstName = $dstImgName;
     }elseif(!empty($sourseExt) && in_array($sourseExt,$allowImgs)){
       $dstName = $dstImgName.$sourseExt;
     }else{
       $dstName = $dstImgName.$this->imageinfo['type'];
     }
     $funcs = "image".$this->imageinfo['type'];
     $funcs($this->image,$dstName);
   }
   /**
   * 销毁图片
   */
   public function __destruct(){
     imagedestroy($this->image);
   }
 }

使用之后个人感觉 $percent 设置为0.5 左右就不错了,压缩后的图片与原图质量基本一样。9lS无知


9lS无知

Imagick压缩图像的方法:

注意:该方法并没有考虑 gif格式的图片9lS无知

function resize($image, $width, $height, $crop) {
    $imagick = new Imagick();
    $imagick->readImageBlob($image);
    $w = $imagick->getImageWidth();
    $h = $imagick->getImageHeight();
    
    if ($w > $width || $h > $height) {
        if ($crop) {
            $imagick->cropThumbnailImage($width, $height);
        } else {
            $imagick->resizeImage($width, $height, Imagick::FILTER_CATROM, 1, true);
        }
    }
    
    $imagick->setImageFormat(‘JPEG’);
    $imagick->setImageCompression(Imagick::COMPRESSION_JPEG);
    $a = $imagick->getImageCompressionQuality() * 0.75;
    
    if ($a == 0) {
        $a = 75;
    }
    
    $imagick->setImageCompressionQuality($a);
    $imagick->stripImage();
    $blob = $imagick->getImageBlob();
    $imagick->clear();
    $imagick->destroy();
    return $blob;
}

详情参考:php imagick图片无损压缩9lS无知


9lS无知

本文由 微wx笑 创作,采用 署名-非商业性使用-相同方式共享 4.0 许可协议,转载请附上原文出处链接及本声明。
原文链接:https://www.ivu4e.cn/blog/lang/2019-08-20/118.html

很赞哦! () 有话说 ()