Skip to content

Instantly share code, notes, and snippets.

@nixterrimus
Created November 21, 2011 05:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nixterrimus/25885913abc56fc34a18 to your computer and use it in GitHub Desktop.
Save nixterrimus/25885913abc56fc34a18 to your computer and use it in GitHub Desktop.
Chunky PNG Cropping Challenge

Crop

This solution crops to the center 100 pixel square in the image.

Show me the Output!

Why this is a great solution

  • It's wicked fast
  • It's easily maintainable
  • It gets the right crop at least as often as more complicated solutions
  • The most interesting part of an image is frequently at the center

Seriously?

I spent a lot of time thinking about this and tried other solutions. The solution I came to is that there aren't a lot of great solutions. An algorithm gets it wrong as much as it gets it right. Centering the crop was the first solution I wrote up as the stupid simple case. It was meant to be the solution against which I compared all other solutions. What I found is that I was happier with it for cropping than other solutions.

Let me try and convince you a bit more. Let's talk about the duck image:

The duck image has no true focal point. There are no lines leading to a central point in the photo. There is no strong use of contrasting color. However if we're talking human focal points then we're probably talking about the heads. We would like to see the ducks cropped to the ducks' heads:

In this image I've highlighted the focal points in pink. I've also highlighted 'ideal' crops in orange. Notice anything interesting? Even if the algorithm could perfectly determine the focal point the crop wouldn't be right. Another thing that's interesting? This is completely a matter of opinion. Cropping is something that's pretty subjective.

Another interesting thing- this center crop picked a solution that was very similar to another I had toyed with that looked for standout colors. This is because the duck's legs are one of the brightest parts of the image. That algorithm was considerably slower.

Now let's talk about the dog and the cat- there is a much clearer center point. This centering method grabs the right picture.

Another good thing about this method is that it's fast. There's no deep calculation that needs to go on so this solution is able to churn through images very quickly. It's also small so it's very maintainable.

If this brawl was a challenge to ship code, this would definitely be the solution I'd ship.

Other solutions

As I said I explored other solutions and I'd like to share some quick notes:

Blob Detection

I explored blob detection by flipping the image grayscale and upping the brightness and contrast until there were black blobs on the page. I then looked for the box that best fit the most number of black pixels. This worked surprisingly well for the ducks, not good for the cat, and awful for the dog. The algorithm falls apart on any images that are dark.

Interest Hue Detection

This algorithm looked for interesting hues. I was really disappointed with the results.

require 'rubygems'
require 'chunky_png'
module ChunkyPNG::Canvas::Operations
def crop_square_at_point_of_interest(x,y,size)
x = x - ( size / 2)
x = 0 if x<0
y = y - ( size / 2 )
y = 0 if y<0
self.crop(x,y,size,size)
end
end
def center_point_of_interest(image)
[image.dimension.width/2, image.dimension.height/2]
end
['cat', 'duck', 'dog'].each do |test_image|
input = ChunkyPNG::Image.from_file("#{test_image}.png")
point_of_interest = center_point_of_interest(input)
input.crop_square_at_point_of_interest(point_of_interest[0],
point_of_interest[1], 100).save("#{test_image}-output.png")
end
@rogerbraun
Copy link

You did not convince me enough ;-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment