Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid
 
PerlMonks  

Detect boundaries within .png's - and cropping

by Stickybit (Novice)
on Jul 08, 2020 at 06:30 UTC ( [id://11119022]=perlquestion: print w/replies, xml ) Need Help??

Stickybit has asked for the wisdom of the Perl Monks concerning the following question:

Hi everyone

Got at specific problem, that I need some hints on. :-)

I got a bunch of fixed size .png images with logos. Those logos are centered on the images, and empty space on the left/right of the logo, is transparent background. I need to crop those images on the fly, so that empty space on the left/right of the logo is removed.

Any hints on how to solve that one? :-)

  • Comment on Detect boundaries within .png's - and cropping

Replies are listed 'Best First'.
Re: Detect boundaries within .png's - and cropping
by Corion (Patriarch) on Jul 08, 2020 at 07:08 UTC

    If all else fails, you can use Imager, and the ->getwidth, ->getheight and ->getpixel methods to read the image pixel by pixel to find the leftmost non-alpha pixel and the rightmost non-alpha pixel (and top/bottom), and then use ->crop to crop the image.

Re: Detect boundaries within .png's - and cropping
by Fletch (Bishop) on Jul 08, 2020 at 07:09 UTC

    Handwavy outline.

    • Use Imager to load the image
    • Start at the top row. Assume the width of the transparent extent for both left and right is the width of the image; similarly the top and bottom is the height.
    • Walk each row and find the length of the transparent extent to the left and right
    • If that length is less than the current maximum, remember it as the new current maximum
    • At the same time you're going to want to look and make a similar determination for the extent in each column
    • After you've walked down each row you know the width of the left most and right most transparent chunks; so crop horizontally from there over. And you should also have the vertical extents as well.

    The cake is a lie.
    The cake is a lie.
    The cake is a lie.

Re: Detect boundaries within .png's - and cropping
by Tux (Canon) on Jul 08, 2020 at 09:25 UTC

    The other two answers are good (and way better than my approach), but I'd share my thoughts anyway.

    As .xpm data is extremely easy to analyse, I'd do

    $ convert -transparent-color Black file.png file.xpm

    Where Black should be replaced with a color not in the image. Then analyze the .xpm and use that to crop the image.

    To be completely dynamic, you can repeat the process for Black, White, and Red and take the minimum margins of the three analises.


    Enjoy, Have FUN! H.Merijn
Re: Detect boundaries within .png's - and cropping
by jcb (Parson) on Jul 09, 2020 at 02:25 UTC

    PDL might be a faster way to implement the approach Fletch suggested.

      Intriguingly, there's no cropping type functionality in core PDL. A bit of a ponder suggests a good approach would be to (for rows), assuming an image of (rgba,x,y):
      $non_blank_rows = ($img->slice('(3)') != 0)->orover; ($low, $high) = $non_blank_rows->which->minmaximum;
      Then do the same for $img->xchg(1,2) for the columns, and hey presto, there's your bounding box!
        It turns out that making this broadcast properly over multiple images was impressively hard.

        which had a hardcoded limitation that it would only work on a 1-dim ndarray (fixed by imitating PDL::VectorValued's strategy of having a "how many set for each vector" output ndarray).

        Then actually using that with minmaximum also posed a problem, since the number of values per image might vary (in other words, the outputs might be ragged) - fixed that by having which fill the unset index-values with -1, and then setting that as the badvalue for the output ndarray, so minmaximum would ignore them.

        After that, the rest was easy! The new PDL::Image2D::crop works on a mask, so the above snippet would call

        $x1x2y1y2 = ($img->slice('(3)') != 0)->crop;
Re: Detect boundaries within .png's - and cropping
by Stickybit (Novice) on Jul 09, 2020 at 11:24 UTC
    Thanks guys .. got it working with the Imager module. :-)
Re: Detect boundaries within .png's - and cropping
by perlfan (Vicar) on Jul 08, 2020 at 20:58 UTC
    Looks like you got some good answers, but my first thought was to look to see if there was an OpenCV interface on CPAN. Unfortunately, there is not and it seems like you don't need that level of sophistication. I am just mentioning it here in case some generous soul reads this and gets inspired to create such an interface for Perl using one of the nice FFI options we have. =D
      I would say an OpenCV interface for PDL is pretty imminent / at the "prototype" stage right now!

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://11119022]
Approved by marto
Front-paged by kcott
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (3)
As of 2024-04-20 08:43 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found