Extracting the nth adjacent sub-image ("undoing an +append")
Posted: 2015-12-12T06:59:13-07:00
Consider an input image that was created by horizontally appending three opaque rectangular images on a transparent background, for example:
The problem
Given an image like that, and an integer n, what's the best automated way to extract the nth original image and save it as a new file?
E.g. given the image shown above and the number 2, the result image would be:
(i.e. identical to the one that would be generated by "convert rose: result.png")
The sizes of the sub-images are not known up-front, but the following assumptions can be made:
So far, my best idea for solving this is to use "-scale" to vertically average the image to a single pixel row, and then take the alpha channel of that and output it as a raw text stream:
This outputs one line per pixel in our row, looking like this:
Then I could use an Awk/Perl/shell script to filter out the lines which have a different color value than their preceding line... The first numbers of those filtered lines would correspond to the x coordinates of the sub-images.
If x is the nth coordinate and w is the difference between the (n+1)th and nth coordinate, I could then extract the wanted sub-image like this:
(The "-crop" operation would extract the correct column, and "-bordercolor Transparent -border 1x1 -trim" would remove the transparent area below the sub-image.)
Question
Would this be a good way to do it? Is there a better (faster/simpler/safer) approach?
In particular, is it possible to do everything in a single 'convert' call, without a shell script?
(I'm using ImageMagick 6.9.2-6 Q16 x86_64 2015-11-23)
Code: Select all
convert \( logo: -resize 35% \) rose: granite: -background Transparent -gravity North +append input.png
The problem
Given an image like that, and an integer n, what's the best automated way to extract the nth original image and save it as a new file?
E.g. given the image shown above and the number 2, the result image would be:
(i.e. identical to the one that would be generated by "convert rose: result.png")
The sizes of the sub-images are not known up-front, but the following assumptions can be made:
- All sub-images are rectangular and fully opaque.
- All sub-images have different heights, and are aligned to the top of the input image.
- All pixels which are not part of a sub-image are fully transparent.
So far, my best idea for solving this is to use "-scale" to vertically average the image to a single pixel row, and then take the alpha channel of that and output it as a raw text stream:
Code: Select all
convert input.png -scale 'x1!' -alpha extract txt:-
Code: Select all
...
4,0: (17944.1,17944.1,17944.1) #464646 gray(70)
5,0: (17944.1,17944.1,17944.1) #464646 gray(70)
6,0: (17944.1,17944.1,17944.1) #464646 gray(70)
...
If x is the nth coordinate and w is the difference between the (n+1)th and nth coordinate, I could then extract the wanted sub-image like this:
Code: Select all
convert input.png -crop "$w"x0+"$x"+0 -bordercolor Transparent -border 1x1 -trim +repage result.png
Question
Would this be a good way to do it? Is there a better (faster/simpler/safer) approach?
In particular, is it possible to do everything in a single 'convert' call, without a shell script?
(I'm using ImageMagick 6.9.2-6 Q16 x86_64 2015-11-23)