PHP 对图像进行缩放


有时对图像进行缩放,有必要记录一下。


正文

这里要用到Gd库的函数,需要安装好php的gd依赖包。

GD 和图像处理 函数:

gd_info — 取得当前安装的 GD 库的信息
getimagesize — 取得图像大小
getimagesizefromstring — 从字符串中获取图像尺寸信息
image_type_to_extension — 取得图像类型的文件后缀
image_type_to_mime_type — 取得 getimagesize,exif_read_data,exif_thumbnail,exif_imagetype 所返回的图像类型的 MIME 类型
image2wbmp — 以 WBMP 格式将图像输出到浏览器或文件
imageaffine — 返回经过仿射变换后的图像,剪切区域可选
imageaffinematrixconcat — Concatenate two affine transformation matrices
imageaffinematrixget — Get an affine transformation matrix
imagealphablending — 设定图像的混色模式
imageantialias — 是否使用抗锯齿(antialias)功能
imagearc — 画椭圆弧
imagebmp — Output a BMP image to browser or file
imagechar — 水平地画一个字符
imagecharup — 垂直地画一个字符
imagecolorallocate — 为一幅图像分配颜色
imagecolorallocatealpha — 为一幅图像分配颜色 + alpha
imagecolorat — 取得某像素的颜色索引值
imagecolorclosest — 取得与指定的颜色最接近的颜色的索引值
imagecolorclosestalpha — 取得与指定的颜色加透明度最接近的颜色
imagecolorclosesthwb — 取得与给定颜色最接近的色度的黑白色的索引
imagecolordeallocate — 取消图像颜色的分配
imagecolorexact — 取得指定颜色的索引值
imagecolorexactalpha — 取得指定的颜色加透明度的索引值
imagecolormatch — 使一个图像中调色板版本的颜色与真彩色版本更能匹配
imagecolorresolve — 取得指定颜色的索引值或有可能得到的最接近的替代值
imagecolorresolvealpha — 取得指定颜色 + alpha 的索引值或有可能得到的最接近的替代值
imagecolorset — 给指定调色板索引设定颜色
imagecolorsforindex — 取得某索引的颜色
imagecolorstotal — 取得一幅图像的调色板中颜色的数目
imagecolortransparent — 将某个颜色定义为透明色
imageconvolution — 用系数 div 和 offset 申请一个 3x3 的卷积矩阵
imagecopy — 拷贝图像的一部分
imagecopymerge — 拷贝并合并图像的一部分
imagecopymergegray — 用灰度拷贝并合并图像的一部分
imagecopyresampled — 重采样拷贝部分图像并调整大小
imagecopyresized — 拷贝部分图像并调整大小
imagecreate — 新建一个基于调色板的图像
imagecreatefrombmp — 由文件或 URL 创建一个新图象。
imagecreatefromgd2 — 从 GD2 文件或 URL 新建一图像
imagecreatefromgd2part — 从给定的 GD2 文件或 URL 中的部分新建一图像
imagecreatefromgd — 从 GD 文件或 URL 新建一图像
imagecreatefromgif — 由文件或 URL 创建一个新图象。
imagecreatefromjpeg — 由文件或 URL 创建一个新图象。
imagecreatefrompng — 由文件或 URL 创建一个新图象。
imagecreatefromstring — 从字符串中的图像流新建一图像
imagecreatefromwbmp — 由文件或 URL 创建一个新图象。
imagecreatefromwebp — 由文件或 URL 创建一个新图象。
imagecreatefromxbm — 由文件或 URL 创建一个新图象。
imagecreatefromxpm — 由文件或 URL 创建一个新图象。
imagecreatetruecolor — 新建一个真彩色图像
imagecrop — Crop an image to the given rectangle
imagecropauto — Crop an image automatically using one of the available modes
imagedashedline — 画一虚线
imagedestroy — 销毁一图像
imageellipse — 画一个椭圆
imagefill — 区域填充
imagefilledarc — 画一椭圆弧且填充
imagefilledellipse — 画一椭圆并填充
imagefilledpolygon — 画一多边形并填充
imagefilledrectangle — 画一矩形并填充
imagefilltoborder — 区域填充到指定颜色的边界为止
imagefilter — 对图像使用过滤器
imageflip — Flips an image using a given mode
imagefontheight — 取得字体高度
imagefontwidth — 取得字体宽度
imageftbbox — 给出一个使用 FreeType 2 字体的文本框
imagefttext — 使用 FreeType 2 字体将文本写入图像
imagegammacorrect — 对 GD 图像应用 gamma 修正
imagegd2 — 将 GD2 图像输出到浏览器或文件
imagegd — 将 GD 图像输出到浏览器或文件
imagegetclip — Get the clipping rectangle
imagegetinterpolation — Get the interpolation method
imagegif — 输出图象到浏览器或文件。
imagegrabscreen — Captures the whole screen
imagegrabwindow — Captures a window
imageinterlace — 激活或禁止隔行扫描
imageistruecolor — 检查图像是否为真彩色图像
imagejpeg — 输出图象到浏览器或文件。
imagelayereffect — 设定 alpha 混色标志以使用绑定的 libgd 分层效果
imageline — 画一条线段
imageloadfont — 载入一新字体
imageopenpolygon — Draws an open polygon
imagepalettecopy — 将调色板从一幅图像拷贝到另一幅
imagepalettetotruecolor — Converts a palette based image to true color
imagepng — 以 PNG 格式将图像输出到浏览器或文件
imagepolygon — 画一个多边形
imagerectangle — 画一个矩形
imageresolution — Get or set the resolution of the image
imagerotate — 用给定角度旋转图像
imagesavealpha — 设置标记以在保存 PNG 图像时保存完整的 alpha 通道信息(与单一透明色相反)
imagescale — Scale an image using the given new width and height
imagesetbrush — 设定画线用的画笔图像
imagesetclip — Set the clipping rectangle
imagesetinterpolation — Set the interpolation method
imagesetpixel — 画一个单一像素
imagesetstyle — 设定画线的风格
imagesetthickness — 设定画线的宽度
imagesettile — 设定用于填充的贴图
imagestring — 水平地画一行字符串
imagestringup — 垂直地画一行字符串
imagesx — 取得图像宽度
imagesy — 取得图像高度
imagetruecolortopalette — 将真彩色图像转换为调色板图像
imagettfbbox — 取得使用 TrueType 字体的文本的范围
imagettftext — 用 TrueType 字体向图像写入文本
imagetypes — 返回当前 PHP 版本所支持的图像类型
imagewbmp — 以 WBMP 格式将图像输出到浏览器或文件
imagewebp — 将 WebP 格式的图像输出到浏览器或文件
imagexbm — 将 XBM 图像输出到浏览器或文件
iptcembed — 将二进制 IPTC 数据嵌入到一幅 JPEG 图像中
iptcparse — 将二进制 IPTC 块解析为单个标记
jpeg2wbmp — 将 JPEG 图像文件转换为 WBMP 图像文件
png2wbmp — 将 PNG 图像文件转换为 WBMP 图像文件

