Split images into tiles

Questions and postings pertaining to the usage of ImageMagick regardless of the interface. This includes the command-line utilities, as well as the C and C++ APIs. Usage questions are like "How do I use ImageMagick to create drop shadows?".
khavish
Posts: 12
Joined: 2017-10-27T07:37:54-07:00
Authentication code: 1151

Split images into tiles

Post by khavish »

I want to split any image into 64x64 tiles and then i need to join the tiles together to form the original image again.
The following from the docs work but how can i get the correct values for -tile parameter automatically.I intend to do this in a bash script later.
convert rose: -crop 20x20 +repage +adjoin rose_tiles_%02d.gif
montage -mode concatenate -tile 4x rose_tiles_*.gif rose_rejoined.gif
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Split images into tiles

Post by snibgo »

I would do that like this:

Code: Select all

convert rose: -crop 20x20 +adjoin rose_tiles_%02d.gif

convert rose_tiles_*.gif -layers merge out.png
Note: there is no "+repage", so rose_tiles_*.gif contains the offsets, which "-layers merge" uses. The intermediate files could be PNG.
snibgo's IM pages: im.snibgo.com
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Split images into tiles

Post by fmw42 »

Leave off the +repage so that you do not throw away the virtual canvas. Then use -layers merge or -layers flatten to recombine.

Code: Select all

convert rose: -crop 20x20 +adjoin rose_tiles_%02d.gif
convert rose_tiles_*.gif -layers merge new_rose.gif
EDIT: Sorry snibgo, we were composing messages at the same time.

P.S. See http://www.imagemagick.org/Usage/layers/#layers
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Split images into tiles

Post by snibgo »

Ha! Our brains seem to synchronize, sometimes.
snibgo's IM pages: im.snibgo.com
khavish
Posts: 12
Joined: 2017-10-27T07:37:54-07:00
Authentication code: 1151

Re: Split images into tiles

Post by khavish »

Thanks a lot for your fast reply guys.
@snibgo
If i modify the image in some way , like a compression for example , then i will lose the offset.I want to be able to rejoin the tiles together later on irrespective of the manipulation i make with the image.

Thanks again for the help guys
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Split images into tiles

Post by fmw42 »

What command are you using to modify the image? What format are you saving the new output. Only some formats store the virtual canvas offsets, PNG, TIFF, MIFF, GIF. JPG does not. So if you are trying to change compression and saving as JPG, then it won't go back together. If you want to do that and have the reconstructed image as JPG, then save all your intermediate images as .miff

Please post your full set of commands so we can see what you are trying to do. The virtual canvas offsets should be saved If you are not distorting the image and just doing compression changes.
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Split images into tiles

Post by snibgo »

khavish wrote:If i modify the image in some way , like a compression for example , then i will lose the offset.
GIF is compressed. Worse, the compression is lossy, in the sense that it uses only 256 colours. If your input image has only 256 colours, that's not a problem.

What processing are you doing to the tiles? Perhaps you don't need to save them as files at all, but can do the whole job in a single command.
snibgo's IM pages: im.snibgo.com
khavish
Posts: 12
Joined: 2017-10-27T07:37:54-07:00
Authentication code: 1151

Re: Split images into tiles

Post by khavish »

JPG is what i am exactly trying to do.The filenames could be used to store the offset?

convert bench.png -crop 64x64 +adjoin bench.png_guetzli_%02d.png
parallel --will-cite 'guetzli --nomemlimit --quality 100 bench.png_guetzli_$(printf %02d {1}).png bench.png_guetzli_$(printf %02d {1}).jpg' ::: $(seq 0 79)
convert bench.png_guetzli_*.jpg -layers merge bench_q100_rejoined.jpg
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Split images into tiles

Post by snibgo »

What does that "parallel" command do? I guess it reads your PNG files and makes JPEGs. Why?

Then you use "convert" to read those JPEGs, merging them into a single JPEG.

JPEG compression is lossy, which means it mangles pixels. Don't do it unless you really need to. Never use JPEG as an intermediate format.
snibgo's IM pages: im.snibgo.com
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Split images into tiles

Post by fmw42 »

Once you have jpg files, you lose the virtual offset. If you save the virtual offsets in the filenames, then you would have to parse the filenames and use -set page +X+Y with each input jpg to put them back into the correct place. So for example:

