图像处理-使用php将jpg保存为透明的png


image processing - Saving a jpg as a transparent png with php

我创建了一个函数,它根据参数以不同的方式处理图像。我在函数中有注释来解释一下。

当我拍摄jpg图像并将其保存为png时,一切都可以工作。我只是检查,即使我使用imagepng(),但保存它的扩展名。jpg,图像显示,而适当调整大小,但与。jpg扩展。但是,如果我上传相同的。jpg图像,使用imagepng()并将其保存为。png扩展名,则在调整大小后,我将获得期望宽度和高度的图像,以png格式,扩展名为。png。虽然整个图片是100%透明的,但我在左上角设置了一个1px * 1px的黑色像素

如果有人能看看这个,看看他们是否看到我错过了什么,我会很感激的。我相信1px X 1px来自我用于imagefill()的点,但我不明白为什么;它应该像图片的其他部分一样全透明。

下面是我的函数:

if(!function_exists("upload")){
    //$image = $image file name
    //$width = intended width of resized image, if 0 it will proportion to height, overrides proportion
    //$height = intended width of resized image, if 0 it will proportion to width, overrides proportion
    //$proportion = 2,1,0;
    //------ 2 = Preserve proportions while adding a border to fill width and height  
    //------ 1 = retain proportion to fit within both given width and height
    //------ 0 = disregard proportions and resize to the exact width and height
    function upload($image, $width, $height, $proportion){
        // IS GD HERE?
        $gdv = get_gd_info();
        if (!$gdv){ 
            return FALSE;
        }
        // GET AN IMAGE THING
        $ext = trim(strtolower(end(explode('.', $image))));
        list($imageX, $imageY, $type) = getimagesize($image);   //gets information about new server image
        // GET THE LESSER OF THE RATIO OF THUMBNAIL H OR W DIMENSIONS
        $ratio_w = ($width / $imageX);
        $ratio_h = ($height / $imageY);
        $ratio   = ($ratio_w < $ratio_h) ? $ratio_w : $ratio_h;     
        if($width == 0){
            if($imageY > $height){
                $newHeight = $height;
                $newWidth = ($height/$imageY) * $imageX;    
            }else{
                $newHeight = $imageY;
                $newWidth = $imageX;    
            }
            $width = $newWidth;
            $height = $newHeight;
            // COMPUTE THUMBNAIL IMAGE CENTERING OFFSETS
            $fromMidX = 0;
            $fromMidY = 0;
        }elseif($height == 0){
            if ($imageX > $width){
                $newWidth = $width;
                $newHeight = ($width/$imageX) * $imageY;
            }else{
                $newHeight = $imageY;
                $newWidth = $imageX;    
            }
            $width = $newWidth;
            $height = $newHeight;
            // COMPUTE THUMBNAIL IMAGE CENTERING OFFSETS
            $fromMidX = 0;
            $fromMidY = 0;
        }elseif($proportion == 2){
            // COMPUTE THUMBNAIL IMAGE DIMENSIONS
            $newWidth = $imageX * $ratio;
            $newHeight = $imageY * $ratio;
            // COMPUTE THUMBNAIL IMAGE CENTERING OFFSETS
            $fromMidX = ($width - $newWidth) / 2.0;
            $fromMidY = ($height - $newHeight) / 2.0;
        }elseif($proportion == 1){
            if ($imageX > $width){
                $newHeight = ($width/$imageX) * $imageY;
                $newWidth = $width;
            }
            if ($imageY > $height){
                $newHeight = $height;
                $newWidth = ($height/$imageY) * $imageX;
            }
            $fromMidY = 0;
            $fromMidX = 0;
        }elseif($proportion == 0){
            $newWidth = $width;
            $newHeight = $height;
            $fromMidY = 0;
            $fromMidX = 0;          
        }
        switch(strtoupper($ext))
        {
            case 'JPG' :
            case 'JPEG' :
                $source = imagecreatefromjpeg($image);
                break;
            case 'PNG' :
                $source = imagecreatefrompng($image);
                break;
            default : die("UNKNOWN IMAGE TYPE: $image");
        }
        // WHICH FUNCTIONS CAN RESIZE / RESAMPLE THE IMAGE?
        if ($gdv >= 2)
        {
            // IF GD IS AT LEVEL 2 OR ABOVE
            $target = imagecreatetruecolor($width, $height);
            $color = imagecolorallocatealpha($target, 0, 0, 0, 127); 
            imagefill($target, 0, 0, $color);
            imagesavealpha($target, TRUE);

            imagecopyresampled ($target, $source, $fromMidX, $fromMidY, 0, 0, $newWidth, $newHeight, $imageX, $imageY);
        }
        else
        {
            // IF GD IS AT A LOWER REVISION LEVEL
            $target = imagecreate($width, $height);
            imagesavealpha($target, TRUE);
                $empty = imagecolorallocatealpha($thumb,0x00,0x00,0x00,127);
                imagefill($target, 0, 0, $empty);
            imagecopyresized($target, $source, $fromMidX, $fromMidY, 0, 0, $newWidth, $newHeight, $imageX, $imageY);
        }
        // SHARPEN THE PIC
        $sharpenMatrix = array
        ( array( -1.2, -1, -1.2 )
        , array( -1,   20, -1 )
        , array( -1.2, -1, -1.2 )
        )
        ;
        $divisor = array_sum(array_map('array_sum', $sharpenMatrix));
        $offset  = 0;
        imageconvolution($target, $sharpenMatrix, $divisor, $offset);
        if(imagepng($target, $image,9)){
            imagedestroy($target);
        }else{
        }
        return $image;  
    }
}

编辑1:我想我应该注意到,我正在上传一个。jpg图像(例如:100px X 200px)并将它们转换为。png(例如:400px X 200px),但我保留了图像的比例,以完美地适应目标。png的中心。所以我要有一个400px X 200px的。png,中间是我的图像,左右是100px,应该是透明的。这样,它就可以很好地适应滑动条,而不需要纯色填充。因此,我调用我的函数的一个例子是upload($image, 400, 200, 2)

我知道问题出在哪里了。决定我是否应该使用imagecreatefromjpegimagecreatefrompng的代码部分错误地离开了传递的图像的扩展,而不是通过其mime类型。我把它改成了:

switch($type)
        {
            case '2' :
                $source = imagecreatefromjpeg($image);
                break;
            case '3' :
                $source = imagecreatefrompng($image);
                break;
            default : die("UNKNOWN IMAGE TYPE: $image");
        }

其中$type来自我刚才写的那行

list($imageX, $imageY, $type) = getimagesize($image);

所以整个函数是:

if(!function_exists("upload")){
    //$image = $image file name
    //$width = intended width of resized image, if 0 it will proportion to height, overrides proportion
    //$height = intended width of resized image, if 0 it will proportion to width, overrides proportion
    //$proportion = 2,1,0;
    //------ 2 = Preserve proportions while adding a border to fill width and height  
    //------ 1 = retain proportion to fit within both given width and height
    //------ 0 = disregard proportions and resize to the exact width and height

    function upload($image, $width, $height, $proportion){
        // IS GD HERE?
        $gdv = get_gd_info();
        if (!$gdv){ 
            return FALSE;
        }
        // GET AN IMAGE THING
        $ext = trim(strtolower(end(explode('.', $image))));
        list($imageX, $imageY, $type) = getimagesize($image);   //gets information about new server image
        // GET THE LESSER OF THE RATIO OF THUMBNAIL H OR W DIMENSIONS
        $ratio_w = ($width / $imageX);
        $ratio_h = ($height / $imageY);
        $ratio   = ($ratio_w < $ratio_h) ? $ratio_w : $ratio_h;     
        if($width == 0){
            if($imageY > $height){
                $newHeight = $height;
                $newWidth = ($height/$imageY) * $imageX;    
            }else{
                $newHeight = $imageY;
                $newWidth = $imageX;    
            }
            $width = $newWidth;
            $height = $newHeight;
            // COMPUTE THUMBNAIL IMAGE CENTERING OFFSETS
            $fromMidX = 0;
            $fromMidY = 0;
        }elseif($height == 0){
            if ($imageX > $width){
                $newWidth = $width;
                $newHeight = ($width/$imageX) * $imageY;
            }else{
                $newHeight = $imageY;
                $newWidth = $imageX;    
            }
            $width = $newWidth;
            $height = $newHeight;
            // COMPUTE THUMBNAIL IMAGE CENTERING OFFSETS
            $fromMidX = 0;
            $fromMidY = 0;
        }elseif($proportion == 2){
            // COMPUTE THUMBNAIL IMAGE DIMENSIONS
            $newWidth = $imageX * $ratio;
            $newHeight = $imageY * $ratio;
            // COMPUTE THUMBNAIL IMAGE CENTERING OFFSETS
            $fromMidX = ($width - $newWidth) / 2.0;
            $fromMidY = ($height - $newHeight) / 2.0;
        }elseif($proportion == 1){
            if ($imageX > $width){
                $newHeight = ($width/$imageX) * $imageY;
                $newWidth = $width;
            }
            if ($imageY > $height){
                $newHeight = $height;
                $newWidth = ($height/$imageY) * $imageX;
            }
            $fromMidY = 0;
            $fromMidX = 0;
        }elseif($proportion == 0){
            $newWidth = $width;
            $newHeight = $height;
            $fromMidY = 0;
            $fromMidX = 0;          
        }
        switch($type)
        {
            case '2' :
                $source = imagecreatefromjpeg($image);
                break;
            case '3' :
                $source = imagecreatefrompng($image);
                break;
            default : die("UNKNOWN IMAGE TYPE: $image");
        }
        // WHICH FUNCTIONS CAN RESIZE / RESAMPLE THE IMAGE?
        if ($gdv >= 2)
        {
            // IF GD IS AT LEVEL 2 OR ABOVE
            $target = imagecreatetruecolor($width, $height);
            $color = imagecolorallocatealpha($target, 0, 0, 0, 127); 
            imagefill($target, 0, 0, $color);
            imagesavealpha($target, TRUE);
            imagecopyresampled ($target, $source, $fromMidX, $fromMidY, 0, 0, $newWidth, $newHeight, $imageX, $imageY);
        }
        else
        {
            // IF GD IS AT A LOWER REVISION LEVEL
            $target = imagecreate($width, $height);
            imagesavealpha($target, TRUE);
                $empty = imagecolorallocatealpha($thumb,0x00,0x00,0x00,127);
                imagefill($target, 0, 0, $empty);
            imagecopyresized($target, $source, $fromMidX, $fromMidY, 0, 0, $newWidth, $newHeight, $imageX, $imageY);
        }
        // SHARPEN THE PIC
        $sharpenMatrix = array
        ( array( -1.2, -1, -1.2 )
        , array( -1,   20, -1 )
        , array( -1.2, -1, -1.2 )
        )
        ;
        $divisor = array_sum(array_map('array_sum', $sharpenMatrix));
        $offset  = 0;
        imageconvolution($target, $sharpenMatrix, $divisor, $offset);
        if(imagepng($target, $image,9)){
            imagedestroy($target);
        }
        return $image;
    }
}

一个示例调用将是:upload("path/to/image/on/server.png", 400, 200, 2)其中图像路径可以是jpg或png mime类型。但扩展名必须是。png。我想我可以使它更聪明的地方,你可以有任何扩展,但与当前的代码使用这个函数,它使我更有意义,让它是。我想最终添加选项来打开或关闭透明度,而不是使用纯色,如黑色,如果需要的话。请随意使用和修改它。

有很好的hex2rgb/rgb2hex函数,我计划在这里使用