使用PHP从透明的16x16图像中裁剪非透明像素

时间:2013-04-18 20:19:56

标签: php gd transparent imagick

我想从透明的16x16画布裁剪非透明像素。由于非透明像素实际上是图像。是否可以在PHP GD或Imagick中使用?

3 个答案:

答案 0 :(得分:0)

由于图像太小,您可能会使用imagecolorat循环遍历所有像素,然后使用imagesetpixel将不透明的像素写入新图像或记下角落并使用imagecopy

复制整个内容

类似的东西:

$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); 

你必须定义函数transparent() - 要么做一点移动来获取alpha通道,要么识别透明色是什么,如果它是gif。

编辑:更新高度/宽度数学

答案 1 :(得分:0)

图片magick有一个修剪方法http://www.php.net/manual/en/imagick.trimimage.php我认为你需要的是

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

答案 2 :(得分:0)

花了很多时间摆弄这个,现在是凌晨!!

我找不到只使用GD的功能/脚本,所以我希望这可以帮助某人。

基本上,如果整个行/列是透明的,它会循环遍历源图像的行和列,如果它是相应地更新$ left,$ right,$ top和$ bottom变量。

我能想到的唯一限制是一个图像,其中有一行或一列将图像分割到中间,此时这将比预期更早地标记$ bottom或$ right,但对任何人来说都是个好的开始找。

在我的情况下,源图像是gd资源,最后需要一些imagedestroy()调用....

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;

}