Chute-A-Pearing

16

1

Here are five images of pears and a steel chute:

A:pears A B:pears B C:pears C D:pears D E:pears E

These are only thumbnails, click them for full size!

(I made these with Algodoo.)

This class of images always has the following properties:

  1. They are always 400×400 pixels with a white background. (It may not be exactly white since SE images are lossily compressed.)
  2. They have 1 to 4 identical pears, each rotated and positioned in (almost) any way.
  3. They have one vertical steel chute that reaches to the bottom of the image.
  4. Other than the bottom of the chute, the chute and the pear bounding boxes (bounding box example) never touch or go out of the image bounds.
  5. The bounding boxes of the pears never overlap each other nor overlap the chute.
  6. The pears may be under the sloped part of the chute, as in B, C, and D. (So the bounding box of the chute may overlap the bounding box of a pear.)
  7. The chute may have any horizontal and vertical position as long as there is enough room for all the bounding boxes of the pears to fit freely above it (no "barely fits" cases will be tested) and part of the column portion is visible.

Challenge

Write a program that takes in such an image and outputs another 400×400 image with the chute in the same place, but with the pears repositioned so they are all above the chute (so they can fall into it and be juiced and whatnot).

The requirements for the output image are:

  1. All the pears in the input image must be repositioned such that they are above the chute, between the left and right edge of its funnel. (Above an edge is not ok.)
  2. Each pear must maintain its rotation angle. (So you should be cutting and pasting the pears, not redrawing them.)
  3. The pears must not overlap or touch each other or the chute. (The pear bounding boxes may overlap though.)
  4. The pears must not touch or go out of the image bounds.

Here are examples of valid outputs for the five sample images:

A:out A B:out B C:out C D:out D E:out D

These are only thumbnails, click them for full size!

Note that the input image for E was already a valid output, but rearranging the pears when not technically necessary is just fine.

Details

  • Take the filename of the image or the raw image data via stdin/command line/function call.
  • Output the image to a file with the name of your choice or output the raw image file data to stdout or simply display the image.
  • Any common lossless image file format may be used.
  • Graphics and image libraries may be used.
  • A few incorrect pixels here and there (due to lossiness or something) is not a big deal. If I can't tell anything is wrong visually then it's probably alright.

The shortest code in bytes wins. Tiebreaker is highest voted post.

Calvin's Hobbies

Posted 2015-06-03T03:42:30.353

Reputation: 84 000

Since I have a Khan Academy account, and this seems perfect to solve there, can I solve it on Khan Academy? There is only one complication: external images are not allowed. Luckily I can run the images through this to convert them to Khan Academy–friendly data. Is this acceptable?

– BobTheAwesome – 2015-06-03T12:16:51.473

@BobTheAwesome So you want to post a JavaScript answer? That's fine, though it's supposed to input and output 400x400 images. You can post your work to show off how you did it with KA but I may not accept it as winner if it doesn't work on 400x400 images. – Calvin's Hobbies – 2015-06-03T14:23:30.980

A perfect coincidence; Khan Academy just so happens to have a default of a 400x400px canvas for Javascript+Pjs. – BobTheAwesome – 2015-06-03T20:08:44.750

No!! Imagenator is super slow on 400x400 images!! – BobTheAwesome – 2015-06-03T20:20:11.233

Answers

6

Python 2.7, 636 bytes

import sys;from PIL.Image import*
_,m,R,I,p,H=255,400,range,open(sys.argv[1]).convert('RGB'),[],0
w,h=I.size;W,A,P,L=(_,_,_),[(x,y)for x in R(w)for y in R(h)],I.load(),I.copy()
try:
 while 1:
    s,x,y,X,Y=[[a for a in A if P[a][0]<50][0]],m,m,0,0
    while s:c=(a,b)=s.pop();x,y,X,Y=min(x,a),min(y,b),max(X,a),max(Y,b);P[c]=W;s+=[n for n in[(a+1,b),(a,b+1),(a-1,b),(a,b-1)]if n in A and P[n]!=W]
    p+=[((x,y,X,Y),X-x,Y-y)]
except:0
def G(a):r,g,b=P[a];return r==g==b and r<_
g=[a for a in A if G(a)]
(z,t),W=g[0],max([x for x,y in g]);t-=1
for r,w,h in p:
 if z+w>W:z,_=g[0];t-=H;H=0
 I.paste(L.crop(r),(z,t-h,z+w,t));z+=w;H=max(h,H)
I.show()

EDIT : now removes the alpha channel before handling the image, and aligns the pears on several rows if necessary

Produced images :

A B C D and E

and with vertical pears (takes around 3 minutes on my computer):

testcase vertical

dieter

Posted 2015-06-03T03:42:30.353

Reputation: 2 010

1Are the images befores/afters? If so I think you've taken the wrong ones for B-E... – Sp3000 – 2015-06-03T14:25:19.927

input image on the left, and output images on the right... they're not pixel-perfect at all due to rescaling and copy-pasting, I've put them just to give hints on how the script works.. – dieter – 2015-06-03T15:13:51.843

Will this work if all the pears are horizontal?

– Calvin's Hobbies – 2015-06-03T15:44:11.023

actually no... for two reasons :it falls in into an infinite loop because this particular image has an alpha channel ->fixing the script so it converts the image first. The other reason it that I removed the code that aligns the pears on several rows -> putting it back – dieter – 2015-06-03T16:28:12.500