最近因为业务需求,需要把一批jpg格式图片的dpi从72改为300,图片有三万张,一个一个用ps搞的话就太难受了,所以想写个脚本批量处理,结合网上的资料搞了半天时间终于弄出来了,脚本跑了10个小时左右把所有图片都处理好了,下面说下我是怎么做的。

  最开始的时候,在想用php自带的gd库能不能处理,在网上搜了一下,找到了一份代码:

  

function setDPI($filename){

    $file = file_get_contents($filename);

//数据块长度为9
    $len = pack("N", 9);
//数据块类型标志为pHYs
    $sign = pack("A*", "pHYs");
//X方向和Y方向的分辨率均为300DPI(1像素/英寸=39.37像素/米),单位为米(0为未知,1为米)
    $data = pack("NNC", 300 * 39.37, 300 * 39.37, 0x01);
//CRC检验码由数据块符号和数据域计算得到
    $checksum = pack("N", crc32($sign . $data));
    $phys = $len . $sign . $data . $checksum;

    $pos = strpos($file, "pHYs");
    if ($pos > 0) {
        //修改pHYs数据块
        $file = substr_replace($file, $phys, $pos - 4, 21);
    } else {
        //IHDR结束位置(PNG头固定长度为8,IHDR固定长度为25)
        $pos = 33;
        //将pHYs数据块插入到IHDR之后
        $file = substr_replace($file, $phys, $pos, 0);
    }

    file_put_contents($filename,$file);
}

  试了下这份代码,发现dpi确实变了,但是只能从72dpi变成96dpi,这就很尴尬了。最后在stackoverflow上搜了下,发现都比较推荐使用imagick这个插件。然后大部分时间都花在安装这个插件上了(淦)。下面将说明下怎么安装这个插件。

php修改JPG格式图片的dpi-风君雪科技博客

  

  首先打印出phpinfo,根据自己的php版本,参数下载对应版本的插件,插件下载地址:https://pecl.php.net/package/imagick 或者 https://windows.php.net/downloads/pecl/releases/imagick/,下载好后解压出来,就跟下面的图一样

php修改JPG格式图片的dpi-风君雪科技博客

  然后把php_imagick.dll丢到php的ext文件下

php修改JPG格式图片的dpi-风君雪科技博客

   接着这个解压出来的文件里面还有其他的dll文件,把这些dll后缀的文件(dll后缀的喔)丢到php文件夹里面。

php修改JPG格式图片的dpi-风君雪科技博客

   做完这些,重启下服务,然后打印phpinfo,可以看到扩展已经识别出来了。如果扩展没有识别出来,那检查下电脑环境变量里面的php环境变量是不是跟你装扩展的php版本不一致(我开始的时候忘记了这个事,一直没识别出来)。

php修改JPG格式图片的dpi-风君雪科技博客

  装完php的扩展后,还需要装上ImageMagick这个软件,下载地址是 http://ftp.icm.edu.pl/packages/ImageMagick/binaries/,根据phpinfo里面的提示,找到对应的版本下载,下载dll版的。

php修改JPG格式图片的dpi-风君雪科技博客

   安装完成后,输入magick –version命令,对比下phpinfo里的信息,看是否安装正确。

php修改JPG格式图片的dpi-风君雪科技博客

  

  最后就可以写代码转化图片的dpi了。我是直接写的脚本,如果说要集成进框架里面应该还需要其他的操作。最后呢,代码如下:

function handleImg($input){
    // if(!is_dir($out_dir)){
    //     mkdir($out_dir,0777,true);
    // }
    $image = new Imagick();
    $image->readImage($input);
    $image->setImageResolution(300,300);
    $image->resampleImage(300,300,imagick::FILTER_UNDEFINED,0);
    $image->writeImage($input);
}

  input是要处理图片的文件路径,因为因为硬盘空间不够了,我直接把原图片给覆盖了。最后处理出来的效果如下:

php修改JPG格式图片的dpi-风君雪科技博客