Conversion transparente du carré à l'hexagone

23

Pour de nombreux jeux joués sur une grille, les hexagones sont le Clearly Superior Choice ™. Malheureusement, de nombreux sites d'art de jeux gratuits n'ont que des ensembles de tuiles sans couture pour les cartes carrées. Lors d'un projet précédent, j'ai utilisé certains d'entre eux et les ai convertis manuellement en hexagones.

Cependant , je suis devenu paresseux dans ma vieillesse. Il devrait être facile d'automatiser le processus avec un petit script.

Cependant , je suis devenu paresseux dans ma vieillesse. Je vous l'externalise et je le déguise en défi de golf de code 1 .


Contribution

L'entrée est une image carrée dans n'importe quel format d'image courant capable de couleur RVB 24 bits. Vous pouvez également prendre un nom de fichier en entrée au lieu des données d'image elles-mêmes.

Vous pouvez supposer que l'image est carrée et que la longueur du côté est un multiple de quatre.

Sortie

La sortie est la tuile d'entrée, mais convertie en hexagone (l'image elle-même sera carrée, avec des zones transparentes). Vous pouvez l'enregistrer dans un fichier ou l'afficher à l'écran.

Encore une fois, n'importe quel format d'image courant fera l'affaire. Si le format que vous utilisez prend en charge la transparence, les zones d'arrière-plan doivent être transparentes. Si ce n'est pas le cas, vous pouvez utiliser la couleur # FF00FF (cette horrible couleur fuchsia) comme stand-in.

Méthode

Alors comment le fait-on? La méthode que j'utilise 2 écrase l'image un peu verticalement, mais dans l'ensemble, elle semble assez bonne pour la plupart des choses. Nous allons faire un exemple avec cette image d'entrée:

contribution

  • Échelle: redimensionne l'image à un rapport de 3: 2. Puisque nos images seront des carrés, cela signifie que vous les redimensionnez simplement à 75% de largeur et 50% de hauteur. Notre exemple d'entrée est 200x200, nous nous retrouvons donc avec cette image 150x100:

écrasé

  • Mosaïque: placez des copies de votre image à l'échelle dans une grille 2x2:

la grille

  • Crop: prenez un hexagone de taille appropriée de n'importe où dans cette grille 2x2. Maintenant, pour faciliter le carrelage, cet hexagone n'est pas exactement régulier. Après avoir recadré un carré de la taille d'origine (ici 200x200), vous recadrez ensuite les coins. Les lignes de recadrage doivent s'étendre (à peu près) du centre de chaque côté gauche / droit à un quart du bord en haut / en bas:

hex

Et c'est votre sortie!

Voici un exemple de ce à quoi cela pourrait ressembler une fois carrelé (zoomé ici):

carrelé

C'est le golf de code, donc le code le plus court en octets gagne. Des échappatoires standard s'appliquent, etc., etc.


1 N'hésitez pas à le croire ou non.
2 Méthode 1 de ce site utile.

Géobits
la source
13
Cette question est mendie une réponse Hexagony.
Sanchises
22
@sanchises Bonne chance.
Martin Ender
17
C'est là que la deuxième partie de Hex Agony devient importante.
flawr
2
@ mbomb007 Probablement, bien que le vert # 00FF00 qui est parfois utilisé à la place ne soit pas si mauvais. Pourtant, j'ai l'impression qu'ils utilisent le fuchsia plus souvent parce que personne
sensé
3
# 3 - J'attends patiemment cela pour voir les algorithmes
géniaux

Réponses:

10

Matlab, 223 215 209 184 163 octets

Le rééchelonnement est assez simple. Pour recadrer les coins, je superpose un système de coordonnées sur les pixels et crée un masque via quatre inégalités linéaires, qui déterminent la zone de l'hexagone.

​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)

entrez la description de l'image ici

PS: Cela s'est transformé en un jeu de codegolf nim avec la soumission de @ MartinBüttner: Vous devez alternativement raccourcir votre code (tout en fournissant les mêmes fonctionnalités) - celui qui peut faire gagner le dernier `` raccourcissement '' =)

flawr
la source
Vous pouvez économiser 5 octets en remplaçant le calcul de l'échelle de redimensionnement par [k.*[2 3]/4].
bécher
4
Les zones d'arrière-plan ne devraient-elles pas être fuchsia, pas noires?
Blackhole
@Blackhole Merci de m'avoir prévenu, je l'ai corrigé maintenant, m'a même sauvé pas mal d'octets =)
flawr
12

Mathematica, 231 211 209 208 201 201 188 173 octets

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

Il s'agit d'une fonction sans nom qui prend un objet image et renvoie un objet image:

entrez la description de l'image ici

Je ne pense pas qu'il y ait beaucoup à expliquer ici, mais quelques détails qui sont à noter:

  • Normalement, pour carreler une image 2x2, vous utiliseriez ImageAssemble[{{#,#},{#,#}}], c.-à-d.ImageAssemble une matrice 2x2 avec des copies de l'image. Cependant, il y a ImageCollageune sorte de fonction magique qui essaie d'organiser un tas d'images aussi bien que possible (quoi que cela signifie ... vous pouvez même donner des poids et des trucs aux images individuelles). Quoi qu'il en soit, si vous lui donnez quatre images de taille égale et avec des poids égaux (ou aucun), il les organisera également dans une grille 2x2. Cela me permet de sauvegarder quelques octets pour l'imbrication de la matrice, ainsi que le nom de la fonction.
  • L'hexagone est rendu comme un seul polygone via Graphics. J'utilise la fonction intégrée RegularPolygon@6, mais applique un rapport d'aspect de 1pour l'étirer si nécessaire. Malheureusement, il a Graphicsbesoin de quelques options coûteuses pour éviter le rembourrage et autres, et il rend également le noir sur blanc au lieu du contraire. Le résultat est fixé avec ColorNegatepuis attaché aux canaux d'origine de l'image avec SetAlphaChannel.
  • Graphicsmet une petite quantité de rembourrage autour de l'hexagone, mais nous voulons que l'hexagone alpha couvre toute la taille de la découpe. cependant,SetAlphaChannel peut combiner des images de différentes tailles, en les centrant les unes sur les autres et en les recadrant à la plus petite taille. Cela signifie qu'au lieu de définir manuellement PlotRangePadding->0, nous pouvons simplement augmenter un peu l'image hexagonale avec ImageSize->1.05e(et nous avons quand même besoin de l'option `ImageSize).
Martin Ender
la source
5

HTML5 + Javascript, 562 octets

<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>

Prend la saisie comme URL d'image via la zone de texte (l'URL, espérons-le, compte comme nom de fichier). Sort les données sur le canevas.

Version qui fonctionne sur tous les navigateurs (580 octets):

<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>

Testez-le avec l'image "blocs" antérieure via cette URL: http://i.stack.imgur.com/gQAZh.png

adroitwhiz
la source
Bon travail! Vous pouvez économiser plusieurs octets en ajoutant id=Aà <form>et id=Bà <canvas>, puis en remplaçant l[0]par Aet l[1]avec Bet en supprimant l=document.body.children;. (Fonctionne dans Firefox 41; je ne sais pas quels autres navigateurs prennent en charge cela.) De plus, je pense qu'il y a quelques points-virgules inutiles à côté des crochets droits et quelques espaces supplémentaires.
ETHproductions
Plus de conseils: je pense que vous pouvez ajouter id=Cà <input>, puis remplacer e.target.children[0]par C. 0.75est égal à 3/4, 1/0.75est égal à 4/3, d/4+d/2est égal à d*3/4et les zéros non significatifs sur les autres décimales ne sont pas nécessaires. Je crois également que vous pourriez remplacer le premier c.drawImagepar c[p="drawImage"], puis tous les suivants par c[p]; vous pourriez faire de même avec c.lineTo.
ETHproductions
4

Python 2 + PIL, 320

Lit le nom du fichier image depuis 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()
diète
la source
C'est vrai, désolé pour ça, PILje n'avais pas à portée de main pour essayer et je n'y pensais pas assez. Je maintiens cependant ma déclaration de nouvelle ligne: P
FryAmTheEggman
2

PHP, 293 octets

J'ai ajouté quelques nouvelles lignes pour la lisibilité:

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;}

Voici la version non golfée:

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);
Trou noir
la source