QQ登录

只需一步,快速开始

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 2164|回复: 4

高质量缩略图的生成函数(多种剪切模式,按高度宽度最佳缩放等)

[复制链接]
发表于 2004-3-13 17:02:18 | 显示全部楼层 |阅读模式
[code:1]
<?php

/**
* 可扩展的缩略图生成函数
*
* 在http://yodoo.com的论坛里可以获得最新版本(注册用户)
* 演示效果也请登录http://yodoo.com看看,该站所有的缩略图(jpg,png)都是使用该函数生成的
*
* 转载请保留完整信息
*
* @author Austin Chin <[email protected]> http://yodoo.com
* @version $Revision: 1.7 $
*
*
* version
*
* + 表示增加的功能
* - 表示丢弃的功能
* C 表示修正的功能
* E 表示扩展了功能
*
* v1.5
* makeThumb($srcFile, $dstFile, $dstW, $dstH, $option=1)
*
* v1.6
* + 增加了剪切模式
* + $option 8: 宽度最佳缩放
* + $option 16: 高度最佳缩放
* makeThumb($srcFile, $dstFile, $dstW, $dstH, $option=1, $cutmode=0, $startX=0,
*     $startY=0)
*
* v1.7
* E 返回值改为数组,第一个元素是代码 0 表示正常, 其它位错误代码;第二个元素是错误描述。
* 错误代码:
* -1 源文件不存在。
* -2 不支持的图片输出函数
* -3 不支持的图片创建函数
* -4 HTTP头信息已经输出,无法向浏览器输出图片。
* -5 无法检测输出的图片类型
* + 增加函数 message2Image 可以把字符串输出成图片格式
*/


/**
* 可扩展的缩略图生成函数
*
* @param string $srcFile 源文件
* @param string $srcFile 目标文件
* @param int $dstW 目标图片的宽度(单位:像素)
* @param int $dstH 目标图片的高度(单位:像素)
* @param int $option 附加参数,可以相加使用,如1+2(或者 1|2)表示同时执行1和2的功能。
*      1: 默认,输出到指定文件 2: 图片内容输出到浏览器 4: 不保持图片比例
*      8:宽度最佳缩放 16:高度最佳缩放
* @param int $cutmode 剪切模式 0: 默认模式,剪切模式 1: 左或上 2: 中 3: 右或下
* @param int $startX 剪切的起始横坐标(像素)
* @param int $startY 剪切的起始纵坐标(像素)
* @return array return[0]=0: 正常; return[0] 为错误代码 return[1] string: 错误描述
*/
define(OP_TO_FILE, 1);              //输出到指定文件
define(OP_OUTPUT, 2);               //图片内容输出到浏览器
define(OP_NOT_KEEP_SCALE, 4);       //不保持图片比例, 即使用拉伸
define(OP_BEST_RESIZE_WIDTH, 8);    //宽度最佳缩放
define(OP_BEST_RESIZE_HEIGHT, 16);  //高度最佳缩放

define(CM_DEFAULT,  0);             // 默认模式
define(CM_LEFT_OR_TOP,  1);         // 左或上
define(CM_MIDDLE,       2);         // 中
define(CM_RIGHT_OR_BOTTOM,  3);     // 右或下

function makeThumb($srcFile, $dstFile, $dstW, $dstH, $option=OP_TO_FILE,
    $cutmode=CM_DEFAULT, $startX=0, $startY=0) {

    $img_type = array(1=>"gif", 2=>"jpeg", 3=>"png");
    $type_idx = array("gif"=>1, "jpg"=>2, "jpeg"=>2, "jpe"=>2, "png"=>3);

    if (!file_exists($srcFile)) {
        return array(-1, "Source file not exists: $srcFile.");
    }

    $path_parts = @pathinfo($dstFile);
    $ext = strtolower ($path_parts["extension"]);
    if ($ext == "") {
        return array(-5, "Can't detect output image's type.");
    }
    $func_output = "image" . $img_type[$type_idx[$ext]];
    if (!function_exists ($func_output)) {
        return array(-2, "Function not exists for output:$func_output.");
    }

    $data = @GetImageSize($srcFile);
    $func_create = "imagecreatefrom" . $img_type[$data[2]];
    if (!function_exists ($func_create)) {
        return array(-3, "Function not exists for create:$func_create.");
    }

    $im = @$func_create($srcFile);

    $srcW = @ImageSX($im);
    $srcH = @ImageSY($im);
    $srcX = 0;
    $srcY = 0;
    $dstX = 0;
    $dstY = 0;
   

    if ($option & OP_BEST_RESIZE_WIDTH) {
        $dstH = round($dstW * $srcH / $srcW);
    }

    if ($option & OP_BEST_RESIZE_HEIGHT) {
        $dstW = round($dstH * $srcW / $srcH);
    }

    $fdstW = $dstW;
    $fdstH = $dstH;

    if ($cutmode != CM_DEFAULT) { // 剪切模式 1: 左或上 2: 中 3: 右或下
        $srcW -= $startX;
        $srcH -= $startY;
        if ($srcW*$dstH > $srcH*$dstW) {
            $testW = round($dstW * $srcH / $dstH);
            $testH = $srcH;
        } else {
            $testH = round($dstH * $srcW / $dstW);
            $testW = $srcW;
        }
        switch ($cutmode) {
            case CM_LEFT_OR_TOP: $srcX = 0; $srcY = 0; break;
            case CM_MIDDLE: $srcX = round(($srcW - $testW) / 2);
                            $srcY = round(($srcH - $testH) / 2); break;
            case CM_RIGHT_OR_BOTTOM: $srcX = $srcW - $testW;
                                     $srcY = $srcH - $testH;
        }
        $srcW = $testW;
        $srcH = $testH;
        $srcX += $startX;
        $srcY += $startY;
    } else { // 原始缩放

        if (!($option & OP_NOT_KEEP_SCALE)) {
            // 以下代码计算新大小,并保持图片比例
            if ($srcW*$dstH>$srcH*$dstW) {
                $fdstH=round($srcH*$dstW/$srcW);
                $dstY=floor(($dstH-$fdstH)/2);
                $fdstW=$dstW;
            } else {
                $fdstW=round($srcW*$dstH/$srcH);
                $dstX=floor(($dstW-$fdstW)/2);
                $fdstH=$dstH;
            }
        
            $dstX=($dstX<0)?0:$dstX;
            $dstY=($dstX<0)?0:$dstY;
            $dstX=($dstX>($dstW/2))?floor($dstW/2):$dstX;
            $dstY=($dstY>($dstH/2))?floor($dstH/s):$dstY;
        }
    } /// end if ($cutmode != CM_DEFAULT) { // 剪切模式

    if( function_exists("imagecopyresampled") and
        function_exists("imagecreatetruecolor") ){
        $func_create = "imagecreatetruecolor";
        $func_resize = "imagecopyresampled";
    } else {
        $func_create = "imagecreate";
        $func_resize = "imagecopyresized";
    }

    $newim = @$func_create($dstW,$dstH);
    $black = @ImageColorAllocate($newim, 0,0,0);
    $back = @imagecolortransparent($newim, $black);
    @imagefilledrectangle($newim,0,0,$dstW,$dstH,$black);
    @$func_resize($newim,$im,$dstX,$dstY,$srcX,$srcY,$fdstW,$fdstH,$srcW,$srcH);

    if ($option & OP_TO_FILE) {
        @$func_output($newim,$dstFile);
    }

    if ($option & OP_OUTPUT) {
        if (function_exists("headers_sent")) {
            if (headers_sent()) {
                return array(-4, "HTTP already sent, can't output image to browser.");
            }
        }
        header("Content-type: image/" . $img_type[$type_idx[$ext]]);
        @$func_output($newim);
    }

    @imagedestroy($im);
    @imagedestroy($newim);

    return array(0, "OK");
}
?>
[/code:1]
发表于 2004-3-15 17:17:59 | 显示全部楼层
难得有人发源代码~~
加精~~
回复

使用道具 举报

 楼主| 发表于 2004-3-16 10:42:36 | 显示全部楼层
谢谢,这是制作一个资源发布网站的真实代码, http://yodoo.com 是测试网站, 我会把最新的代码应用到yodoo.com上, 源代码也会及时发布最新版。

再提供一个将文字转换为图片的函数,支持中文噢(需要使用TTF字体,比如使用windows下面的simsun.ttf字体就可以),本站登录时的验证码就是使用该函数生成的,该函数还可以生产随机干扰图案,以防OCR技术。

