【PHP】PHP图像裁剪缩略裁切类源代码及使用方法

原因

最近在做网页拖拽验证码的开源项目,需要在服务端生成图片对应的可移动的色块,但是网上的资源都是做缩略图,对整个图片进行缩放的,所以自己动手,完成了对图片进行裁剪小块的工具

CODE


<?php

namespace  App\Libs;

/**
 * 2016-01-07 15:54:58
 * Lixiaoyu
 *
 * mode 1 : 强制裁剪,生成图片严格按照需要,不足放大,超过裁剪,图片始终铺满
 * mode 2 : 和1类似,但不足的时候 不放大 会产生补白,可以用png消除。
 * mode 3 : 只缩放,不裁剪,保留全部图片信息,会产生补白,
 * mode 4 : 只缩放,不裁剪,保留全部图片信息,生成图片大小为最终缩放后的图片有效信息的实际大小,不产生补白
 * 默认补白为白色,如果要使补白成透明像素,请使用SaveAlpha()方法代替SaveImage()方法

 */
class ImageCrop{

    var $sImage;
    var $dImage;
    var $src_file;
    var $dst_file;
    var $src_width;
    var $src_height;
    var $src_ext;
    var $src_type;

    function __construct($src_file,$dst_file=''){
        $this->src_file=$src_file;
        $this->dst_file=$dst_file;
        $this->LoadImage();
    }

    function SetSrcFile($src_file){
        $this->src_file=$src_file;
    }

    function SetDstFile($dst_file){
        $this->dst_file=$dst_file;
    }

    function LoadImage(){
        list($this->src_width, $this->src_height, $this->src_type) = getimagesize($this->src_file);
        switch($this->src_type) {
            case IMAGETYPE_JPEG :
                $this->sImage=imagecreatefromjpeg($this->src_file);
                $this->ext='jpg';
                break;
            case IMAGETYPE_PNG :
                $this->sImage=imagecreatefrompng($this->src_file);
                $this->ext='png';
                break;
            case IMAGETYPE_GIF :
                $this->sImage=imagecreatefromgif($this->src_file);
                $this->ext='gif';
                break;
            default:
                exit();
        }
    }

    function SaveImage($fileName=''){
        $this->dst_file=$fileName ? $fileName : $this->dst_file;
        switch($this->src_type) {
            case IMAGETYPE_JPEG :
                imagejpeg($this->dImage,$this->dst_file,100);
                break;
            case IMAGETYPE_PNG :
                imagepng($this->dImage,$this->dst_file);
                break;
            case IMAGETYPE_GIF :
                imagegif($this->dImage,$this->dst_file);
                break;
            default:
                break;
        }
    }

    function OutImage(){
        switch($this->src_type) {
            case IMAGETYPE_JPEG :
                header('Content-type: image/jpeg');
                imagejpeg($this->dImage);
                break;
            case IMAGETYPE_PNG :
                header('Content-type: image/png');
                imagepng($this->dImage);
                break;
            case IMAGETYPE_GIF :
                header('Content-type: image/gif');
                imagegif($this->dImage);
                break;
            default:
                break;
        }
    }

    function SaveAlpha($fileName=''){
        $this->dst_file=$fileName ? $fileName . '.png' : $this->dst_file .'.png';
        imagesavealpha($this->dImage, true);
        imagepng($this->dImage,$this->dst_file);
    }

    function OutAlpha(){
        imagesavealpha($this->dImage, true);
        header('Content-type: image/png');
        imagepng($this->dImage);
    }

    function destory(){
        imagedestroy($this->sImage);
        imagedestroy($this->dImage);
    }

