1

私はこのプロジェクトに何日も取り組んできましたが、何らかの理由で、処理されるすべてのタイルに現れる予期しない 1 ピクセル x 1 ピクセル (約) の白いスポットを取り除くことができません。

概要:

元の画像 ( original.jpeg など) を参照として使用して、はるかに小さい jpeg 画像 (約 10px x 10px) をマージしてモザイク画像 (約 1000px x 1000px の mosaic.jpeg など) を作成しています。

作業するタイル画像が約 20,000 個あるデータ セットがあります。

ここまでの流れ

  1. original.jpeg 画像をマッピングして 5px x 5px のタイルにカットし、各タイルの平均色を見つけて、後で使用するために保存しました。
  2. すべての (10x10) タイル画像をスキャンし、個々の平均色も保存しました。
  3. Weighted ref :上記のサイトからのユークリッド距離を使用して、どのタイル画像が元の画像のどのタイルに最も近いかを計算しました。
  4. PHP gd ライブラリを使用して、一致するすべてのタイルが正しい位置に配置された新しいトゥルーカラー画像を作成することができました (したがって、オリジナルの .jpeg 画像のモザイクを効果的に作成します)。

問題

タイルが適切に一致しないため、期待していた明確なモザイクが得られません。

回避策

時間がないため、元の画像を取得して 50% の不透明度を指定し、最終的なモザイクに配置するときに各タイルの上にオーバーレイする簡単な修正を使用しています。

注: 元の画像をモザイク画像の上に効果的にオーバーレイしていますが、一度に行っているわけではありません。オーバーレイは各タイル レベルで発生する必要があります。

要するに: 各タイルを最終的なモザイクの正しい位置に配置する前に、次のことを行います。セクションの透明度 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

問題は次の 2 行にあります。

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

imagefill は、提供された座標にある色と同じ/類似の色を持つ領域を塗りつぶすために使用されるため、それらは必要ありません。あなたの場合は 0, 0 (左上) で、隣接する類似の色がない場合は、指定された座標の色を変更するだけです。

代わりにimagefilledrectangleを使用できますが、それでも必要ないと思います。これらの 2 行をコメントアウトして、要件に一致する場合は結果を確認し、そうでない場合はimagefilledrectangleを使用してください。

imagefilledrectangle

于 2013-02-02T16:08:11.487 に答える