Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I managed to get some decent results using this algorithm (not at my own computer so can't post code, yet):

- create a smaller greyscale copy of the image, and use sobel to calculate gradients (smaller to speed this up)

- set a gradient magnitude threshold, and add those points to a queue, largest first.

- for these points, add 2 squares, one either side of the queued point, in the direction of the gradient (ie you expect one to be light and one dark)

- add the squares to a location hash as they are placed. (I'm using a grid size slightly larger than my square tiles). The location hash is to speed up comparisons.

- skip placing a square if it would fall within a small radius of a previous square's centre (I used 0.5 of a square size). When looking up a point in the location hash, remember to look not for the point itself, but for the hash values for the corners of an axis-aligned square with your point at the centre; this is to catch overlaps when the point falls need grid lines.

- once all points in this queue have been processed or skipped, we start on a new queue, containing all squares placed so far.

- for each square in the queue, try to place a new square to its north, south, east and west along its alignment; as before skip these if they overlap too much

- any squares we place - jitter their position and angle slightly (otherwise it looks horribly unnatural)

- any squares we do place, add them to the phase 2 queue.

The first phase is quite slow, set the threshold high. Second phase placement is very fast. My squares all use a grey stroke the same grey as the background for the grout effect, and the squares are drawn using the colour of the point picked as the square's centre (I don't bother averaging). I have it rendering this interactively, using requestAnimationFrame, so it doesn't clog up the browser - I add about 50 tiles per frame

I'm looking at one it did of the mona lisa; it places the phase 1 tiles along her hairline and hand in a nice "vermiculatum" way, the phase 2 placement is less satisfying but with jitter it seems ok. Originally I'd thought about calculating where squares overlap and cutting tiles nicely but it was quicker just to _allow_ the overlap and so most of what you see are the whole tiles placed on top of partials. The overall effect isn't _quite_ like hand placed tiles but I like it better than a grid.

You can see a couple of output images here. https://hachyderm.io/deck/@bazzargh/114938616011157584



Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: