Search code examples
imagemagicktransparencycrop

ImageMagick – Split Transparency Image Along Internal Non-transparent Object Borders


I have a transparent image containing three non-transparent objects, each separated by transparency. Is there a simple command—not one with zillions of options, arguments and random geek walks inside the pic—to explode this picture into its three parts, each in a picture file.

Please, visit this link to view the kind of pic.

I thank you very much for your help.


Solution

  • If the 3 components you want are always in the same place, you can just extract according to coordinates:

    convert image.png -crop 164x146+27+0 +repage result-0.png
    convert image.png -crop 12x146+0+0   +repage result-1.png
    convert image.png -crop 30x7+138+151 +repage result-2.png
    

    enter image description here

    enter image description here

    The last one is empty!


    If they are not always in the same place, I would look at the image's alpha/transaprency layer:

    convert image.png -alpha extract alpha.png
    

    enter image description here

    As it shows the bits you want on white, I would look for white blobs, using "Connected Component Analysis"

    convert image.png -alpha extract                  \
      -define connected-components:verbose=true       \
      -define connected-components:area-threshold=200 \
      -connected-components 4 -normalize result.png
    

    Output

    Objects (id: bounding-box centroid area mean-color):
    2: 164x146+27+0 108.5,72.5 23944 srgb(255,255,255)
    3: 32x161+174+0 196.5,87.0 2670 srgb(2,2,2)
    5: 174x15+0+146 79.8,152.8 2370 srgb(1,1,1)
    1: 15x146+12+0 19.0,72.5 2190 srgb(2,2,2)
    0: 12x146+0+0 5.5,72.5 1752 srgb(255,255,255)
    39: 30x7+138+151 152.5,154.0 210 srgb(255,255,255)
    

    That shows us all the blobs in your image. Looking back at the alpha layer, you only want the white ones and you want the second field on the line because that tells you where to crop that blob.

    That leads us to this:

    #!/bin/bash
    
    # Edit this according to your input image name
    image="image.png"
    
    i=0
    convert "$image" -alpha extract                    \
       -define connected-components:verbose=true       \
       -define connected-components:area-threshold=200 \
       -connected-components 4 -normalize result.png | 
          awk '/255,255,255/{print $2}'              | 
             while read c ; do
                convert "$image" -crop "$c" +repage result-$i.png
                ((i=i+1))
             done
    

    which hopefully does what you want.