0

我遇到了一个问题,我允许用户调整容器中的图像大小,然后需要创建一个结果图像,该图像是容器的大小,但图像会根据用户的选择进行缩放和调整。

例如,假设容器为 400 x 200,用户希望能够放入 600 x 100 的徽标,他们可能希望缩小徽标以使其适合并在顶部和底部留出空间。我需要能够将其保存为 400x200 的图像,顶部和底部有适当的间隙。

但我发现,如果图像内容(本例中的徽标)超出容器的顶部和右侧,一切都很好,或者如果它没有超出任何一个,那很好,但如果它超出一个而不是另一个然后我得到黑色填充 - 或类似的东西 - 见下面的例子......

下面是一些结果示例,这是我正在使用的代码......

$cropped =  wp_imagecreatetruecolor( $frame_w, $frame_h);
    $backgroundColor = imagecolorallocatealpha($cropped, 0, 0, 0, 127);
    //imageantialias( $cropped, true );
    //if $img_y or $img_x are negative we need to apply the value to $img_x and $img_y
    //if $img_y or $img_x are positive we need to apply the value to $dest_x and $dest_y
    $dest_x = strstr($img_x,'-') ? 0 : abs($img_x);//if neg is true = 0 else offset inside
    $dest_y = strstr($img_y,'-') ? 0 : abs($img_y);
    $img_x = strstr($img_x,'-') ? abs($img_x) : 0;//if neg is true offset outside else 0
    $img_y = strstr($img_y,'-') ? abs($img_y) : 0;
    $img_w = $img_w > $frame_w ? $frame_w : $img_w;
    $img_h = $img_h > $frame_h ? $frame_h : $img_h;
    imagecopy( $cropped, $resized, $dest_x, $dest_y, $img_x, $img_y, $img_w, $img_h);
    //imagecopymerge( $cropped, $resized, $dest_x, $dest_y, $img_x, $img_y, $img_w, $img_h,100);
    //imagecopyresampled( $cropped, $resized, $dest_x, $dest_y, $img_x, $img_y, $frame_w, $frame_h, $img_w, $img_h );
    imagefill($cropped, 0, 0, $backgroundColor);//putting this after the copy makes any black borders transparent again unless $resized does not extend beyond both dimensions

例子

图像没有超出顶部或超出右侧(罚款) 图像没有超出顶部或超出右侧(罚款)

图像超出底部但不正确(不好) 图像超出底部但不正确(不好)

图像超出两者(很好) 图像超出两者(很好)

图像超出右侧但未超出底部(不好) 图像超出右侧但未超出底部(不好)

图像既不超出(罚款) 图像既不超出(罚款)

我一直在努力解决这个问题,并尝试了所有可能的imagesavealpha、imagecopymerged、imagecolorallocatealpha、imagealphablending等我能想到的组合,但似乎没有什么能解决这个问题......

那么这是GD的错误/限制吗?或者有人可以来救我吗!

4

3 回答 3

0

我不知道这是否会帮助你,但我今天早些时候遇到了这个问题。盒子扩大了,但该区域是黑色的。这是我的代码(修复它):

<?php
function createImage($text)
{
    // Adds an extra space to fill underline
    $text = " $text";
    // Adds one line at the end
    $text .= "\n";
    // Wrap the text to fit the image
    $text = wordwrap($text, 40, "\n");
    // Count new lines
    $newlines = substr_count($text, "\n");
    // Count how long to expand
    if($newlines == 0)
    {
        $height = 30;
    }
    else
    {
        $height = 30*$newlines-$newlines*5;
    }

    putenv('GDFONTPATH=' . realpath('.'));
    header('Content-Type: image/png');
    // Adding underline
    $e = explode('<', $text);
    for($i=0;$i<count($e);$i++)
    {
        $e[$i] = implode('&#x0332;', str_split($e[$i]));
    }
    // Creating image
    $text = implode(' ', $e);
    $im = imagecreatetruecolor(315, $height);
    $white = imagecolorallocate($im, 255, 255, 255);
    $grey = imagecolorallocate($im, 128, 128, 128);
    $black = imagecolorallocate($im, 0, 0, 0);
    $purple = imagecolorallocate($im, 97, 26, 139);
    imagefilledrectangle($im, 0, 0, 399, $height, $white);
    $font = 'arialbd.ttf';

    imagettftext($im, 11, 0, 10, 20, $purple, $font, $text);
    imagepng($im);
    imagedestroy($im);
}

createImage("asbdasddsa");
?>
于 2013-02-07T03:59:10.193 回答
0

我认为这只会发生在使用其他格式的 PNG 检查

于 2013-02-07T12:23:01.713 回答
0

我不确定这是否是一个实际的答案,因为它基本上是“使用 ImageMagick”,但无论如何对于那些选择 ImageMagick 的人来说,下面的代码可能会帮助他们实现与我在上面尝试的相同的事情......基本上是 ImageMagick看起来比 GD 好得多,旋转图像周围没有边框,透明度没有麻烦,没有想要的黑色填充,如果你正在放大,更清晰的调整大小......

$img_x = -50; //left offset of the image within the frame
$img_y = 50; //top offset of the image within the frame
$img_w = 400; //width of the image to be put in the frame
$img_h = 200; // height of the image to be put in the frame
$angle = 45; //rotation to be applied to the image before it is put into the frame
$frame_w = 300; //width of the frame the image is going into
$frame_h = 300; //height of the frame the image is going into
$img_path = 'path/to/image/file.jpg';
$image = new Imagick( $img_path );
$size = $image->getImageGeometry();
$orig_w = $size['width']; $orig_h = $size['height'];
$image->scaleImage( $img_w, $img_h );
//rotate if necessary
if($angle)
    {
    $image->rotateImage( new ImagickPixel('none'), $angle );
    $size = $image->getImageGeometry();
    $img_w = $size['width']; $img_h = $size['height'];
    }
//composite into frame
//in imagemagick we create an image that is the size of the frame and make it transparent
$frame = new Imagick();
$frame->newImage($frame_w, $frame_h, new ImagickPixel("none"));
//then we composite the image itself into this with the respective offset values
$frame->compositeImage( $image, Imagick::COMPOSITE_DEFAULT, $img_x, $img_y );
//save it
$destfilename = "{$dir}/{$name}-{$img_suffix}.{$ext}";
$frame->writeImage($destfilename);
$frame->clear();
$frame->destroy();
$image->clear();
$image->destroy();

上面的代码产生 上面的代码产生了这个......耶!

于 2013-02-07T15:14:40.587 回答