实例1

看一个图片上传并缩放的例子:

public function actionAvatarEdit()
{
     if ( $_FILES['imageFile'] ) {
          $upload_dir = Yii::$app->basePath . '/web/uploads/resource/';
          $file_extension = substr($_FILES['imageFile']['name'], strrpos($_FILES['imageFile']['name'], '.') + 1); // 后缀名
          $upload_file = date("YmdHis") . rand(10000,99999) . '.' . $file_extension;
          if ( !move_uploaded_file( $_FILES['imageFile']['tmp_name'], $upload_dir.$upload_file ) ) {
               return 0;
          }

          $files_upload = '/uploads/resource/';
         $this->thumb($upload_dir.$upload_file, $file_extension, 100, 100);

          $data = Admin::findOne( Yii::$app->user->id );
          $data->avatar = $files_upload . $upload_file;

         if ( $data->save() ) {
              return $files_upload . $upload_file;
          }
     }

     return 0;
}
protected function thumb( $filename, $file_extension, $width = 0, $height = 0 )
{
     // 获取原图像$filename的宽度$width_orig和高度$height_orig
     list($width_orig, $height_orig) = getimagesize($filename);
     // 根据参数$width和$height值,换算出等比例缩放的高度和宽度
     if ( $width && ($width_orig < $height_orig) ) {
          $width = ($height / $height_orig) * $width_orig;
     } else {
          $height = ($width / $width_orig) * $height_orig;
     }

     // 将原图缩放到这个新创建的图片资源中
     $image_p = imagecreatetruecolor($width, $height);
     // 获取原图的图像资源
     if ( strtolower($file_extension) == 'png' ) {
          $image = imagecreatefrompng($filename);
     } else if(strtolower($file_extension) == 'jpg' || strtolower($file_extension) == 'jpeg' ) {
          $image = imagecreatefromjpeg($filename);
     }

     // 使用imagecopyresampled()函数进行缩放设置
     imagecopyresampled( $image_p, $image, 0, 0, 0, 0, $width, $height, $width_orig, $height_orig );

     // 将缩放后的图片$image_p保存,100(质量最佳,文件最大)
     if ( strtolower($file_extension) == 'png' ) {
          imagepng($image_p, $filename);
     } elseif ( strtolower($file_extension) == 'jpg' || strtolower($file_extension ) == 'jpeg' ) {
          imagejpeg($image_p, $filename);
     }

     imagedestroy($image_p);
     imagedestroy($image);
} 

