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

使用PHP从透明的16x16图像中裁剪非透明像素,php,gd,transparent,imagick,Php,Gd,Transparent,Imagick,我想从透明的16x16画布上裁剪非透明像素。因为非透明像素实际上是一个图像。在PHP GD或Imagick中可能吗?由于图像太小,您可能会使用循环遍历所有像素,然后使用或记录角点将不透明的像素写入新图像,然后使用复制整个图像 比如: $x1 = -1; $y1 = -1; for($x=0;$x<16;$x++){ for($y=0;$y<16;$y++){ if (!transparent(imagecolorat($im, $x, $y))){

我想从透明的16x16画布上裁剪非透明像素。因为非透明像素实际上是一个图像。在PHP GD或Imagick中可能吗?

由于图像太小,您可能会使用循环遍历所有像素,然后使用或记录角点将不透明的像素写入新图像,然后使用复制整个图像

比如:

$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); 
$x1=-1;
$y1=-1;

对于($x=0;$ximage magick有一种修剪方法,我想这就是您需要的

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

只是花了很长时间来摆弄这件事,现在是凌晨

我在任何地方都找不到只使用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;

}
函数透明($src\u img,$in){
$c=图像颜色索引($src_img,$in);
如果($c[“alpha”]==127){
返回true;
}否则{
返回false;
}
//var_dump(c美元);
}
函数裁剪($src\u img){
$width=imagesx($src\u img);
$height=imagesy($src\u img);
$top=0;
$bottom=0;
$left=0;
$right=0;

对于($x=0;$x,裁剪是什么意思?16x16画布中是否有10x10的图像?是否尝试将其置于新的背景中?是的,例如16x16画布中有一个10x10的图像。但它并不总是10x10,大小也可能不同…因此我需要裁剪包含透明像素的图像,(它是PNG)…裁剪后,我可能会将其复制到不同位置的新画布上这真的很有帮助。但是,imagecopy不起作用..我得到了所有非透明的正确像素,但imagecopy遗漏了几个像素..我不能使用imagesetpixel,因为我希望裁剪后的图像位于左上角、右上角、左下角和右下角.需要帮忙吗?