当前位置: 动力学知识库 > 问答 > 编程问答 >

gd - Crop non transparent pixels from a transperent 16x16 image using PHP

问题描述:

I would like to crop the non-transparent pixels from a transparent 16x16 canvas. Since the non transparent pixels is actually an image. Is it possible in PHP GD or Imagick?

网友答案:

Since the image is so small, you could probable loop through all the pixels with imagecolorat and then write the ones that aren't transparent to a new image with imagesetpixel or make note of the corners and copy the whole thing with imagecopy

Something like:

$x1 = -1;
$y1 = -1;
for($x=0;$x<16;$x++){
    for($y=0;$y<16;$y++){
        if (!transparent(imagecolorat($im, $x, $y))){
            if($x1 < 0 ){
                $x1 = $x;
                $y1 = $y;
            }else{
                $x2 = $x;
                $y2 = $y;       
            }
        }
    }
}
imagecopy($im2, $im, 0, 0, $x1, $y1, $x2-$x1+1, $y2-$y1+1); 

You will have to define the function transparent() - either do a bit shift to get the alpha channel or identify what the transparent color is if it's a gif.

Edit: Height/Width math updated

网友答案:

image magick has a trim method http://www.php.net/manual/en/imagick.trimimage.php I think that's what you need

<?php
/* Create the object and read the image in */
$im = new Imagick("image.jpg");

/* Trim the image. */
$im->trimImage(0);

/* Ouput the image */
header("Content-Type: image/" . $im->getImageFormat());
echo $im;
?>
网友答案:

Just spent ages fiddling with this and it's now the early hours!!

I couldn't find a function/script anywhere that only used GD so I hope this helps someone.

Essentially it loops through the rows and columns of the source image working out if the whole row/column is transparent, if it is it updates the $left, $right, $top and $bottom variables accordingly.

The only limitation I can think of is an image where there is a row or column that splits the image down the middle, at which point this would mark the $bottom or $right earlier than desired, but a nice start for anyone looking.

In my case the source image was a gd resource, and there is need of some imagedestroy() calls at the end....

function transparent($src_img,$in){
    $c = imagecolorsforindex($src_img,$in);
    if($c["alpha"] == 127){
        return true;
    }else{
        return false;
    }
    //var_dump($c);
}

function crop($src_img){

    $width = imagesx($src_img);
    $height = imagesy($src_img);

    $top = 0;
    $bottom = 0;
    $left = 0;
    $right = 0;

    for($x=0;$x<$width;$x++){
        $clear = true;
        for($y=0;$y<$height;$y++){
            if ($this->transparent($src_img,imagecolorat($src_img, $x, $y))){

            }else{
                $clear = false;
            }
        }
        if($clear===false){
            if($left == 0){
                $left = ($x-1);
            }
        }
        if(($clear===true)and($left != 0)){
            if($right == 0){
                $right = ($x-1);
            }else{
                break;
            }
        }
    }

    for($y=0;$y<$height;$y++){
        $clear = true;
        for($x=0;$x<$width;$x++){
            if ($this->transparent($src_img,imagecolorat($src_img, $x, $y))){

            }else{
                $clear = false;
            }
        }
        if($clear===false){
            if($top == 0){
                $top = ($y-1);
            }
        }
        if(($clear===true)and($top != 0)){
            if($bottom == 0){
                $bottom = ($y-1);
            }else{
                break;
            }
        }
    }

    $new = imagecreatetruecolor($right-$left, $bottom-$top);
    $transparent = imagecolorallocatealpha($new,255,255,255,127);
    imagefill($new,0,0,$transparent);


    imagecopy($new, $src_img, 0, 0, $left, $top, $right-$left, $bottom-$top);
    return $new;

}
分享给朋友:
您可能感兴趣的文章:
随机阅读: