1

我已经在这个项目上工作了好几天,由于某种原因,我无法摆脱在处理的每个图块中出现的意外 1px x 1px(大约)白点。

概括:

我正在使用原始图像(例如 original.jpeg )作为参考,通过合并更小的 jpeg 图像(大约 10 像素 x 10 像素)来创建马赛克图像(例如,mosaic.jpeg,大约 1000 像素 x 1000 像素)。

我有大约 20,000 张平铺图像的数据集可供使用。

到目前为止的过程

  1. 我已经映射了 original.jpeg 图像以将其切割成 5 x 5 像素的图块,然后找到每个图块的平均颜色并将其保存以供进一步使用。
  2. 我已经扫描了所有 (10x10) 平铺图像并存储了它们各自的平均颜色。
  3. 我已经通过使用加权参考计算出哪个平铺图像最适合原始图像的哪个平铺:距所提及站点的欧几里得距离
  4. 我设法使用 PHP gd 库创建了一个新的真彩色图像,所有匹配的瓷砖都放置在正确的位置(从而有效地创建了 original.jpeg 图像的马赛克)

问题

我没有得到我预期的清晰马赛克,由于某种原因瓷砖不匹配。

解决方法

现在由于时间不够,我使用了一个快速修复方法,在我拍摄原始图像的地方,给它一些 50% 的不透明度,并在将其放入最终马赛克时将其覆盖在每个图块的顶部。

注意:虽然我有效地将原始图像覆盖在马赛克图像上,但我并没有一次性完成。覆盖必须发生在每个图块级别。

简而言之:在将每个图块放置在最终马赛克的正确位置之前,我执行以下操作 1. 获取原始图像的特定部分 (5x5px) 2. 将其扩展以匹配最终图块大小 (10x10px) 3. 设置部分的透明度 4. 将其放在将要放置的瓷砖上 5. 将此新瓷砖合并到相应位置的最终马赛克上。

这是我创建的功能,用于覆盖图像的一部分以及为其设置的透明度。

public function overlay($dImg, $sImg, $opacity = null) {

    // set default Opacity if not specified
    $opacity = (is_null($opacity)) ? $this->opacity : $opacity;

    // get width, height of sourceImage
    $sWidth = imagesx($sImg);
    $sHeight = imagesy($sImg);

    // get width height of final image
    $dWidth = imagesx($dImg);
    $dHeight = imagesy($dImg);

    $image = imagecreatetruecolor($dWidth, $dHeight);
    imagecopyresampled($image, $sImg, 0, 0, 0, 0, $dWidth, $dHeight, $sWidth, $sHeight);

    $background = imagecolorallocatealpha($image, 255, 255, 255, 127);        
    imagefill($image, 0, 0, $background);

    imagealphablending($image, true);

    imagecopymerge($dImg, $image, 0, 0, 0, 0, $dWidth, $dHeight, $opacity);

    imagedestroy($image);

    return $dImg;
}

真正的问题

从理论上讲,这一切似乎都很好。但结果对此事有自己的发言权。

我注意到在最终马赛克的每一块瓷砖的开头都有一个不寻常的几乎 1x1 像素的白色补丁。

只有在应用上述透明度技术时,才会出现此白色补丁。否则不会发生。

我不知道为什么会发生这种情况,由于这个白色补丁,整个图像看起来像是到处都是白噪声,并且极大地降低了整体质量。

请指导我了解为什么会发生这样的事情。

4

1 回答 1

1

你的问题在于这两行:

$background = imagecolorallocatealpha($image, 255, 255, 255, 127);        
imagefill($image, 0, 0, $background);

您不需要这些,因为 imagefill 用于填充具有相同/相似颜色的区域与位于提供的坐标上的颜色,在您的情况下为 0, 0(左上角),当没有相邻的相似颜色时,然后它只是改变给定坐标的颜色。

您可以改用imagefilledrectangle,但我仍然认为您不需要,只需注释掉这两行并查看结果是否符合您的要求,如果不符合,请继续使用imagefilledrectangle

图像填充矩形

于 2013-02-02T16:08:11.487 回答