设为首页 收藏本站
查看: 960|回复: 0

[经验分享] PHP图片自动裁切

[复制链接]
累计签到:1 天
连续签到:1 天
发表于 2017-3-27 08:03:27 | 显示全部楼层 |阅读模式
PHP图片自动裁切 
 
 
如果做过那种门户站的朋友,肯定知道,一张图片可能会在不同的地方显示,大小不同,比例也不同,
如果只用一张图的话,那么肯定会变形,而且在显示小图的地方,链接 大图,又太浪费了.....用缩略图来处理,也不完美,因为每个地方出现的比例 大小可能都不一样 ,举个例子!!!!!!!!!!!!
 
 
DSC0000.jpg
 
请看上图。
 
在这个地方,其实调去出来的是一个列表,但是 图片的大小是不一样的,有多大宽有的窄,,当遇到这样的情况的时候 你们怎么办呢,如果直接用原来的地址,肯定是会变形的,如果搞缩略图也不靠谱,这个调去是自动调去的,你根本不知道哪个图片需要多大的宽高,
------------------------------------------------------------------------------------------------------------------
下面进入正题:
我一直用一种方法,就是PHP 自动裁切...相比你们看到过类似那种图片地址吧  /aaaa/abc_200_100.jpg  或者/aaaa/abc_200*100.jpg
我的方式就是在需要图片地方把这个图片地址转化为 类似上面的那种地址, 然后通过apache rewrite 定向到一个处理程序.根据宽高生成一个图片然后保存起来,
 
这样做的好处有几个地方:
第一,非常灵活,在有图片地方,你需要多宽多高,都可以随意 控制,不会变形,而且程序永远会让图片内容显示的最多
第二个,当图片生成过一次的时候,apache下次就不会再重定向到程序了, 因为在规则前面 !d !f 这个判断,意思就是当前文件不存在的时候才会定向走,下次图片存在了,就不会再出来了 直接就是真是的图片了
 
不好的地方,就是生成的图片可能会比较多,占用的空间也比较大,但是如果是自己服务器 那就无所谓了,可以归类整理下
 
OK 奉上代码,我们就以discuz为例
 
function crop_img($img, $width = 200, $height = 200) {
    $img_info = parse_url($img);
    /* 外部链接直接返回图片地址 */
    if (!empty($img_info['host']) && $img_info['host'] != $_SERVER['HTTP_HOST']) {
        return $img;
    } else {
        $pos = strrpos($img, '.');
        $img = substr($img, 0, $pos) . '_' . $width . '_' . $height . substr($img, $pos);
        return $img;
    }
}
 
function img($img,$width,$height){
    $img_info = parse_url($img);
    /* 外部链接直接返回图片地址 */
    if (!empty($img_info['host']) && $img_info['host'] != $_SERVER['HTTP_HOST']) {
        return $img;
    } else {
        $pos = strrpos($img, '.');
        $img = substr($img, 0, $pos) . '_' . $width . '_' . $height . substr($img, $pos);
        echo '<img src="'.$img.'" width="'.$width.'" height="'.$height.'" />';
        return ;
    }   
}
 
函数的用法 crop_img('原图地址','宽度','高度'); 这个函数返回处理过的图片地址,img 函数直接返回图片标签字符串,比如在discuz模板里面调用这个函数 {eval img($pic,200,100)}
这样返回的地址就是/data/attachment/forum/aaaaaa_200_100.jpg  目前来说 这个图片是不存在 那么看第二步
 
第二步 需要添加apacherewrite规则
 
<IfModule mod_rewrite.c> 
    RewriteEngine on
   
   
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f 
    RewriteRule ^data/attachment/(.*)$ images.php?url=$1 [L]
 
</IfModule>
 
上面的意思,就是 data/attachement/这个地址开头不存在的文件都定向到image.php来处理,并且把url当参数传过去
 
第三部就是image.php 这个里面的代码里
 
<?php
 
$url = $_GET['url'];
$src = './data/attachment/' . preg_replace('/_(\d+)_(\d+)/', '', $url);
$filename = './data/attachment/' . $url;
 
if (file_exists($filename)) {
    ob_start();
    header('Content-type:image/jpeg');
    readfile($filename);
    ob_flush();
    flush();
} else {
    if(!preg_match('/_(\d+)_(\d+)/', $url, $wh)){
          defulat();
          exit();
    }
    $width = $wh[1];
    $height = $wh[2];
    thumb(realpath($src), $width, $height, $filename, 'crop', '85');
}
 
