正方形から六角形へのシームレスな変換


23

グリッドでプレイされる多くのゲームでは、六角形がClearly Superior Choice™です。残念ながら、多くの無料ゲームアートサイトには、正方形のマップ用のシームレスなタイルセットしかありません。過去のプロジェクトで、これらのいくつかを使用して、手動で六角形に変換しました。

しかし、私は老後は怠け者になりました。小さなスクリプトでプロセスを簡単に自動化できるはずです。

しかし、私は老後は怠け者になりました。だから私はあなたにそれをアウトソーシングし、コードゴルフチャレンジ1としてそれを偽装しています。


入力

入力は、24ビットRGBカラーが可能な一般的な画像形式の正方形の画像です。画像データ自体の代わりに、入力としてファイル名を使用することもできます。

画像が正方形で、辺の長さが4の倍数であると仮定できます。

出力

出力は入力タイルですが、六角形に変換されます(画像自体は透明な領域のある正方形になります)。ファイルに保存したり、画面に表示したりできます。

繰り返しになりますが、一般的な画像形式ならどれでもかまいません。使用している形式が透明度をサポートしている場合、背景領域は透明でなければなりません。そうでない場合は、代役として色#FF00FF(恐ろしいフクシアの1つ)を使用できます。

方法

それではどうすればいいのでしょうか?私が2つ使用する方法は、画像を少し垂直に押しつぶしますが、全体的にはほとんどの場合にかなり良く見えます。この入力画像を使用して例を示します。

入力

  • 拡大縮小:画像を3:2の比率に拡大縮小します。画像は正方形になるため、幅75%、高さ50%に拡大縮小するだけです。入力例は200x200なので、この150x100の画像になります。

つぶした

  • タイル:スケーリングされた画像のコピーを2x2グリッドに配置します。

グリッド

  • 切り抜き:この2x2グリッドの任意の場所から適切なサイズの六角形を取得します。さて、タイリングを簡単にするために、この六角形は厳密には規則的ではありません。元のサイズの正方形(ここでは200x200)をトリミングした後、コーナーをトリミングします。切り取り線は、(おおよそ)左右の各辺の中央から上/下の端から4分の1の位置まで伸びる必要があります。

ヘックス

それがあなたの出力です!

以下は、タイル表示されたときの外観の例です(ここで拡大表示されています)。

タイル張り

これはコードゴルフであるため、バイト単位の最短コードが優先されます。標準的な抜け穴などが適用されます。


1これを信じても信じなくても構いません。
2 この役立つサイトの方法1


13
この質問は、六角形の答えを求めています。
Sanchises

22
@sanchises頑張ってください。
マーティンエンダー

17
そこで、Hex Agonyの 2番目の部分が重要になります。
flawr

2
@ mbomb007おそらく、代わりにときどき使用される#00FF00グリーンはそれほど悪くないでしょう。それでも、彼らの右心の誰もがスプライトその正確な色を望んでいないので、彼らはフクシアをより頻繁に使用しているように感じます、それでかなり普遍的です:P
Geobits

3
#3-生成されたクールなアルゴリズムが表示されるまで辛抱強く待ちます...それから優しく、愛情を込めてそれらを私の使用のために「借りる」
;

回答:


10

MATLAB、223の215 209 184 163バイト

再スケーリングは非常に簡単です。角を切り取るために、ピクセルの上に座標系を重ね、六角形の面積を決定する4つの線形不等式を介してマスクを作成します。

​l=imread(input(''));
u=size(l,1);
L=imresize(l,u*[2 3]/4);
L=[L,L;L,L];L=L(1:u,1:u,:);
[x,y]=meshgrid(1:u);
r=u/2;x=x*2;
set(imshow(L),'Al',y<x+r&y+x>r&y+x<5*r&y>x-3*r)

ここに画像の説明を入力してください

PS:これは@MartinBüttnerの投稿でcodegolf nimゲームに変わりました:交互にコードを短くする必要があります(同じ機能を提供しながら)-最後の「短縮」の勝利を得ることができるもの=)


サイズ変更の計算をに変更すると、5バイト節約できます[k.*[2 3]/4]
ビーカー

4
背景領域は黒ではなくフクシアであるべきではありませんか?
ブラックホール

@Blackhole私に知らせてくれてありがとう、私は今それを修正し、バイトをかなり節約しました=)
flawr

12

Mathematicaの、231の 211 209 208 201 188 173バイト

ImageCrop[ImageCollage@{#,#,#,#},e,Left]~SetAlphaChannel~ColorNegate@Graphics[RegularPolygon@6,ImageSize->1.05e,AspectRatio->1]&@ImageResize[#,{3,2}(e=ImageDimensions@#)/4]&

これは、画像オブジェクトを受け取り、画像オブジェクトを返す名前のない関数です。

ここに画像の説明を入力してください

ここで説明することは多くないと思いますが、注意すべき詳細がいくつかあります。

  • 通常、2x2の画像をタイルするには、を使用しますImageAssemble[{{#,#},{#,#}}]。つまりImageAssemble、2x2のマトリックスに画像のコピーを渡します。ただし、ImageCollage写真の束を可能な限り「うまく」配置しようとする何らかの魔法の機能があります(つまり、個々の画像に重みやものを与えることもできます)。とにかく、同じサイズで同じウェイト(またはウェイトなし)の4つのイメージを指定すると、2x2グリッドに配置されます。これにより、関数の名前と同様に、マトリックスのネスト用にいくつかのバイトを保存できます。
  • 六角形はを介して単一の多角形としてレンダリングされGraphicsます。私はビルトインを使用していますが、必要に応じてRegularPolygon@6アスペクト比を適用1してストレッチします。残念ながら、Graphicsパディングなどを避けるためにいくつかの高価なオプションが必要です。また、反対の代わりに白に黒をレンダリングします。結果はで修正さColorNegateれ、で画像の元のチャンネルに添付されますSetAlphaChannel
  • Graphics六角形の周りに少量のパディングを配置しますが、カットアウトのフルサイズをアルファ六角形でカバーしたいです。ただし、SetAlphaChannel異なるサイズの画像を重ね合わせるには、画像を互いの中央に配置し、最小サイズにトリミングします。つまり、手動で設定する代わりにPlotRangePadding->0、六角形の画像を少し拡大するだけで済みImageSize->1.05eます(とにかく `ImageSizeオプションが必要です)。

5

HTML5 + Javascript、562バイト

<html><form><input type=text></form><canvas><script>l=document.body.children;l[0].addEventListener("submit",e=>{e.preventDefault();c=l[1].getContext("2d");i=new Image();i.onload=q=>{l[1].width=l[1].height=d=i.width;c.scale(0.75,0.5);c.drawImage(i,0,0);c.drawImage(i,d,0);c.drawImage(i,0,d);c.drawImage(i,d,d);c.globalCompositeOperation="destination-in";c.scale(1/0.75,2);c.beginPath();c.moveTo(d/4,0);c.lineTo(d/4+d/2,0);c.lineTo(d, d/2);c.lineTo(d/4+d/2, d);c.lineTo(d/4, d);c.lineTo(0, d/2);c.closePath();c.fill();};i.src=e.target.children[0].value;})</script>

テキストボックスを介して画像URLとして入力を受け取ります(URLはファイル名としてカウントされることが望ましい)。データをキャンバスに出力します。

すべてのブラウザーで機能するバージョン(580バイト):

<html><form><input type=text></form><canvas><script>l=document.body.children;l[0].addEventListener("submit",function(e){e.preventDefault();c=l[1].getContext("2d");i=new Image();i.onload=function(){l[1].width=l[1].height=d=i.width;c.scale(0.75,0.5);c.drawImage(i,0,0);c.drawImage(i,d,0);c.drawImage(i,0,d);c.drawImage(i,d,d);c.globalCompositeOperation = "destination-in";c.scale(1/0.75,2);c.beginPath();c.moveTo(d/4, 0);c.lineTo(d/4+d/2,0);c.lineTo(d, d/2);c.lineTo(d/4+d/2, d);c.lineTo(d/4, d);c.lineTo(0, d/2);c.closePath();c.fill();};i.src=e.target.children[0].value;})</script>

次のURLから以前の「ブロック」イメージでテストします:http : //i.stack.imgur.com/gQAZh.png


よくやった!あなたは追加することによって、かなりの数のバイトを救うことができるid=A<form>してid=Bまで<canvas>、その後、交換l[0]してAl[1]してB、削除しますl=document.body.children;。(Firefox 41で動作します。他のどのブラウザがこれをサポートしているかはわかりません。)また、右中括弧の横に不要なセミコロンがいくつかあり、いくつかの余分なスペースがあると思います。
ETHproductions

その他のヒント:私はあなたが追加することができます信じているid=C<input>し、交換してくださいe.target.children[0]C0.75等しい3/41/0.75等しい4/3d/4+d/2等しいd*3/4、その他の小数の先行ゼロは必要ありません。また、最初のものc.drawImagec[p="drawImage"]に置き換え、その後のすべてのものをに置き換えることができると信じていますc[p]。あなたも同じことができますc.lineTo
ETHproductions

4

Python 2 + PIL、320

stdinから画像ファイルの名前を読み取ります。

from PIL import ImageDraw as D,Image as I
i=I.open(raw_input())
C=A,B=i.size
i,j=i.resize((int(.75*A),B/2)),I.new('RGBA',C)
W,H=i.size
for a,b in[(0,0),(0,H),(W,0),(W,H)]:j.paste(i,(a,b,a+W,b+H))
p,d=[(0,0),(A/4,0),(0,B/2),(A/4,B),(0,B)],lambda p:D.Draw(j).polygon(p,fill=(0,)*4)
d(p)
d([(A-x,B-y)for x,y in p])
j.show()

確かに、それについてPILすみませんが、試してみるのに手間がかかりませんでしたし、十分に考えていませんでした。しかし、私はまだ改行文を支持しています:P
FryAmTheEggman

2

PHP、293バイト

読みやすくするためにいくつかの改行を追加しました。

function($t){$s=imagesx($t);imagesettile($i=imagecreatetruecolor($s,$s),$t=imagescale
($t,$a=$s*3/4,$b=$s/2));imagefill($i,0,0,IMG_COLOR_TILED);$z=imagefilledpolygon;$z($i,
[0,0,$s/4,0,0,$b,$s/4,$s,0,$s],5,$f=imagecolorallocate($i,255,0,255));$z($i,[$s,0,$a,
0,$s,$b,$a,$s,$s,$s],5,$f);return$i;}

以下は、バージョン化されていないバージョンです。

function squareToHexagon($squareImage)
{
    $size = imagesx($squareImage);
    $tileImage = imagescale($squareImage, $size * 3/4, $size/2);

    $hexagonImage = imagecreatetruecolor($size, $size);
    imagesettile($hexagonImage, $tileImage);
    imagefill($hexagonImage, 0, 0, IMG_COLOR_TILED);

    $fuchsia = imagecolorallocate($hexagonImage, 255, 0, 255);
    imagefilledpolygon(
        $hexagonImage,
        [
            0,       0,
            $size/4, 0,
            0,       $size/2,
            $size/4, $size,
            0,       $size,
        ],
        5,
        $fuchsia
    );
    imagefilledpolygon(
        $hexagonImage,
        [
            $size,       0,
            $size * 3/4, 0,
            $size,       $size/2,
            $size * 3/4, $size,
            $size,       $size,
        ],
        5,
        $fuchsia
    );

    return $hexagonImage;
}

header('Content-type: image/gif');
$squareImage = imagecreatefrompng('squareImage.png');
$hexagonImage = squareToHexagon($squareImage);
imagegif($hexagonImage);
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.