【问题标题】:How to make any "extra space" white when using imagecopy in PHP在 PHP 中使用 imagecopy 时如何使任何“额外空间”变白
【发布时间】:2026-01-09 05:35:01
【问题描述】:

我正在使用 imagecopy 将 PNG 图像裁剪为用户规范。

目前,如果裁剪区域大于图像,任何“额外空间”都会变成黑色,但我希望它是白色的。

找了一堆,发现可以使用imagefill或者imagefillrectangle来让背景变白,但是如果在imagecopy之前完成,那么它没有效果,如果在imagecopy之后完成,它也会使任何图像的黑色部分为白色。

我的代码目前看起来像这样,原始图像的黑色部分变成白色以及额外的空间:

// Input and output files
$infile = "[Image]";
$outfile = "[Output path for image]"

// Make the image
$orig =imagecreatefromjpeg($infile);
$width = imagesx($orig);
$height = imagesy($orig);
$new = imagecreatetruecolor($width, $height);

// Crop the image
imagecopy($new, $orig,  0, 0, -100, 100, $width, $height);

// Try and make the extra space white
$white = imagecolorallocate($new, 255,255,255);
imagefill($new, 0, 0, $white);

// Save the file
imagepng($new, $outfile);

如何在不影响原始图像的情况下使多余的空间变白?我无法控制用户可能上传的图片,因此我无法选择透明颜色,因为该颜色可能是他们原始图片的一部分。

编辑:当用户选择原始图像尺寸之外的裁剪尺寸时,就会出现这种情况,我确实希望这是一个有效的选项。裁剪是强制一个方形图像,但如果用户上传一个横向矩形并希望他们的所有图像都在最终裁剪中,那么裁剪将在顶部和底部的图像之外(这是我希望它是白色而不是黑色)

【问题讨论】:

    标签: php gd


    【解决方案1】:

    发生这种情况是因为您向imagecopy() 提供了“无效”值(也就是说,裁剪坐标超出了源图像的范围)。 GD 只是用黑色像素填充边界区域。如果它改为使用透明(或任何颜色)像素,那就太好了,但不幸的是,这不是一个选择。

    我不完全理解您要做什么(您的来源似乎与您声明的目标不匹配),但可能的解决方案是将裁剪限制在图像的范围内:

    $src = imagecreatefromjpeg('JPEG FILE'); // 100x100 image in my test.
    $src_w = imagesx($src);
    $src_h = imagesy($src);
    
    $user_crop = [
        'x' => -50,
        'y' => -50,
        'width' => 150,
        'height' => 150
    ];
    
    if ($user_crop['x'] < 0) {
        $user_crop['x'] = 0;
    }
    if ($user_crop['y'] < 0) {
        $user_crop['y'] = 0;
    }
    if ($user_crop['x'] + $user_crop['width'] > $src_w) {
        $user_crop['width'] = $src_w - $user_crop['x'];
    }
    if ($user_crop['y'] + $user_crop['height'] > $src_h) {
        $user_crop['height'] = $src_h - $user_crop['y'];
    }
    
    $dest = imagecreatetruecolor($src_w, $src_h);
    imagefill($dest, 0, 0, 0x00ffffff); // opaque white.
    imagecopy(
        $dest,
        $src,
        $user_crop['x'],
        $user_crop['y'],
        $user_crop['x'],
        $user_crop['y'],
        $user_crop['width'],
        $user_crop['height']
    );
    
    header('Content-type: image/png;');
    imagepng($dest);
    imagedestroy($src);
    imagedestroy($dest);
    exit;
    

    请注意,我在这段代码中对裁剪图像的位置做了一些假设。

    【讨论】:

    • 示例代码被简化了,但基本上用户可以缩小并裁剪图像边界之外的图像,我确实希望这是一个有效的选项。裁剪是强制一个正方形,但是如果用户的图像是一个横向矩形并且他们希望在最终输出中所有的原始图像,那么裁剪大小将在顶部和底部的原始图像之外。希望这是有道理的!
    • 好吧,我认为这个解释填补了我理解的空白。我看看能不能修改上面的。