    function Crop($dst_width,$dst_height,$mode=1,$dst_file=''){
        if($dst_file) $this->dst_file=$dst_file;
        $this->dImage = imagecreatetruecolor($dst_width,$dst_height);

        $bg = imagecolorallocatealpha($this->dImage,255,255,255,127);
        imagefill($this->dImage, 0, 0, $bg);
        imagecolortransparent($this->dImage,$bg);

        $ratio_w=1.0 * $dst_width / $this->src_width;
        $ratio_h=1.0 * $dst_height / $this->src_height;
        $ratio=1.0;
        switch($mode){
            case 1:        // always crop
                if( ($ratio_w < 1 && $ratio_h < 1) || ($ratio_w > 1 && $ratio_h > 1)){
                    $ratio = $ratio_w < $ratio_h ? $ratio_h : $ratio_w;
                    $tmp_w = (int)($dst_width / $ratio);
                    $tmp_h = (int)($dst_height / $ratio);
                    $tmp_img=imagecreatetruecolor($tmp_w , $tmp_h);
                    $src_x = (int) (($this->src_width-$tmp_w)/2) ;
                    $src_y = (int) (($this->src_height-$tmp_h)/2) ;
                    imagecopy($tmp_img, $this->sImage, 0,0,$src_x,$src_y,$tmp_w,$tmp_h);
                    imagecopyresampled($this->dImage,$tmp_img,0,0,0,0,$dst_width,$dst_height,$tmp_w,$tmp_h);
                    imagedestroy($tmp_img);
                }else{
                    $ratio = $ratio_w < $ratio_h ? $ratio_h : $ratio_w;
                    $tmp_w = (int)($this->src_width * $ratio);
                    $tmp_h = (int)($this->src_height * $ratio);
                    $tmp_img=imagecreatetruecolor($tmp_w ,$tmp_h);
                    imagecopyresampled($tmp_img,$this->sImage,0,0,0,0,$tmp_w,$tmp_h,$this->src_width,$this->src_height);
                    $src_x = (int)($tmp_w - $dst_width) / 2 ;
                    $src_y = (int)($tmp_h - $dst_height) / 2 ;
                    imagecopy($this->dImage, $tmp_img, 0,0,$src_x,$src_y,$dst_width,$dst_height);
                    imagedestroy($tmp_img);
                }
                break;
            case 2:        // only small
                if($ratio_w < 1 && $ratio_h < 1){
                    $ratio = $ratio_w < $ratio_h ? $ratio_h : $ratio_w;
                    $tmp_w = (int)($dst_width / $ratio);
                    $tmp_h = (int)($dst_height / $ratio);
                    $tmp_img=imagecreatetruecolor($tmp_w , $tmp_h);
                    $src_x = (int) ($this->src_width-$tmp_w)/2 ;
                    $src_y = (int) ($this->src_height-$tmp_h)/2 ;
                    imagecopy($tmp_img, $this->sImage, 0,0,$src_x,$src_y,$tmp_w,$tmp_h);
                    imagecopyresampled($this->dImage,$tmp_img,0,0,0,0,$dst_width,$dst_height,$tmp_w,$tmp_h);
                    imagedestroy($tmp_img);
                }elseif($ratio_w > 1 && $ratio_h > 1){
                    $dst_x = (int) abs($dst_width - $this->src_width) / 2 ;
                    $dst_y = (int) abs($dst_height -$this->src_height) / 2;
                    imagecopy($this->dImage, $this->sImage,$dst_x,$dst_y,0,0,$this->src_width,$this->src_height);
                }else{
                    $src_x=0;$dst_x=0;$src_y=0;$dst_y=0;
                    if(($dst_width - $this->src_width) < 0){
                        $src_x = (int) ($this->src_width - $dst_width)/2;
                        $dst_x =0;
                    }else{
                        $src_x =0;
                        $dst_x = (int) ($dst_width - $this->src_width)/2;
                    }

                    if( ($dst_height -$this->src_height) < 0){
                        $src_y = (int) ($this->src_height - $dst_height)/2;
                        $dst_y = 0;
                    }else{
                        $src_y = 0;
                        $dst_y = (int) ($dst_height - $this->src_height)/2;
                    }
                    imagecopy($this->dImage, $this->sImage,$dst_x,$dst_y,$src_x,$src_y,$this->src_width,$this->src_height);
                }
                break;
            case 3:        // keep all image size and create need size
                if($ratio_w > 1 && $ratio_h > 1){
                    $dst_x = (int)(abs($dst_width - $this->src_width )/2) ;
                    $dst_y = (int)(abs($dst_height- $this->src_height)/2) ;
                    imagecopy($this->dImage, $this->sImage, $dst_x,$dst_y,0,0,$this->src_width,$this->src_height);
                }else{
                    $ratio = $ratio_w > $ratio_h ? $ratio_h : $ratio_w;
                    $tmp_w = (int)($this->src_width * $ratio);
                    $tmp_h = (int)($this->src_height * $ratio);
                    $tmp_img=imagecreatetruecolor($tmp_w ,$tmp_h);
                    imagecopyresampled($tmp_img,$this->sImage,0,0,0,0,$tmp_w,$tmp_h,$this->src_width,$this->src_height);
                    $dst_x = (int)(abs($tmp_w -$dst_width )/2) ;
                    $dst_y = (int)(abs($tmp_h -$dst_height)/2) ;
                    imagecopy($this->dImage, $tmp_img, $dst_x,$dst_y,0,0,$tmp_w,$tmp_h);
                    imagedestroy($tmp_img);
                }
                break;
            case 4:        // keep all image but create actually size
                if($ratio_w > 1 && $ratio_h > 1){
                    $this->dImage = imagecreatetruecolor($this->src_width,$this->src_height);
                    imagecopy($this->dImage, $this->sImage,0,0,0,0,$this->src_width,$this->src_height);
                }else{
                    $ratio = $ratio_w > $ratio_h ? $ratio_h : $ratio_w;
                    $tmp_w = (int)($this->src_width * $ratio);
                    $tmp_h = (int)($this->src_height * $ratio);
                    $this->dImage = imagecreatetruecolor($tmp_w ,$tmp_h);
                    imagecopyresampled($this->dImage,$this->sImage,0,0,0,0,$tmp_w,$tmp_h,$this->src_width,$this->src_height);
                }
                break;
        }
    }// end Crop

