简体   繁体   English

用php将jpg保存为透明png

[英]Saving a jpg as a transparent png with php

I have a function created which processes images in different ways based on the parameters. 我创建了一个函数,该函数根据参数以不同方式处理图像。 I have comments in the function to explain a bit. 我在函数中有注释来解释一下。

Everything works with exception to when I take a jpg image and save it as a png. 除了拍摄jpg图像并将其另存为png之外,一切都正常。 I just checked, even if I use imagepng() but save it with the extension .jpg, the image displays while properly resized, but with a .jpg extension. 我只是检查了一下,即使我使用imagepng()但将其保存为扩展名.jpg时,该图像imagepng()在正确调整大小的同时显示,但扩展名为.jpg。 However, if I upload the same .jpg image, use imagepng() and save it with a .png extension, I get an image of the expected width and height after the resize, in a png format, with a .png extension. 但是,如果我上传相同的.jpg图像,使用imagepng()并以.png扩展名保存,则在调整大小后,我会得到具有预期宽度和高度的图像,其格式为png格式,扩展名为.png。 While the whole image is 100% transparent I have a 1px by 1px black pixel in the top left corner. 虽然整个图像都是100%透明的,但我在左上角有一个1px x 1px的黑色像素。

I would appreciate it if anyone can look at this and see if they see something I am missing. 如果有人可以看看这个,看看他们是否看到我缺少的东西,我将不胜感激。 I believe the 1px X 1px is coming from the point I use for the imagefill() , but I don't understand why; 我相信1px X 1px来自我用于imagefill() ,但我不明白为什么; it should be filling all transparent as with the rest of the image. 它应该像图像的其余部分一样全部透明。

Here is my function: 这是我的功能:

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;  
    }
}

EDIT 1: I guess I should have noted that I am uploading a .jpg image (Ex: 100px X 200px) and converting them to .png (Ex: 400px X 200px) but am retaining the proportions of the image to fit perfectly in the center of the destination .png. 编辑1:我想我应该注意到,我正在上传.jpg图像(例如:100px X 200px)并将其转换为.png(例如:400px X 200px),但是保留图像的比例以使其完全适合目标.png的中心。 So I would have a 400px X 200px .png with my image in the center and 100px on the left and right which should be transparent. 因此,我将拥有一个400px X 200px .p​​ng的图像,其图像居中,而左右两侧分别为100px,这应该是透明的。 This way it fits nicely in a slider without a solid color as a fill. 这样,它可以很好地适合没有纯色填充的滑块。 So an example of my call to my function would be upload($image, 400, 200, 2) . 因此,我对函数的调用示例为upload($image, 400, 200, 2)

I figured out what the issue was. 我弄清楚了问题所在。 The portion of code which decides whether I should use imagecreatefromjpeg or imagecreatefrompng was incorrectly going off of the extension of the passed image and NOT by its mime type. 决定我应该使用imagecreatefromjpeg还是imagecreatefrompng的代码部分错误地超出了所传递图像的扩展名,而不是由其mime类型决定。 I switched it to this: 我将其切换为:

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

where $type is coming from the line I had in there $type来自我在那里的那一行

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

So all together the function is: 所以所有的功能是:

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;
    }
}

And an example call would be: upload("path/to/image/on/server.png", 400, 200, 2) Where the image path can be either in a jpg or png mime type. 调用示例为: upload("path/to/image/on/server.png", 400, 200, 2)其中图像路径可以是jpg或png mime类型。 But the extension MUST be .png. 但是扩展名必须为.png。 I suppose I can make it smarter where you can have any extension, but with the current code which uses this function it makes more sense for me to leave it as is. 我想我可以在可以进行任何扩展的地方变得更聪明,但是使用该功能的当前代码对我来说更有意义。 I would like to eventually add the option to turn on or off the transparency and instead use a solid color such as black if it is needed. 我想最终添加用于打开或关闭透明度的选项,如果需要的话,可以使用诸如黑色的纯色。 Feel free to use and modify this. 随时使用和修改它。

There are nice hex2rgb/rgb2hex functions which I plan on using for this here 我计划在这里使用不错的hex2rgb / rgb2hex函数

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM