使用 PHP 裁剪 png 图像,移除空白透明度

Crop a png image with PHP, remove empty transparency

我目前正在尝试使用图片和 PHP,多亏了 GD 功能。 现在我想修改PNG图片的大小。这是我要调整大小的 PNG 示例:

虚线代表PNG的边框,背景是透明的,我只在大space中间丢了一颗星星。我想裁剪这颗星星,得到一个简单的正方形星星(即使新背景变成空白,也没关系)。

我怎样才能有效地做这样的事情?我考虑过循环检查图片的每个像素。试图找到图像的位置,最终根据最小 x / 最大 X 和最小 y / 最大 y 值裁剪一点边距,但如果我开始工作几百张图,真的很长

编辑:

<?php

$file = "./crop.png";

$ext = pathinfo($file, PATHINFO_EXTENSION);

$image;

switch ($ext){
case 'png':
    $image = imagecreatefrompng($file);
    break;

case 'jpeg':
case 'jpg':
    $image = imagecreatefromjpeg($file);
    break;

case 'gif':
    $image = imagecreatefromgif($file);
    break;
}

$cropped = imagecropauto($image, IMG_CROP_DEFAULT);

    if ($cropped !== false) { // in case a new image resource was returned
        echo "=> Cropping needed\n";
        imagedestroy($image);    // we destroy the original image
        $image = $cropped;       // and assign the cropped image to $im
    }

    imagepng($image, "./cropped.png");
    imagedestroy($image);

如果您阅读并遵循完全符合您要求的 documentation, you'll find a function called imagecropauto,它会裁剪图像的 Alpha 通道。

使用 alpha 通道裁剪 PNG 图像

$im = imagecreatefrompng("./star-with-alpha.png");
$cropped = imagecropauto($im, IMG_CROP_DEFAULT);

if ($cropped !== false) { // in case a new image resource was returned
    imagedestroy($im);    // we destroy the original image
    $im = $cropped;       // and assign the cropped image to $im
}

imagepng($im, "./star-with-alpha-crop.png");
imagedestroy($im);

您可以使用以下代码直接在 php 页面上尝试:

<body>

<img src="star-with-alpha.png">

<?php 

$im = imagecreatefrompng("./star-with-alpha.png");
$cropped = imagecropauto($im, IMG_CROP_DEFAULT);

if ($cropped !== false) { // in case a new image resource was returned
    imagedestroy($im);    // we destroy the original image
    $im = $cropped;       // and assign the cropped image to $im
}

imagepng($im, "./star-with-alpha-crop.png");
imagedestroy($im);

?>

<img src="star-with-alpha-crop.png">

</body>

结果

http://zikro.gr/dbg/php/crop-png/

[这是给 ubuntu 12] imagecropauto 的唯一问题是它仅适用于 Mac 和 Windows。 而且由于当今大多数服务器都使用 ubuntu/debain - 此功能没有用。 而是为此使用 Imagick() 。 这是我编写的示例代码,正是这样做的:

    //Add background transmparent
    $background = 'none';
    $image = new Imagick($path);
    $image->trimImage(0);
   
    //add transparent border
    //border add start
    /** Set border format **/
    $borderWidth = 20;
    $borderColor = 'none';
    $borderPadding = 10;


    $imageWidth = $image->getImageWidth() + ( 2 * ( $borderWidth + 
    $borderPadding ) );
    $imageHeight = $image->getImageHeight() + ( 2 * ( $borderWidth + 
    $borderPadding ) );

为带边框的最终图像创建 Imagick 对象

    $imageWithBorder = new Imagick();
    // Set image canvas
    $imageWithBorder->newImage( $imageWidth, $imageHeight, new ImagickPixel( 
    'none' ));
    // Create ImagickDraw object to draw border
    $border = new ImagickDraw();
    // Set fill color to transparent
    $border->setFillColor( 'none' );
    // Set border format
    $border->setStrokeColor( new ImagickPixel( $borderColor ) );
    $border->setStrokeWidth( $borderWidth );
    $border->setStrokeAntialias( false );

绘制边框

    $border->rectangle(
        $borderWidth / 2 - 1,
        $borderWidth / 2 - 1,
        $imageWidth - ( ($borderWidth / 2) ),
        $imageHeight - ( ($borderWidth / 2) )
    );
    // Apply drawed border to final image
    $imageWithBorder->drawImage( $border );
    $imageWithBorder->setImageFormat('png');

保存图像

    // Put source image to final image
    $imageWithBorder->compositeImage(
            $image, Imagick::COMPOSITE_DEFAULT,
            $borderWidth + $borderPadding,
            $borderWidth + $borderPadding
    );
    
    $imageWithBorder->writeImage($path);

重新居中并适合原始图像的高度和宽度

    $imageWithBorder->scaleImage(FINAL_WIDTH, FINAL_HEIGHT, true);
    $imageWithBorder->setImageBackgroundColor($background);
    $w = $imageWithBorder->getImageWidth();
    $h = $imageWithBorder->getImageHeight();
    $imageWithBorder->extentImage(FINAL_WIDTH, FINAL_HEIGHT, ($w  - 
    FINAL_WIDTH) / 2, ($h - FINAL_HEIGHT)/ 2);
    $imageWithBorder->writeImage($path);

希望对您有所帮助。 干杯!