    /**
     *
     * 裁切方法
     * 2016-01-07 15:05:44
     * Lixiaoyu
     *
     * @param $dst_width 目标长
     * @param $dst_height  目标高
     * @param $dst_x   裁剪部分和原图左侧的距离
     * @param $dst_y   裁剪部分和原图右侧的距离
     * @param int $mode  模式
     * @param string $dst_file  目标文件路径
     */
    function Cut($dst_width,$dst_height,$dst_x,$dst_y,$dst_file='')
    {
        if ($dst_file) $this->dst_file = $dst_file;  //设置目标文件位置
        $this->dImage = imagecreatetruecolor($dst_width, $dst_height); //创建了目标文件的大小的画布

        $bg = imagecolorallocatealpha($this->dImage, 255, 255, 255, 127); //给画布分配颜色
        imagefill($this->dImage, 0, 0, $bg);     //给图像用颜色进行填充
        imagecolortransparent($this->dImage, $bg);  //背景定义成透明色

        $ratio_w = 1.0 * $dst_width / $this->src_width;  //横向缩放的比例
        $ratio_h = 1.0 * $dst_height / $this->src_height;  //纵向缩放的比例

        //var_dump($this);

        //不进行缩放,直接对图像进行裁剪
        $ratio = 1.0;
        $tmp_w = (int)($dst_width / $ratio);
        $tmp_h = (int)($dst_height / $ratio);
        $tmp_img = imagecreatetruecolor($dst_width, $dst_height); //创建暂时保存的画布
        imagecopy($tmp_img, $this->sImage, 0,0,$dst_x,$dst_y,$dst_width,$dst_height);  //拷贝出图像的一部分,进行裁切
        imagecopyresampled($this->dImage,$tmp_img,0,0,0,0,$dst_width,$dst_height,$tmp_w,$tmp_h); //把暂时缓存的图片,放到目标文件里面
        imagedestroy($tmp_img);

    }
}
?>

Use

裁剪图像


$ic=new ImageCrop($pathToFile,'./pic/afterCrop'.time().'.jpg');
$ic->Cut(40,30,120,130);
$ic->SaveImage();
//$ic->SaveAlpha();将补白变成透明像素保存
$ic->destory();

实现效果

原图

裁剪之后的图

缩放图像

原图

缩略图

重点难点

重点在于使用图像处理函数 imagecopyimagecopyresampled

bool imagecopy ( resource dstim,resourcesrc_im , int dstx,intdst_y , int srcx,intsrc_y , int srcw,intsrc_h )
将 src_im 图像中坐标从 src_x,src_y 开始,宽度为 src_w,高度为 src_h 的一部分拷贝到 dst_im 图像中坐标为 dst_x 和 dst_y 的位置上。

参考资料

时间: 2024-09-17 03:55:05

【PHP】PHP图像裁剪缩略裁切类源代码及使用方法的相关文章

PHP图像裁剪缩略裁切类源码及使用方法_php实例