Input:
Image

Code: Select all

convert lena.png -crop 50x50% lena_%d.png
for ((i=0; i<4; i++)); do
convert lena_$i.png -quality 80 lena_$i.jpg
done
convert \
\( lena_0.jpg -set page +0+0 \) \
\( lena_1.jpg -set page +128+0 \) \
\( lena_2.jpg -set page +0+128 \) \
\( lena_3.jpg -set page +128+128 \) \
-layers merge lena_new.jpg
Image

I will leave it to you to label the jpg images with the offset and to parse the names to get the offsets to use with -set page.

But if all you want to do is change the compression, you might as well just do that on the final output, keeping the intermediates in GIF or PNG or TIFF or MIFF.
khavish
Posts: 12
Joined: 2017-10-27T07:37:54-07:00
Authentication code: 1151

Re: Split images into tiles

Post by khavish »

@snibgo
GNU parallel helps to make use of all cores.

Here is the situation.
Guetzli is very slow JPEG decoder

I am trying to split a PNG into small tiles and then convert them to JPEG with Guetzli.Then i want to join the JPEG tiles together to get the full JPEG compressed image.Small images are ok for guetzli to process

I am aware that JPEG is lossy but am supposing that the merge here is just arranging the tiles next to each other so it shouldn't be too bad.I will use psychovisual methods to check the loss of quality later.
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Split images into tiles

Post by fmw42 »

OK. Here is a way to do that scripting with Unix.

# crop and save offsets in filename

Code: Select all

convert lena.png -crop 50x50% lena_%d.png
num=`convert lena_*.png -format "%n\n" info: | tail -n 1`
for ((i=0; I<num; i++)); do
offset=`convert lena_$i.png -format "%X%Y" info:`
convert lena_$i.png -quality 80 lena_${i}_${offset}.jpg
done

# extract the offsets from the filename
# create list of filenames with -set page offset
# process list to merge the files again

Code: Select all

list=""
for ((i=0; I<$num; i++)); do
offset=`echo lena_${i}_*.jpg | sed -n 's/^lena.*[+]\(.*\)[+]\(.*\).jpg$/+\1+\2/p'`
echo "$i $offset"
list="$list ( lena_${i}_${offset}.jpg -set page $offset )"
done
convert $list -layers merge lena_new.jpg
khavish
Posts: 12
Joined: 2017-10-27T07:37:54-07:00
Authentication code: 1151

Re: Split images into tiles

Post by khavish »

@fmw42
Thanks for the great script snippets

I have a two part question

-For cropping and saving offsets parts
1.I could just count the number of images produced to know the value for the loop . Is there a cool one liner way to do it just after the convert
-For merge process
2.I need minimum quality loss while merging the JPEG tiles.Is convert -quality 100% the optimum way here or montage would be better as we just need to snitch the JPEG tiles together here

Basically i want a lena_new.jpg that is as close as

Code: Select all

convert lena.png -quality 80 lena_direct_convert.jpg
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Split images into tiles

Post by fmw42 »

1) I edited my post above to include

num=`convert lena_*.png -format "%n\n" info: | tail -n 1`
where in my case num=4

See http://www.imagemagick.org/script/escape.php


2) Montage will also degrade the quality. Adding -quality 100 will still change the quality.

If you name your files in the correct order with leading zeros, then you can simply montage them if you know the tile arrangement. But that would only work easily if the image is square. That way you can take sqrt(num) for the number of row and columns in -tile RxC.

Or you could precompute how many rows and columns you will get by dividing the input dimensions by your crop dimensions. Then you could just montage with -tile RxC.

Or you could use my script, overlay-crop, with zero overlap and label them in matrix format. Then parse the labels of the last image to find how many rows and column. Then use montage to combine together again. See my scripts at my link below.
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Split images into tiles

Post by fmw42 »

P.S. If you, say, use -quality 80 to make the jpg images, then if you add -quality 100, you will get as close visual quality as you had before, but the file size will increase dramatically. So you probably want to make the new combined result have a similar or slightly larger quality than 80, but not 100. Each time you compress and decompress with JPG, you lose some visual quality. You cannot get that back. You would be better keeping your intermediate images in non-lossy compressed form, such as tif with lzw compression or png.
Post Reply