function thumb($src, $width, $height, $filename, $mode = 'scale', $quality = '100') {
    try {
        $imageValue = getimagesize($src);
        $sourceWidth = $imageValue[0];  //原图宽
        $sourceHeight = $imageValue[1]; //原图高
        $thumbWidth = $width;   //缩略图宽
        $thumbHeight = $height; //缩略图高
        $_x = 0;
        $_y = 0;
        $w = $sourceWidth;
        $h = $sourceHeight;
        if ($mode == 'scale') {
            if ($sourceWidth <= $thumbWidth && $sourceHeight <= $thumbHeight) {
                $_x = floor(($thumbWidth - $sourceWidth) / 2);
                $_y = floor(($thumbHeight - $sourceHeight) / 2);
                $thumbWidth = $sourceWidth;
                $thumbHeight = $sourceHeight;
            } else {
                if ($thumbHeight * $sourceWidth > $thumbWidth * $sourceHeight) {
                    $thumbHeight = floor($sourceHeight * $width / $sourceWidth);
                    $_y = floor(($height - $thumbHeight) / 2);
                } else {
                    $thumbWidth = floor($sourceWidth * $height / $sourceHeight);
                    $_x = floor(($width - $thumbWidth) / 2);
                }
            }
        } else if ($mode == 'crop') {
            if ($sourceHeight < $thumbHeight) { //如果原图尺寸小于当前尺寸   
                $thumbWidth = floor($thumbWidth * $sourceHeight / $thumbHeight);
                $thumbHeight = $sourceHeight;
            }
            if ($sourceWidth < $thumbWidth) {
                $thumbHeight = floor($thumbHeight * $sourceWidth / $thumbWidth);
                $thumbWidth = $sourceWidth;
            }
 
            $s1 = $sourceWidth / $sourceHeight; //原图比例
            $s2 = $width / $height;         //新图比例
            if ($s1 == $s2) {
               
            } else if ($s1 > $s2) {  //全高度               
                $y = 0;
                $ax = floor($sourceWidth * ($thumbHeight / $sourceHeight));
                $x = ($ax - $thumbWidth) / 2;
                $w = $thumbWidth / ($thumbHeight / $sourceHeight);
             
            } else { //全宽度  
                $x = 0;
                $ay = floor($sourceHeight * ($thumbWidth / $sourceWidth)); //模拟原图比例高度
                $y = ($ay - $thumbHeight) / 2;
                $h = $thumbHeight / ($thumbWidth / $sourceWidth);
            }
          
        }
        switch ($imageValue[2]) {
            case 2: $source = imagecreatefromjpeg($src);
                break;
            case 1: $source = imagecreatefromgif($src);
                break;
            case 3: $source = imagecreatefrompng($src);
                break;
            case 6: $source = imagecreatefromwbmp($src);
                break;
            default: defulat();
                return;
        }
        header("Content-type: image/jpeg");
        $thumb = imagecreatetruecolor($width, $height);
        imagefill($thumb, 0, 0, imagecolorallocate($thumb, 255, 255, 255));
        imagecopyresampled($thumb, $source, 0, 0, $x, $y, $width, $height, $w, $h);
        imagejpeg($thumb, null, $quality);
        // if ($_SERVER['HTTP_REFERER'] || false !== stripos($_SERVER['HTTP_REFERER'], 'http://' . $_SERVER['SERVER_NAME'])) {
        imagejpeg($thumb, $filename, $quality);
        // }
        imagedestroy($thumb);
        imagedestroy($source);
    } catch (Exception $ex) {
        defulat();
    }
}
 
function defulat() {
    $default_img = realpath('media/images/nopic.jpg');
    ob_start();
    header('Content-type:image/jpeg');
    readfile($default_img);
    ob_flush();
    flush();
}
 
thumb 函数 可以控制 裁切方式,scale 为等比缩放,不裁切,不够的地方 用白色填充,crop 为裁切,如果要求的宽高比 大于原图宽高比,那么就保持最大显示宽度,居中裁切上下多余部分,如果要求宽高比小于原图宽高比,那么就保持最大高度,居中裁切左右多余部分,总而言之,在保持不变形的前提下 ,把图片缩小,而且最大保留图片的内容.哈哈 这个代码有多叼,试试知道了,,,当然你需要支持rewrite功能和GD2 支持
 
 
拒绝当废柴,我要当学霸!领取PHP教程!

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-355828-1-1.html 上篇帖子: PHP入门知识点 下篇帖子: php程序员陋习
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表