2

I'm assuming ImageMagick is the best option for this, but please let me know if you have other recommendations that can be scripted.

I am trying to replace all the 32x32 tiles of an image with a single tile. This is an example for the original image:

Original

This is the tile that I want to use to replace all tiles on the original image:

Placeholder tile

And this is what I want the output to be:

Placeholder image

I've figured out from other posts on Stack Overflow that I can use ImageMagick's composite option to overlay the tile onto the original image:

$ convert original.png tile.png -composite overlay.png

Resulting in the following:

Overlay

And I assume by knowing the original images dimensions I can overlay the tile manually multiple times. But is there a way to automate the process. In the example pictures I have given, I need to overlay the tile 8 times on the original 64x128 image.

How can I do this with ImageMagick or another software? And if ImageMagick, would the montage or composite command be a better option?

Edit: As an additional question, would it be possible to skip tiles that are completely transparent?

Input example:

Original transparent

Output example:

Placeholder transparent

It isn't really important to be able to do this part, but would be nice.

AntumDeluge
  • 490
  • 1
  • 5
  • 13

3 Answers3

3

I don't know why you would need to overlay the 8 tiles on the original. Just create it from scratch and name the output the same as your original

You could use Imagemagick montage to do that (unix syntax):

nx=`convert original.png -format "%[fx:w/32]" info:`
ny=`convert original.png -format "%[fx:h/32]" info:`
num=$((nx*ny-1))
montage tile.png -duplicate $num -tile ${nx}x${ny} -geometry +0+0 result.png


enter image description here

Here I use convert to duplicated the tile, but it uses a relatively current -duplicate feature. If you do not have a current enough version of Imagemagick, then just repeat the tile in montage as follows:

montage Ro1Lp.png Ro1Lp.png Ro1Lp.png Ro1Lp.png Ro1Lp.png Ro1Lp.png Ro1Lp.png Ro1Lp.png -tile 2x8 -geometry +0+0 result.png


fmw42
  • 46,825
  • 10
  • 62
  • 80
  • You are correct, I do not need to "overlay" the original image. But, I have many images of different sizes, all with dimensions that are multiples of 32. This answer does work for me. I just need to get the dimensions of the original image, which can be done with `identify original.png | cut -d " " -f 3`. Then I just need to divide the *x* & *y* values by 32. – AntumDeluge Mar 21 '18 at 05:17
  • I have edited my post to include the computations of the number of tiles. – fmw42 Mar 21 '18 at 16:18
  • I want to thank you very much for this answer. It was hard to decide between yours & GeeMack's, & I implemented both of them into a script. I wish I could choose multiple, because I think this one answers the question just as well. – AntumDeluge Mar 23 '18 at 00:11
  • Can you not up-vote both? I thought that was possible. But perhaps not for the person writing the question. – fmw42 Mar 23 '18 at 02:45
  • Yes, I up-voted both of them. But I can only choose one as *accepted answer*. – AntumDeluge Mar 25 '18 at 00:10
  • Understood. Thanks – fmw42 Mar 25 '18 at 00:30
3

If the tile image fits evenly into the dimensions of the original, a command like this should do most of what you want...

convert original.png tile.png -background none -virtual-pixel tile \
   -set option:distort:viewport %[fx:u.w]x%[fx:u.h] -distort SRT 0 +swap \
   -compose copyopacity -composite overlay.png

That reads in both images. Then it creates another canvas the size of the original and filled with multiple copies of the tile image. Then it uses the original as a transparency mask to create a copy of the new tiled image with the same transparent cells as the original.

GeeMack
  • 4,486
  • 1
  • 7
  • 10
  • I may have done something wrong, but this command gave me two files: "overlay-0.png" & "overlay-1.png". "overlay-0.png appears to be a copy of "tile.png", & "overlay-1.png" is a copy of "original.png". – AntumDeluge Mar 21 '18 at 05:19
  • Okay, I must have done something wrong to begin with, because I copied & pasted your command which had a different output. It still gave me two files, "overlay-0.png" & "overlay-1.png". But this time, "overlay-0.png" had my desired output. Any way to suppress outputting the 2nd file & the addition of the "-0" suffix? – AntumDeluge Mar 21 '18 at 05:22
  • I'm sorry, it appears when I copy/pasted the command I left out a bit of it. I've edited the command now to add "-compose copyopacity -composite" right after the "+swap". Try that, and if it still doesn't do what you want we can try to fix it to to work. – GeeMack Mar 21 '18 at 14:28
  • Thank you very much GeeMack. At first I was a little skeptical that this method didn't completely block out each tile, but rather retained transparency & only covered opaque pixels. But actually, I have decided that this works perfectly for what I want to use it for. – AntumDeluge Mar 23 '18 at 00:13
0

As Fred (fmw42) says, "why don't you just create the whole image from scratch?".

Maybe your description isn't complete, so here are a couple more pieces that might help you work it out.

Given bluetiles.png and singlered.png:

enter image description here enter image description here

you can position red ones as you wish like this:

convert bluetiles.png \
   singlered.png -geometry +0+32  -composite \
   singlered.png -geometry +32+96 -composite result.png

enter image description here


Given bluewithtransparent.png:

enter image description here

you can copy its transparency to the newly-created image like this:

convert bluetiles.png \
   singlered.png -geometry +0+32  -composite \
   singlered.png -geometry +32+96 -composite \
\( bluewithtransparent.png -alpha extract \) -compose copyopacity -composite result.png

enter image description here

Mark Setchell
  • 191,897
  • 31
  • 273
  • 432