在PHP中使用imagecopy时如何使任何“额外空间”变白

时间:2015-08-22 23:39:59

标签: php gd

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

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

已经搜索了一堆,我发现你可以使用imagefill或imagefilledrectangle使背景变白,但是如果在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);

如何在不影响原始图像的情况下将额外空间设为白色?我无法控制用户可能上传的图片,因此我无法真正选择透明色,因为该颜色可能是其原始图片的一部分。

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

1 个答案:

答案 0 :(得分: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;

请注意,我已在此代码中做了一些关于裁剪图像放置的假设。