一些图片/GD问题:裁剪、设置颜色和透明度

3
我写了一些使用GD的PHP代码,在Ubuntu机器上运行(PHP 5.5.9),现在将其移植到了Amazon Linux上的Amazon EC2上(PHP 5.5.31),但是从相同的输入数据文件中得到了完全不同的结果(我只使用imagecreatefromstring()$data包含JPEG文件的内容)。
  1. 在更改机器之前,它会将白色变为透明。现在它不再进行这种变化。
  2. 它曾经可以完美地裁剪图形。现在它在左侧留下一点白色,并且在右侧切掉了一小部分图像。
  3. 左侧有一条细黑线。
  4. 我甚至无法使用imagecolorset()来更改图像的颜色。
以下是代码:
if ($isFileString) {
    $src2 = imagecreatefromstring($data);
} else {
    $src2 = imagecreatefromjpeg($data);
}

// This was an attempt to get it to recognize transparent.
if (!unlink ("../drive/sigs/tmp.png"))
    die("Failed to delete tmp.png");

imagepng($src2, "../drive/sigs/tmp.png");
imagedestroy($src2);
$src = imagecreatefrompng("../drive/sigs/tmp.png");

imagealphablending($src, false);
imagesavealpha($src, true);

for ($i=0; $i< 1024; $i++) {
    echo $i;
    echo print_r(imagecolorsforindex($src, $i));
    imagecolorset($src, $i, 255, 255, 255,255);
    echo print_r(imagecolorsforindex($src, $i));
    echo "<BR>";
}

$src = imagecropauto($src, IMG_CROP_WHITE);
$white = imagecolorallocate($src, 255, 255, 255);
imagecolortransparent($src, $white);
$src = imagerotate($src, -90, 0);

编辑 以下是一个例子,说明我无法让imagecolorset()在文件中进行更改,下面是对$i循环的输出:

1Array ( [red] => 0 [green] => 0 [blue] => 1 [alpha] => 0 ) 1Array ( [red] => 0 [green] => 0 [blue] => 1 [alpha] => 0 ) 1
2Array ( [red] => 0 [green] => 0 [blue] => 2 [alpha] => 0 ) 1Array ( [red] => 0 [green] => 0 [blue] => 2 [alpha] => 0 ) 1
3Array ( [red] => 0 [green] => 0 [blue] => 3 [alpha] => 0 ) 1Array ( [red] => 0 [green] => 0 [blue] => 3 [alpha] => 0 ) 1

编辑2

更多信息:我检查了GD版本(php -i | grep -i gd)。我惊讶地发现Ubuntu版本的GD版本为2.1.1-dev,而EC2版本的GD版本为“捆绑(2.1.0兼容)”。我对GD不太熟悉,所以我更倾向于认为这是我的问题,而不是亚马逊提供了一个错误的GD版本。

编辑3

  • 似乎这不是内存问题。 memory_get_peak_usage()报告约为35MB。

  • gd_info()报告的唯一区别是版本号。

1个回答

0

那个版本的GD似乎有一些问题。虽然不是完美的,但这是我们最终确定的代码:

    if ($isFileString) {
        $im1 = imagecreatefromstring($data);
    } else {
        $im1 = imagecreatefromjpeg($data);
    }
    $tmp_file = $this->tmp_dir . md5(time() . mt_rand());
    imagepng($im1, $tmp_file);
    imagedestroy($im1);

    // rotate, pre-resize and resample the source image
    $im2 = imagecreatefrompng($tmp_file);
    unlink($tmp_file);
    if (imagesy($im2) > imagesx($im2))
        $im2 = imagerotate($im2, $this->rotate, 0);
    $width = imagesx($im2);
    $height = imagesy($im2);
    $percent = ($this->standard_width * 2) / $width;
    $newWidth = $width * $percent;
    $newHeight = $height * $percent;
    $im = imagecreatetruecolor($newWidth, $newHeight);
    imagecopyresampled($im, $im2, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height);

    // create a transparent image with a size like $im image
    $im3 = imagecreatetruecolor($newWidth, $newHeight);
    imagesavealpha($im3, TRUE);
    imagefill($im3, 0, 0, imagecolorallocatealpha($im3, 0, 0, 0, 127));

    // find non-white-ish pixels on $im and copy them to $dst
    $sizeX = $newWidth;
    $sizeY = $newHeight;
    $startX = $startY = 100000;
    $finishX = $finishY = 0;
    for ($x = 1; $x < $sizeX - 1; $x++) {
        for ($y = 1; $y < $sizeY - 1; $y++) {
            $rgb = imagecolorat($im, $x, $y);
            $colors = imagecolorsforindex($im, $rgb);
            $r = $colors['red'];
            $g = $colors['green'];
            $b = $colors['blue'];
            if ($r < $this->redLimit && $g < $this->greenLimit && $b < $this->blueLimit) {
                imagesetpixel($im3, $x, $y, $rgb);
                if ($startX > $x) {
                    $startX = $x;
                }
                if ($startY > $y) {
                    $startY = $y;
                }
                if ($finishX < $x)
                    $finishX = $x;
                if ($finishY < $y)
                    $finishY = $y;
            }
        }
    }

    // final resize
    $width = $finishX - $startX + 1;
    $height = $finishY - $startY + 1;
    $percent = $this->standard_width / $width;
    $newWidth = $width * $percent;
    $newHeight = $height * $percent;
    $im4 = imagecreatetruecolor($newWidth, $newHeight);
    imagesavealpha($im4, TRUE);
    imagefill($im4, 0, 0, imagecolorallocatealpha($im4, 0, 0, 0, 127));
    imagecopyresampled($im4, $im3, 0, 0, $startX, $startY, $newWidth, $newHeight, $width, $height);

    // returning image
    ob_start();
    imagepng($im4);
    $image_data = ob_get_contents();
    ob_end_clean();
    return $image_data;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接