サイトの石工コンストラクターを作成する

Sidzheko社は、 Reconstroy組織のサイトをサポートしています。Reconstroy組織は、中央ブラックアース地域でレンガ、タイル、建築装飾品、その他多くの建築材料を販売しています。



このサイトで作業する過程で、石工デザイナーのアイデアが浮上しました。



ドイツの懸念「 Feldhaus Klinker 」には、レンガのモデル範囲「Vascu Mix」と「Sintra Mix」があります。これらは、異なる比率で混合し、独自の石造パターンを作成するために特別に設計されています。 それらには、レンガの間に石積みジョイントをコーティングするときに使用されるクイックミックスパテがいくつかあります。 このアプローチを実証するために、レンガ造りのデザイナーを作成することにしました。RuNetにはまだアナログを見ていません(例を見て喜んでいます)。











描画をできるだけ実物に近づけるために、影や傷がレンガや縫い目に重ねられます。 スイッチはタッチデバイスとして様式化することを決定しました。 何百もの画像がデザイナーのために処理されました:石積み、レンガ、ジョイント用のパテなどの写真



酒に酔ったマスターモード-楽しみ:



 « »







プロセス



デザイナーに写真を残します(実際、そこでの仕事の量はプログラマー側の問題よりもかなり大きいです)、フロントエンドのDimaはクライアント側で美しくして、バックエンドで彼の習得に到達しようとします。



だから...



主な手順



会社の広告資料でしか見つけることができない石造の可能なすべての写真を撮り、写真を追加します。



レンガを切り取り、透明なフィールドで切り取ります。



レンガの画像を1つのサイズにします。 結果が退屈しないように、各モデルから実際の写真が必要です。







仮想石積みは、実際の石積みと同じ順序で構築されていません:-)

そのため、最初にフィールド全体をシーム画像で埋め、それを希望の画像サイズに乗算します。



画像



次に、レンガの層を塗りつぶします。ここでは、線の異なるモデルが正しい比率で混合されます。 偶数行は、奇数行から半分のブリックだけ水平方向にシフトされます。 (ビジネス愛好家のための他の石積みの図面がありますが、これまでは、期限を満たすために古典的なものにとどまることが決定されています。)



画像



停止することも可能ですが、洗練されすぎています。 現実は常に優れています:擦り傷、傷-各ものの外観はその歴史を反映しています。 画像をノイズで人工的に「エージング」する必要があります。



画像の各ピクセルをランダムに変化させるだけでノイズを発生させることができます。 しかし、それは長い間機能しますが、見た目はあまり良くありません。カメラのISOノイズではなく、素材の実際のテクスチャをエミュレートしたいのです。



//  () for ($x = 0; $x < $allWidth; $x++) for ($y = 0; $y < $allHeight; $y++) imagesetpixel($image, $x, $y, imagecolorallocatealpha($image, 0xff, 0xff, 0xff, MyRand::rand(115, 127)));
      
      





ランダムノイズ



さらに興味深い方法で見てみましょう(さらに、画像の生成時間を大幅に節約します)-「スクラッチ」を適用します。



スクラッチは、実際には、ランダムな長さ、傾き、透明度を持つ白と黒の線です。 線の上部が明るく、下部が暗い場合、画像では上部が暗く、下部のライトがスクラッチのように見えます(はい)。



 //   () //    for ($x = 0; $x < 5000; $x++) { $dotX = MyRand::rand(0, $allWidth); $dotY = MyRand::rand(0, $allHeight); $scratchWidth = MyRand::rand(1, 8); // 80% - (+1)  20%  (-1) $scratchAdj = MyRand::rand(0, 10) > 8 ? -1 : +1; for ($i = 0; $i < $scratchWidth; $i++) { imagesetpixel($image, $dotX+$i, $dotY+$scratchAdj, imagecolorallocatealpha($image, 0xff, 0xff, 0xff, MyRand::rand(95, 110))); imagesetpixel($image, $dotX+$i, $dotY, imagecolorallocatealpha($image, 0x00, 0x00, 0x00, MyRand::rand(95, 110))); } }
      
      









ノイズなしで、それらと共に:







著作権を適用することは残っています。 フォントをダウンロードします(Ubuntuが行います)。



 imagettftext($image, 10, 90, $allWidth - 7, $allHeight - 7, imagecolorallocatealpha($image, 0, 0, 0, 90), 'font/ubuntu-r.ttf', 'Sijeko Brick Generator ' . GENERATOR_VERSION);
      
      









できた!



出力コンストラクターはJPEGとPNGの両方を生成できます(すべてのソース画像はPNG24にあります)が、結果のPNGのサイズが大きいため、JPEGに決めました。



キャッシュとURL


同じ入力パラメータを使用してイメージを作成する必要がない2回目は、プロセッサとユーザーを節約します。 最初の使用時にイメージを保存し、後続の呼び出しでキャッシュから発行します。



画像キャッシュの識別子(ファイル名)は、URLのGET部分の変数の順序と同じでなければなりません。 したがって、最初にすべての不要な変数(URLに手動で置き換えることができるキーと値)を削除してから、グローバル$_GET



配列をキーでソートします。



 //   (         ) ksort($_GET);
      
      





次に、残りの識別子を取得します。



 $fileIdentifier = 'images/cache/' . $randSeed; $fileIdentifier .= sprintf( '/lineup-%s_color-%d_drunk-%s_', $lineup, $backFile, $isDrunk ? 'on' : 'off' ); foreach ($_GET as $key => $value) { if (!empty($value)) $fileIdentifier .= preg_replace('/[^a-z0-9_-]/ui', '', $key) . '-' . preg_replace('/[^a-z0-9_-]/ui', '', $value) . '_'; } $fileIdentifier = rtrim($fileIdentifier, '_'); $fileIdentifier .= '.' . OUTPUT_FORMAT;
      
      







キャッシングに関連するHTTPヘッダーを忘れないでください。



 header('Cache-Control: Public'); header('Pragma: Public'); header('Last-Modified: ' . gmdate('D, d MYH:i:s', $time) . ' GMT'); header('Expires: ' . gmdate('D, d MYH:i:s', $time + 30*24*60*60) . ' GMT');
      
      







乱数ジェネレーター


URLの哲学を完全に遵守するためには、各リンクに対して常に同じ画像を表示する必要があります。 しかし、システムには多くのランダムな要素(ノイズ、バンプ)があります。 非常に正確にするには、擬似乱数ジェネレーター(PRNG)ではなく、擬似乱数シーケンスジェネレーター(GPSP)が必要です。 特定の識別子( seed



)で定義された各シーケンスは、一意で反復可能でなければなりません。



PHPの新しいバージョン(≥5.2.1)では、 mt_rand()



ジェネレーターは、 mt_srand($seed)



パラメーターの同じ値に対して同じシーケンスの発行を停止しました(少なくとも、この動作にmt_srand($seed)



ないことをお勧めします)。 自転車を書きましょう。 ジェネレータからの暗号化セキュリティは必要ないため、最も一般的で単純な方法の1つである転送を使用した乗算を使用します。



 /** *        . * @param integer $min * @param integer $max * @return integer */ public static function rand($min = 0, $max = 0xffffffff) { self::$m_z = 36969 * (self::$m_z & 65535) + (self::$m_z >> 16); self::$m_w = 18000 * (self::$m_w & 65535) + (self::$m_w >> 16); $res = ((self::$m_z << 16) + self::$m_w) & 0xffffffff; $res = $res > 0 ? $res : ~$res; //var_dump($res, PHP_INT_MAX, 0xffffffff); die; return intval($min + floor(($res / doubleval(0xffffffff)) * ($max - $min + 1))); }
      
      





ここで、 self::$m_z



およびself::$m_w



は、ジェネレーターの現在の状態の静的フィールドです。 self::$m_z



self::$m_w



の同じ与えられたセットでself::$m_w



ジェネレータは整数の同じ擬似乱数シーケンスを生成します。



酔ったマスターモード


狭い傾斜範囲でランダムな角度で各レンガを回してみましょう。酔ったマスターはすでにあなたの壁で作業しています。



傾斜範囲を度単位で変えることで、飲み物の量と程度を変えることができます(しゃれはごめんなさい)。 ±3.2°で停止しました。



参照資料






All Articles