实例2

看一个TP5中的例子:

<?php

namespace app\admin\controller;

use app\common\exception\UploadException;
use app\common\library\Upload;
use app\common\controller\Backend;

/**
 * Class Candy
 * @package app\admin\controller\yq2b
 */
class Candy extends Backend
{
    /**
     * 上传文件
     */
    public function upload()
    {
        $attachment = null;

        $file = $this->request->file('file');
        try {
            $info = $file->getInfo();
            $tmp_name = $info["tmp_name"];

            list($width, $height, $type) = getimagesize($tmp_name);
            if ($width > 750 || $height > 620) {
                $this->compress($tmp_name, $tmp_name, 750, 620, 100, $info["name"]);

                $image_info = getimagesize($tmp_name);
                $info["type"] = $image_info["mime"];
                $info["size"] = filesize($tmp_name);

                $file = $file->setUploadInfo($info);
            }

            $upload = new Upload($file);
            $attachment = $upload->upload();
        } catch (UploadException $e) {
            $this->error($e->getMessage());
        }

        $this->success(__('Uploaded successful'), '', ['url' => $attachment->url, 'fullurl' => cdnurl($attachment->url, true)]);
    }

    /**
     * @param $image_src
     * @param $image_dist
     * @param int $dist_width
     * @param int $dist_height
     * @param int $quality
     * @param string $filename
     * @return bool
     * @throws UploadException
     */
    protected function compress($image_src, $image_dist, $dist_width = 320, $dist_height = 240, $quality = 70, $filename = "")
    {
        $imagecreate_list = [
            1 => function ($path) {
                return imagecreatefromgif($path);
            },
            2 => function ($path) {
                return imagecreatefromjpeg($path);
            },
            3 => function ($path) {
                return imagecreatefrompng($path);
            },
            // 4   =>  function($path) {return imagecreatefromswf($path);},
            // 5   =>  function($path) {return imagecreatefrompsd($path);},
            6 => function ($path) {
                return imagecreatefrombmp($path);
            },
            // 7   =>  function($path) {return imagecreatefromtiff($path);},
            // 8   =>  function($path) {return imagecreatefromtiff($path);},
            9 => function ($path) {
                return imagecreatefromjpeg($path);
            },
            10 => function ($path) {
                return imagecreatefromjpeg($path);
            },
            11 => function ($path) {
                return imagecreatefromjpeg($path);
            },
            12 => function ($path) {
                return imagecreatefromjpeg($path);
            },
            // 13   =>  function($path) {return imagecreatefromswc($path);},
            // 14   =>  function($path) {return imagecreatefromiff($path);},
            15 => function ($path) {
                return imagecreatefromwbmp($path);
            },
            16 => function ($path) {
                return imagecreatefromxbm($path);
            },
            // 17   =>  function($path) {return imagecreatefromico($path);},
            18 => function ($path) {
                return imagecreatefromwebp($path);
            },
        ];

        // 后缀名
        $file_extension = null;
        if (!empty($filename) && strrpos($filename, '.') !== false) {
            $file_extension = substr($filename, strrpos($filename, '.') + 1);
        }

        try {
            list($src_width, $src_height, $stype) = getimagesize($image_src);
            if ($dist_width && ($src_width < $src_height)) {
                $dist_width = ($dist_height / $src_height) * $src_width;
            } else {
                $dist_height = ($dist_width / $src_width) * $src_height;
            }

            $image_resource = imagecreatetruecolor($dist_width, $dist_height);

            $src_image = $imagecreate_list[$stype]($image_src);

            imagecopyresampled($image_resource, $src_image, 0, 0, 0, 0, $dist_width, $dist_height, $src_width, $src_height);

            if (strtolower($file_extension) == 'jpg' || strtolower($file_extension ) == 'jpeg') {
                imagejpeg($image_resource, $image_dist, $quality);
            } else {
                imagepng($image_resource, $image_dist, intval(($quality - 10) / 10));
            }

            imagedestroy($image_resource);
            imagedestroy($src_image);

            return true;
        } catch (\Exception $e) {
            throw new UploadException($e->getMessage());

            return false;
        }
    }
}

函数原型

/**
 * Output a PNG image to either the browser or a file
 * @link https://php.net/manual/en/function.imagepng.php
 * @param resource $image
 * @param string $filename [optional] <p>
 * The path to save the file to. If not set or &null;, the raw image stream
 * will be outputted directly.
 * </p>
 * <p>
 * &null; is invalid if the quality and
 * filters arguments are not used.
 * </p>
 * @param int $quality [optional] <p>
 * Compression level: from 0 (no compression) to 9.
 * </p>
 * @param int $filters [optional] <p>
 * Allows reducing the PNG file size. It is a bitmask field which may be
 * set to any combination of the PNG_FILTER_XXX
 * constants. PNG_NO_FILTER or
 * PNG_ALL_FILTERS may also be used to respectively
 * disable or activate all filters.
 * </p>
 * @return bool true on success or false on failure.
 */
function imagepng ($image, $filename = null, $quality = null, $filters = null) {}

/**
 * Get the size of an image
 * @link http://php.net/manual/en/function.getimagesize.php
 * @param string $filename <p>
 * This parameter specifies the file you wish to retrieve information
 * about. It can reference a local file or (configuration permitting) a
 * remote file using one of the supported streams. 
 * </p>
 * @param array $imageinfo [optional] <p>
 * This optional parameter allows you to extract some extended
 * information from the image file. Currently, this will return the
 * different JPG APP markers as an associative array.
 * Some programs use these APP markers to embed text information in 
 * images. A very common one is to embed 
 * IPTC information in the APP13 marker.
 * You can use the iptcparse function to parse the
 * binary APP13 marker into something readable.
 * </p>
 * @return array|bool an array with 7 elements.
 * </p>
 * <p>
 * Index 0 and 1 contains respectively the width and the height of the image.
 * </p>
 * <p>
 * Some formats may contain no image or may contain multiple images. In these
 * cases, getimagesize might not be able to properly
 * determine the image size. getimagesize will return
 * zero for width and height in these cases.
 * </p>
 * <p>
 * Index 2 is one of the IMAGETYPE_XXX constants indicating 
 * the type of the image.
 * </p>
 * <p>
 * Index 3 is a text string with the correct 
 * height="yyy" width="xxx" string that can be used
 * directly in an IMG tag.
 * </p>
 * <p>
 * mime is the correspondant MIME type of the image.
 * This information can be used to deliver images with correct the HTTP 
 * Content-type header:
 * getimagesize and MIME types
 * ]]>
 * </p>
 * <p>
 * channels will be 3 for RGB pictures and 4 for CMYK
 * pictures.
 * </p>
 * <p>
 * bits is the number of bits for each color.
 * </p>
 * <p>
 * For some image types, the presence of channels and
 * bits values can be a bit
 * confusing. As an example, GIF always uses 3 channels
 * per pixel, but the number of bits per pixel cannot be calculated for an
 * animated GIF with a global color table.
 * </p>
 * <p>
 * On failure, false is returned.
 * @since 4.0
 * @since 5.0
 */
function getimagesize ($filename, array &$imageinfo = null) {}

源码

public function actionAvatarEdit()
{
    if ($_FILES['imageFile']) {

        $upload_dir = Yii::$app->basePath . '/web/uploads/resource/';
        $file_extension = substr($_FILES['imageFile']['name'], strrpos($_FILES['imageFile']['name'], '.') + 1);  // 后缀名
        $upload_file = date("YmdHis") . rand(10000, 99999) . '.' . $file_extension;
        if (!move_uploaded_file($_FILES['imageFile']['tmp_name'], $upload_dir . $upload_file)) {

            return 0;
        }


        $files_upload = '/uploads/resource/';
        $this->thumb($upload_dir . $upload_file, $file_extension, 100, 100);

        $data = Admin::findOne(Yii::$app->user->id);
        $data->avatar = $files_upload . $upload_file;

        if ($data->save()) {

            return $files_upload . $upload_file;
        }

    }


    return 0;
}