[code:1]
/**
* 字符串转换为png图片格式并输出到浏览器,支持换行,支持TTF字体,支持各种语言,如果包含其他非英文文字,请先转换
* 为Unicode(UTF-8)。
* 支持中文(需要使用相应的TTF字体,比如使用windows下面的simsun.ttf字体就可以), http://yodoo.com 登录时的验证码就是使用该函数生成的,该函数还可以生产随机干扰图案,以防OCR技术。
*
* 转载请保留完整信息。
*
* 最新版本在 http://yodoo.com
* @author Austin Chin <[email protected]> http://yodoo.com
* @version $Revision: 1.0 $
*
* @param string $message 字符串信息
* @param int $space 边框的宽度
* @param int $font 字体,如果使用内置字体,需要指定这项
* @param bool $drawFrame 是否画边框线
* @param bool $drawRandom 是否生成随机干扰图案
* @param int $randomCount 干扰图案的数量(次数)
* @param string $ttfFont TTF字体的路径
* @param int $fontSize TTF字体的大小
* @return NULL 直接输出到浏览器
*/
function message2Image($message, $space=5, $font=5, $drawFrame = false,
    $drawRandom = false, $randomCount = 1, $ttfFont = '', $fontSize = 15) {

    if (function_exists("headers_sent")) {
        if (headers_sent()) {
            return False;
        }
    }

    $use_ttf = function_exists('ImageTTFBBox') && function_exists('imageTTFtext')
        && file_exists($ttfFont) && is_numeric($fontSize);

    if ($use_ttf) {
        $fontSize = ($fontSize < 5)?5:$fontSize;
        $text_bbox = @ImageTTFBBox($fontSize, 0, $ttfFont, $message);
        $imagewidth = $text_bbox[2] - $text_bbox[0] + 2;
        //$fontHeight = $text_bbox[1] - $text_bbox[7] + 2;
        $imageheight = $text_bbox[1] - $text_bbox[7];
    } else {
        $lines = explode("\n", $message);
        $fontwidth = imagefontwidth($font);
        $fontheight = imagefontheight($font);
        $imagewidth = 0;
        $imageheight = 0;
        for ($i=0;$i<count($lines);$i++) {
            $strwidth = strlen($lines[$i]) * $fontwidth;
            if ($strwidth > $imagewidth) {
                $imagewidth = $strwidth;
            }
            $imageheight += $fontheight;
        }
    }

    $box_width = $imagewidth + $space*6;
    $box_height = $imageheight + $space*2;
    $im  = @imagecreate ($box_width, $box_height); /* Create a blank image */
    $bgColor = @imagecolorallocate ($im, 255, 255, 255);
    $gray = @imagecolorallocate ($im, 192, 192, 192);
    $color  = @imagecolorallocate ($im, 0, 0, 0);
   
    @imagefilledrectangle ($im, 0, 0, 150, 30, $bgColor);

    if ($use_ttf) {
        //echo ("$fontSize:$space:$ttfFont:$message");die();
        imageTTFtext($im, $fontSize, 0, $space*3, $space + $imageheight, $color,
            $ttfFont, $message);
    } else {
        $y = $space;
        for ($i=0;$i<count($lines);$i++) {
            @imagestring ($im, $font, $space*3, $y,  $lines[$i], $color);
            $y += $fontheight;
        }
    }

    if ($drawFrame) {
        //$style = array ($color,$color,$bgColor);
        //@imagesetstyle ($im, $style);
        @imagerectangle($im, 0, 0 ,$box_width - 1, $box_height - 1, $color);
    }

    if ($drawRandom) {
        $style = array ($gray,$bgColor);
        @imagesetstyle ($im, $style);
        $count = strlen($message);
        $sep = $imagewidth / $count;

        for ($i=0; $i<$randomCount; $i++) {
            $count = strlen($message);
            $startX = $count * $sep;
            $startY = rand(1, $imageheight);
            while ($count-- > 0) {
                $endY = rand(1, $imageheight);
                $endX = $count * $sep;
                imageline($im, $startX, $startY, $endX, $endY, IMG_COLOR_STYLED);
                $startX = $endX;
                $startY = $endY;
            }
        }

    }

    @header("Content-type: image/png");
    @imagepng($im);
    @ImageDestroy($im);
}
[/code:1]
回复

使用道具 举报

发表于 2004-3-16 13:23:16 | 显示全部楼层
先顶~~~谢谢
回复

使用道具 举报

发表于 2004-3-16 13:23:37 | 显示全部楼层
先顶~~~谢谢
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

GMT+8, 2024-5-10 20:56 , Processed in 0.145155 second(s), 15 queries .

© 2021 Powered by Discuz! X3.5.

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