最近在做网页拖拽验证码的开源项目,需要在服务端生成图片对应的可移动的色块,但是网上的资源都是做缩略图,对整个图片进行缩放的,所以自己动手,完成了对图片进行裁剪小块的工具 <?php namespace App\Libs; /** * 2016-01-07 15:54:58 * Lixiaoyu * * mode 1 : 强制裁剪,生成图片严格按照需要,不足放大,超过裁剪,图片始终铺满 * mode 2 : 和1类似,但不足的时候 不放大 会产生补白,可以用png消除. * mode 3 : 只缩

php 图片处理类,缩略,水印

php 图片处理类,缩略,水印 class Image {  /**   * @var string $fileName 文件名   * @access private   */  private $fileName = '';    /**   * @var gd resource $imageResource 原图像   * @access private   */  private $imageResource = NULL;    /**   * @var int $imageWidth

广电总局屏蔽NBA等缩略词

本报讯(记者易东方)昨天,央视体育频道总监江和平证实,广电总局一周前向央视等媒体下发通知,要求在主持人口播.记者采访和字幕中,不能再使用诸如NBA.GDP.WTO.CPI等外语和缩略词.江和平称,这一通知对央视的解说员和记者来说,规避起来比较简单. 从这个月起,央视体育新闻已经在节目中开始规避"NBA""CBA""F1"等观众耳熟能详的缩略词,取而代之的是"美国职业篮球联赛""中国男子篮球联赛""

McAfee推域名缩略服务McAf.ee

北京时间9月21日晚间消息,据国外媒体报道,安全软件公司McAfee周二宣布推出域名缩略服务McAf.ee,并表示该服务将帮助用户创建安全的缩略域名. McAfee该服务目前仍是测试版.如果使用该服务,用户将无需额外的安全软件.业内人士对McAfee推出域名缩略服务的目的感到不解,不过根据McAfee的说法,这一想法是由公关公司提出的,并且受到McAfee企业通信主管的支持. McAf.ee采用了McAfee实验室实时的"全球威胁智能"解决方案.这一解决方案采用上百万监测工具收集全球I

拿起铅笔:创作缩略草图

在Web UI之前,印刷设计师们使用一种称之为缩略草图(thumbnail sketching)的方法来尝试表达及完善创意.这种方法在现在的PC工具时代似乎已经失传. 这里我们将简要介绍什么是缩略草图,以及一些技巧来帮助把这门技术应用到你的工作之中. 在画线框图之前,先草图 线框图(wireframing)的话题由来已久.不需要回避这个话题,许多设计师以及UI/UX专家们认为线框图是一个最基本以及整个项目中第一个步骤,让我们能专注在基础的架构上而不是多余的设计风格上的干扰. 另一种定义说的是线框

java代码-java实现图片浏览器,要求带图片缩略

问题描述 java实现图片浏览器,要求带图片缩略 其他基本功能已实现,现在就差缩略没写,功能大概是在读入文件时访问所有图片文件,并生成缩略图,在主面板一侧以列表的形式显示,当点击列表中的缩略图时,在主面板中显示原图 解决方案 简单图片浏览器的实现java swing实现简单的图片浏览器缩略图片

软件工程缩略词名词解释

问题描述 软件工程缩略词名词解释 DMT SREM SRI CML RTM SCRUM 求大神帮忙解释一下 解决方案 DMT(Dynamic Multithreading Architecture,动态多线程结构) SREM(software requirement engineering methodology,软件要求工程方法学) SRI(SIP Relay Interface,SIP传递的接口) CML(Concurrent Mapping and Localization ,并行映射与定

java实现图片浏览器,要求带图片缩略

问题描述 java实现图片浏览器,要求带图片缩略 其他基本功能已实现,现在就差缩略没写,功能大概是在读入文件时访问所有图片文件,并生成缩略图,在主面板一侧以列表的形式显示,当点击列表中的缩略图时,在主面板中显示原图 解决方案 简单图片浏览器的实现java swing实现简单的图片浏览器缩略图片 解决方案二: 简单图片浏览器的实现java swing实现简单的图片浏览器缩略图片 解决方案三: 楼主问题不是很清晰,针对你的问题,我有如下建议: 1. 如果使用java生成缩略图,有很多方法,java

Tr.im停止网址缩略服务API仍可使用

北京时间3月22日下午消息,据国外媒体今日报道,网址缩略服务Tr.im通过官方网站发布通知称,该网站将不再为用户提供网址缩略服务,但API(应用编程接口)仍然可以使用. Tr.im说:"Tr.im将不再通过网站接受网址缩略请求.我们恭敬地建议您选择其他替代产品.这一决定将不会影响到内置Tr.im服务的软件.Tr.im的API仍然可以使用,重新定向功能仍将正常运行." 这意味着,只有使用Tr.im API的工具或服务才能够继续使用网址缩略服务,其他渠道均无法继续使用这一服务.(鼎宏)