protected function thumb($filename, $file_extension, $width = 0, $height = 0)
{
    // 获取原图像$filename的宽度$width_orig和高度$height_orig
    list($width_orig, $height_orig) = getimagesize($filename);
    // 根据参数$width和$height值,换算出等比例缩放的高度和宽度
    if ($width && ($width_orig < $height_orig)) {

        $width = ($height / $height_orig) * $width_orig;
    } else {

        $height = ($width / $width_orig) * $height_orig;
    }

    // 将原图缩放到这个新创建的图片资源中
    $image_p = imagecreatetruecolor($width, $height);
    // 获取原图的图像资源
    if (strtolower($file_extension) == 'png') {

        $image = imagecreatefrompng($filename);
    } else if (strtolower($file_extension) == 'jpg' || strtolower($file_extension) == 'jpeg') {

        $image = imagecreatefromjpeg($filename);
    }
    
    // 使用imagecopyresampled()函数进行缩放设置
    imagecopyresampled($image_p, $image, 0, 0, 0, 0, $width, $height, $width_orig, $height_orig);

    // 将缩放后的图片$image_p保存,100(质量最佳,文件最大)
    if (strtolower($file_extension) == 'png') {

        imagepng($image_p, $filename);
    } elseif (strtolower($file_extension) == 'jpg' || strtolower($file_extension) == 'jpeg') {

        imagejpeg($image_p, $filename);
    }
    
    imagedestroy($image_p);
    imagedestroy($image);
}

public function actionAvatarEdit()
{
     if ( $_FILES['imageFile'] ) {
          $upload_dir = Yii::$app->basePath . '/web/uploads/resource/';
          $file_extension = substr($_FILES['imageFile']['name'], strrpos($_FILES['imageFile']['name'], '.') + 1); // 后缀名
          $upload_file = date("YmdHis") . rand(10000,99999) . '.' . $file_extension;
          if ( !move_uploaded_file( $_FILES['imageFile']['tmp_name'], $upload_dir.$upload_file ) ) {
               return 0;
          }

          $files_upload = '/uploads/resource/';
         $this->thumb($upload_dir.$upload_file, $file_extension, 100, 100);

          $data = Admin::findOne( Yii::$app->user->id );
          $data->avatar = $files_upload . $upload_file;

         if ( $data->save() ) {
              return $files_upload . $upload_file;
          }
     }

     return 0;
}


protected function thumb( $filename, $file_extension, $width = 0, $height = 0 )
{
     // 获取原图像$filename的宽度$width_orig和高度$height_orig
     list($width_orig, $height_orig) = getimagesize($filename);
     // 根据参数$width$height值,换算出等比例缩放的高度和宽度
     if ( $width && ($width_orig < $height_orig) ) {
          $width = ($height / $height_orig) * $width_orig;
     } else {
          $height = ($width / $width_orig) * $height_orig;
     }

     // 将原图缩放到这个新创建的图片资源中
     $image_p = imagecreatetruecolor($width, $height);
     // 获取原图的图像资源
     if ( strtolower($file_extension) == 'png' ) {
          $image = imagecreatefrompng($filename);
     } else if(strtolower($file_extension) == 'jpg' || strtolower($file_extension) == 'jpeg' ) {
          $image = imagecreatefromjpeg($filename);
     }

     // 使用imagecopyresampled()函数进行缩放设置
     imagecopyresampled( $image_p, $image, 0, 0, 0, 0, $width, $height, $width_orig, $height_orig );

     // 将缩放后的图片$image_p保存,100(质量最佳,文件最大)
     if ( strtolower($file_extension) == 'png' ) {
          imagepng($image_p, $filename);
     } elseif ( strtolower($file_extension) == 'jpg' || strtolower($file_extension ) == 'jpeg' ) {
          imagejpeg($image_p, $filename);
     }

     imagedestroy($image_p);
     imagedestroy($image);
}






参考资料

PHP 图像处理 https://www.runoob.com/php/php-image-gd.html

图像处理和 GD https://www.php.net/manual/zh/book.image.php


返回