perjantai 14. lokakuuta 2011

HD Mosaics


Like many other families, we have also LOTS of family pictures forgotten into the harddrives of our computers. These times people take so many pictures that it's impossible to enjoy all of them. Lately, I've been thinking some "mass-way" to utilize them.

Some photography companies offer some solution to this: Photobook, different collases etc. But they still use only less than 50 images and the results are not very nice.. Too much automation/decorations-i-dont-want etc. Also, I'm guessing that if i would make an album, it would be watched couple of time with relatives, and then forgotten to a bookshelf. I figured the only real possibility is to get the photos into my walls somehow. Large poster / canvas art is the only real option.

Mosaic are great choise when you are able to print in large enough size. This is what I started to study more.

I hand-picked few hundred best pictures and decided that I will create a mosaic from them, forming our wedding picture. I started to search for a good application to calculate the mosaic: I couldn't find any. All of the programs I found, were mostly grid-based lighting / color matchers. They never could make good enough quality for reasonable sized tiles that actually represent the target picture in any printable size => so that in large scale, I could see the picture they are forming. And in small scale, i could see the photos that are forming it.

I decided to write the generator by myself. Since I (and everyone else who is using only own pictures) have very limited size ("very limited" in this context means something like below 10.000) of source images, i needed to find some way to increase the amount of matches with the actual sources I have. The actual test program is (once again) C/C++ with QtSDK and manual "per-pixel-manipulation".

I start the scanning-process by normalizing the lightness on each of my source- and targetblocks. This way there can be good matches even when the original lightness of two images are completely different: Only relative changes apply. This alone increased the quality of the results so significantly, that it alone could have been already enough. I still wanted more, I started adding different parameters / transforms into the blitting of the source tiles:
* xlip (-1 or 1)
* Angle (Anything user wants. I'm testing between -2 and 2 radians with 0.2 radian steps)
* Scale (Anything user wants. I'm using scales from 0.4 to 0.9 )
* Source offset (i'm scanning all of the possibilites from the source according current scale and angle. With a selectable step).

First i tried the algorithm with just a single tile; to see how the scaling / rotating functionality works. The process had many steps before these results but they are not stored anywhere. I ended up doing the matching only with normalized lighting, discarding the source's color. The blit color is derived from the target picture.




Then I started to add actual tiles I'm going to use in the final picture. With more tiles, the time required for the calculation increases. For each tile, it runs several loops inside other loops. This is not a problem for me, I can wait for couple of hours for good image to render. The original results have VERY large resolution (print quality) and they are scaled down before posted here:






Even tough I haven't made the final photo to be printed. I like the results. As you can see, the tiles really try to form the shapes from the original photo. Its especially visible in tests made with larger blocks. I will post the final source when I get it done! No back to coding :p

tiistai 27. syyskuuta 2011

AsciiArt with free width fonts

Well, not exactly ASCII - art. But art with any set of glyphs. Originally, i was planning to create a Facebook-plugin which one could use to comment with pictures (without pictures though), the problem was that i couldn't know which font viewer's browser was using... With OSX, most commonly it was Lucida Grande, with Windows, Tahoma etc. The facebook "fontchain" has several different fonts which it tries for each character until it finds the glyph.. Finally i was able to isolate a subset of glyphs from Arial which worked for most viewers (Arial has some glyphs that any font defined before Arial in the facebook-font-chain has not).

I wrote a software which takes any image as input, and uses any set of glyphs (or why not imagees?) and tries them to the image line per line to achieve minimum error^2 / pixel. I really like the results. I would just (once again) find something useful to do with the test :)


These are made with subset of Arial:


Girl


███████████████▓▓▓▓▒▓▓████████▓▓▓▄▒`´`░▀▓████████
███████████████▓▓█▓▓▓██████▓███▓▓▓▓▒◦◦◦``░▀▓▓▓████
███████████████▓▓█▓▓██████▓▓▓▓▓▓▓Ѿ▓▒◦◦´``´`░▒▓▓█▓█
████████████████▓█▓█████▓▓▓▒▒▒▒◦░▒◦`░▒▒´´´´`´`´`´▒▒▓▓▓▓
███████████████▓▓▓▓▓████▓▓▒▒´´´´´`´´`´```´´`◦````◦◦´`´`´´´`´´´░▒▓▓
██████████████▓▓▓▓▓▓▓▓████▓▒◦```````´``´`´``´´`````´´´´```´````´░▒▒
██████████████▓▓▓▓▒▒▒▒▓▓▓██▒▒◦``````````````````````´`´´````````░▒▒
██████████████▓▓▓▒▒▒▒▒▒▒▒▒▓▓▒◦´´´```´`````´´``´`````´`´´```´```´``░▒
██████████████▓▓▒▒▒▒◦◦◦´`◦`◦░▒▒▒▒´`◦```````´````````````````◦´````´`´```░
██████████████▓▓▒▒▒▒◦```´`´`´´´`´``░▒▒¸`´````````````````````´``´◦`´´``´´``´◦
██████████████▓▓▒▒▒◦◦◦``´´´´``````´`````░▒◦¸```´``````````````````´`◦`´´´```◦◦
██████████████▓▓▒▒◦´`´´´´`´````````````````´``▒▒¸`´´`◦``´´`´´`````´```````´´``◦░
████████████████▓▄▒¸¸`´``````´``````´``````´```´▒▒▒`◦◦´`´`````´``````´`´```◦▒
████████████▓▓▓▓▒▒▒▀▓▓▒▒◦◦`´´´`´`´`◦◦▒▒▓▓▒▒▒◦`´`´`´```´`´`´`´```´▒
████████████▓▓▓████▓▓◄▒▒▒´´``´´`´`░▒▄▓▓▄▓▒▒◦◦◦´´``````´````´░
████████▓▓██▓▒▒Ѿ█▓▓▒▬▓▓▓◦```´´``◄▄▓▓▓◄▀▒▒▒◦◦´`◦◦`´``´´``░
██████████▓█▓▒▒◦´´´░░░´´```░▒▓▒´´`´`´`´´´░░░´´´````´`´``░▒◦´``░▒◦◦◦░
█████████████▓▒◦´´``````´`´´´`░▒▒▒`´´´´´```````´```´´```´´`````▐▓▒▒▒░░░▒
█████████████▓▒▒◦``´```````´░▒▓▒◦`````´```´````´`````´´``´``Ѡ▓▒▒◦◦◦◦`░▒
█████████████▓▓▒◦◦´´`````´`░▓▓▓◦``````````````````´````````◄▓▒▒◦`◦◦◦◦◦░▒
██████████████▓▒▒◦◦´```´´◦▒▓▓▒```````´´`´`````````´````´Ѡ▓▓▒▒◦`◦░░░
██████████████▓▓▒░◦´◦◦◦░▒▒▒▒´```´´´´```````´`´``````Ѡ▓▓▓▒▒◦◦░▒▒
██████████████▓▓▒▒▒◦▒▓▒▒¸¸¸´``´``````´``¸´´´``````Ѡ█▓▒▓▒▒▒░`░▒
███████████████▓▓▒▒░▒▓▓▓▒▒▒▒`´´´`´```´``´`◄██▓▓▒▒▒▒▒◦´◦Ѿ
████████████████▓▓▒▒▒▒▒▒▒○◦◦◦◦◦´```````Ѡ█▓██▓▒▒▒▒▒◦◦◦``Ѿ
██████████▓██████▓▓▓▒▒◦´´´´`´´`````´´´````Ѡ█▓▓▓▓▓▓▒▒▒▒▒◦`´´`
████████▓▓▓█████▓▓▓▒▒▒▒◦´````````´´´´``´´▒▓█▓▒▒▓▓▓▒▒▒▒▒◦````
███████▓▓▓██▓▓█▓▓▓▒▒▒◦◦`´´```´´´``´``````´`▒▒▓▓▒▒▒▓▓▓▒▒▒▒░◦`´
███████████▓▓▒▓▓▓▒▒▒▒◦◦`´`´´`´``````````´``▒▒▒▓▓▒▒▒▓▓▓▒▒▒◦░◦
█████████▓▓▓▓▓▓▓▓▒▒░◦◦´`◦`´`´```````´´´´````░▒▒▓▓▓▓▒▒▒▒▓▓¸░░`◦
███████▓▓▓▓▓▓▓▒▒▒▐▒◦◦´``´```´´`````´``````´´´´`´▒▒▒▓▓▓▓▒▒▒▒▓▓▒▒
██████▓▓▓▓▓▓▓▌▓´░▒`◦▒▒¸◦◦´´`´````´```´````````´`´`░▒▒▒▒▓▓▓▒▒▒▒▓▒
███▓▒▀▓▓▓▓▒▒▓▌▒▒◦´░▒▒▒▒▒◦◦◦◦◦◦```´`´``´`````´``´´´``░▒▒▓▓▓▓▒▒▒▓
█▓▓▓▓(`░▒▒▒▒▒▓▌▒▒◦◦◦◦░▒´▒▒▒◦◦◦◦``´`´``´``````´```´´``´◦◦`◦▒▒▒▓▓▓▓▒▒
▓▓▓▒▒▒\¸`´▒▒▒▒▒▌▒▒▒▒◦○◦◦▒´´´▒▒◦`´´``´```´´`´`´´``´`´´◦◦◦´`◦◦░▒▒▒▓▓▓▓▒
▓▒▒▒▒▒▒\¸``░▒▒▒▓▒▒▒▒▒◦`¸´◦◦◦◦`´░▒¸¸¸´´`´`´´`´`´´````´``◦◦◦◦◦◦░░▒▒▒▓▓▒▓
▒▒▒▒▒▒▒▒¸```░▒▒▓▒▒▒▒░░◦``´`○◦◦◦▒▓▒``◦´`´`´```´`´`◦´´`◦◦◦◦◦░░▒▒▒▒▓▓
▒▒▒▒▒▒▒▒▒¸```▒▒▓▓▒▒▒▒▒▒▒´´´``◦`´○▒▒▒◦◦◦◦◦◦´``◦◦◦´◦◦◦◦◦◦░░▒▒▒▒▒▓
▒▒▒▒▒▒▒▒▒▒``´░▓▓▒▒▒▒▒▒▒▒▒````◦´`○▒▒▒◦◦◦◦◦◦◦◦◦◦◦◦◦◦░░░▒▒▒▒▒▒
▒▒▒▒▒▒▒▒▒▒▒´`░▓▒▒▒▒▒▒▒▒▒▒▒´`´░`´▒▓▓◦◦◦◦◦◦◦◦◦◦◦◦░░░▒▒▒▒▒▒▓
▒▒▒▒▒▒▒▒▒▒▒ȴ´´`▒▒▒▒▒▒▒▒▒▒▒▒▒▒´░▒▒▒▒▒◦░░░░░░▒▒▒▒▒▒▒▒




DRAGON:


````````````````````````````````````````````¿```▐ƺ«◄*«´``¸¸``````````````````````````````````````´```````````````````
``````````````````````````````````````````Ѡ◄▓▓▒▒▒▒▒▬ȴ````````````````````````````````````````````````````´``
`````````````````````````````````````ȵ◙▓Ѽ▌````´´´`´´´`´´´`░▒▒▒□`````````````````¸``````````````````````````````
``````````````````````````````````╓Ѿ▒▒▄▒▒▒▒▒▒▒▒»¸¸¸```░▒▒¸`````▒@▓▓▌ҳ¸````````````````````````
```````````````````````````````Ѹ▓▀▒`▒▒▒▒◄▼×▒▒/´´▒▒\¸¸¸``▒▒◄▓▒▒▒```´´╚¸``````````````````````
``````````````````````````¸ӽ´¸▒▐▌`¸▒▒▲▒▄◙◙◙▒▒▒¸¸¸¸`¸¸░▒▒``░▒▒▒▀▓▓▓▒▓Ɣ````````````````````
````````````````````````ƴ░▒▀▓▒▒▓▒▬▀▒▄═◦`´`´``´´░▒´´░´´◦▒◦`´`▒▒○◦``¸□▒▒▒▒´``````````````````
````````````````````¸▄▓▀▓◙▓▓▀▒▄▓▓▒▒◄◙´``````´´`░▒▒▒`´░◦``░▄▒▒▒▒´▒▒▐```````````````````
`````````````Ѹ▓Ѿ▒▒▒□¸`▒▓▓▓▐▓´◄`Ѽ▌`````````▒▒▒▒````````Ѿ▌▒▒▒◄░▒´``````````````````
```````````◄@▌▒▓▀▓7▒)`ѾҦ▓▒`▐´´Ѿ´`````````░▒`▒◦`````````Ѽ▌`▒▒¸▒`´▒)````````````````````
`````````░▀▒▒▒▒▒▒▌Ӿ`´´`░◦Dž▓▒◦▒´ѠĬ```````´`░○`░´´´`````´`´`Ѿ▒▒`dž´`░҂````````````````````
```¸□>*`´─~³````´┌``´´¸¸´╒▒▒×`▐▓▒◦`░▒▐▒«¸◦¸´░▒◦´▒^````````░◄▓░҂W`´░ƒ´````````````````````
`◄═▒▒¸¸¸``´`¸▒▒´¸▒▒═*´`´`´``◄▐▌¸░░░▒▒▒▒▒´´````▒▒¸▒▒/`´░▒▒░Ⱦ´´▒/``````````````````````
``▐▓▒Ѽ▓▓▒▒▒▒´``````````````░▌▓▓▓═◄▬▒¸▒▒▓▓▄▒▒▒▒▒▄▄▓▌`░Ɣ```````````````````````
``´▒▒Ѡ▌▒▒`´`````````````````````´▐▒▐▓▒¸`````¸¸Ѿ▒Ѽ▒╒ƹº*▒▓▓▓█▒`▒▒`´```````````````````````
``````````´`´░``░´``````````````````````ŴѠ█▓«▒▒◦◦```└▓▓▓▒´´´`◄▓▓█Ǐ◦◦▒ƒ``````````````````````````
```````````````````````````````````````````Ѿ▓▓▒`░▒▒````▒▒▒▓▒▒◦```░▓▓█▒▒¸¸□○○¸¸`````````````````
````````````````````````````````¸○─~~─Ѿ▒▒▒░▒○´``░▒▒▒▒▒````░`◦Ѿ█▀`````´─ѵ◦▒(```````````````
`````````````````````````````╓▒´´``´`´´`Ѽ▓▒▒▒░▒`◦`░░▒▒▒`````○▒○`◦▒▌```````````▒▒▐``````````````
``````````````````````````░▒´´`´```◦◦░´░◦▐▒▒▒◦◦▒▒´´░▒▒◦´```○▒░/▒▒ǰ`◦``````````¸dž░├```````````´´`
`````````````````````````░/´¸¸¸¸¸¸○▒▒``▒▒▒▒◦░◦◦░▒◦´`´``´´´´´´▒▒◦░▒▒▒▒▒´`─▒▒▒Ѹ▄¸¸`````````◦`
````````````````````````◄▒`▒▒´´◦´``´◦▼▒▒`´`>░▒○```´´``````◦◦◦◦░░▒`▒▓▒▒◦◦░▒▒▒▓▒▓▓ȴ```````
`````````````````````````▒▒▒◦```´``´`◦`Ѽ▒▒◦◦```´`´´´`´```````◦○░○▒``´░▒▓▒▒`´´░░Ѡ▒´``´Ѿ▄´````
``````````````````````````░▒▒´´´``````░○▐▒▒◦▒▒▒○``````─◦░░░○▒▓▓▓▒`◦´``````Ѹ▒○◦◦````Ѿȴ```
````````````````````````````▒▒▒◦´◦`````░Ѿ▒░░▒░░`´´´○─▒▒▒◦▒▓▓▓▓◦``◦◦```▒▒◦´``◦░´´```Ѽ▌``
`````````````````````````````´▒Ҁ▒◦/´````´░▐▒▒▒▒◦`◦´`░▒▒▒▒▒¸░▐▓▓█▒´```´¸▒▒```´`´◦´◦``´```Ѿ◙
`````````````´``````````````````░▒○░◦```░Ѿ▄▓▒▒¸¸◄▒▒▒▒▒▒▓███▓`´´´´░▓▓`´```◦░░`´´```Ѿ`
``````````````````````````````````░▒▒▒``´`░DŽ▓▓▓▓▓▓▓▒▓▄▓▓█▓▓█´´´`─▓▓▌´```◦◦░´`´◦´```▐▓
`````````````▲`````````````````````Ȭ▒▒```░ţ`´`▒▀▀▓▓▓▓▓▓▓▓▓▓██▓´``░DŽ█◦`´´○○`◦◦``````◄▌
```````````◄▓►¸¸````````````````´`Ȭ▒◦`´░╕¸¸¸¸¸¸¸``´`´´´▒▒░▒▒Ī``````´Ѿ¸▒Ѿ█▓``´`◦◦`´◦`◦`´´`Ѡ▌
````````ѹ▒▓▓▒▒►¸```````````````´▒¸``´○``~◦▒▒░◦´`░¬─□¸¸`¸○ӽ▒▒▒▒▄Ѿ█▌`´`´▒◦─◦◦```◄▓´
``````◄▒▐▓▓▓▒▒▒◙¸````````````У▄▄╦▒▒▒▒▒▒□□▒▒▒▒◙▒▒▄▓▒○Ŵ▓▌`´``░○´`´`´`Ѡ█´`´
````Ѹ▒DŽ▐░▓▓░▒▓▌``´````Ѡ▀```´`````````````´´░▒▓▒▒▄►▓▓▒▒▀▓▀Ǐ`´´○▒▒◦´´´``ѹ▓║´``
````▐▒▒▓▓▌▐Ѿ/``░▀\´´`````▼`````````````````¸¸▲▒▒▄◙▒Ѿ▄▓▓►▒```´◦─░░´´`´`Ѡ▒▒^`````
```Ѡ▓Ѭ█Ì`Ѽ▓▓´``````````````````````````````ѵ▒Ⱥ◄@▒```¸»@▓▒´``````´◦▒▒▒´´``´``╔▐Ǐ´░*```````
````▒´´```ѾѠ▒Ѿȴ`````````````````````````Ѡ▀▒▓▒▒▒▒▒▀▒´`````◦□▒▒▒▒´´´`Ѡ▒▒▒Ǫ`````````
```````````Ѡ`▐▒▄¸´░▒~○¸¸`````````````````░``¸Ѡ▒▓▒▒´´´`□▒○░░░´`´´´´░¸´``░´▐`´´◦ѹ```````````
```````````▐▒◦`´´◄▒``´``´◦`▒▒▼◙◙▄╥ӡ▒▒▒@▀▓Ǐ`´◦◦`◦▒▒▒░◦´``´¸¸```үѼ▒/````○◦V`````````````
```````````▐▒▒◦´´▒▒▄▌¸``´´´´´`░○○◦◦´▒▒▒▒◦◦`◦▒´◦´´``◦◦◦`´◦´¸¸`´´`┌Ŵ▒´`░ª`´```░●*`´``````````````
```````````◄¸`░◦`´```Ŵ``└@Ӽ````´¸¸´´´◦`´`¸´´`◦`◦´´¸¸¸````Ѹȴ¸``┌◄6▒`´└ª```○◦``¸▒°`````````````````````
````````````Ѽȴ´`░░◦´``````░ª`░ӽѠ▒``Ѡ▌*×ɀƴ▐ƛ¸ƴ◄\`´Ƴ´▒ª´````«○´▒▒▪*´´´´``````````````````````
``````````````Ѿ▄¸´`░░◦ӽ◦¸``´´^Ѽ▒´`░´▒ª`````´`´`´*`░´´▒▒◦░▒░▒▒▒<´`´```````````````````´``````````` ``````````````````▒▀▀◙◙▄▄▒¿¸◦¸´`´░◦◦─○`´´◦◦◦◦◦`◦◦◦`´`◦¸▒□═<*´``´´`````````````````````````````````````´ `````````````````````````´``````´░▒▒******¬¬¬^^**********`´```´`````````````````````````````````````````´````````

Dad and daughter:





```````````````````````````````````````````````````````````````````````͵͵͵͵͵░▒▒▒▒͵͵͵͵͵͵͵͵͵͵͵͵͵͵͵͵͵͵͵``````````````````````````````````
````````````````````````````````````````````````````````````````````͵͵▒▒▓▓▓▓▒▒▒▒▒▒▒▒▒◦͵͵͵͵͵͵͵͵͵``````````````````````````
``````````````````````````````````````````````````````````````````͵▒▓▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒͵͵͵͵͵͵͵͵````````````````````
````````````````````````````````````````````````````````````````░▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒▒▒▒▒○◦͵͵͵͵͵``````````````
```````````````````````````````````````````````````````````````▒▓▓██████████▓▓▓▓▓▓▓▓▓▓▒▒▒▒◦͵͵͵͵```````````
``````````````````````````````````````````````````````````````▒▓▓████████████▓▓▓▓▓▓▓▓▓▓▓▒▒▒◦͵͵͵͵```````
`````````````````````````````````````````````````````````````▒▓████████████▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒▒▒͵͵͵͵```
````````````````````````````````````````````````````````````▒▓███████████▓▓▓▓▒▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒͵◦͵͵`
```````````````````````````````````````````````````````````Ѡ██████████▓▓▓▒▒▒▒▒▒▒▓▓▓██▓▓▓▓▓▓▒▒͵͵
```````````````````````````````````````````````````````````▒▓██████████▓▓▒▒▒▒░░░▒▒▒▓▓▓██▓▓▓▓▓▒◦`
``````````````````````````````````````````````````````````░▓▓████████▓▓▓▒▒▒▒░░░░░▒▒▒▒▓▓▓▓▓▓▓▓▒͵
```````````````````````````````````````````````````````````▒▓██████████▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒◦͵
``````````````````````````````````````````````````````````͵▒▒Ѿ████████▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
``````````````````````````````````````````````````````````▒▒▒▒▓██████▓▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒◦
```````````````````````````````````````````````````````````▒▒▓▓▓▓▓██▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
```````````````````````````````````````````````͵͵͵͵͵͵͵͵͵͵͵͵▒▒▒▒▒▒▓▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
````````````````````͵͵͵͵͵͵͵͵͵͵͵͵͵͵͵͵͵͵͵͵○͵░▒▒▒▒▒▓▒▒▒▒▒▒▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓▓▒▒▒▒▓▓▒▒
````````````````͵͵͵͵͵░▒▒▒▒▒▒▒▒▒▒▒▒▓▓▓▓▓▓▒▒▒▒▓▓▒▒▒▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒
`````````````͵͵͵░▒▒▒▒▒▒▓▒▒▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓▓▓▒▒▒▒▒▓▓██████████▓▓▓███▓▓▓▒
````````````´͵░▒▒▒▒▓▒▓▒▓▒▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓▓▓▒▒▒▒▒▓▓▓████▓▓▓▒▒▓█▓▒▒▓▓▒
```````````͵͵◦░▒▒▒▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓▓▓▓▒▒▒▒▒▓▓▓▓▓▒▒▒▒▒▓▓▓▒Ѡ▌▒
`````````͵͵͵░▒▒▒▒▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓▒▒▒▒▒▒▒▒▒▓▓▓█▓▓▓▒▒▓▓▓▓▒▒▒▒▒▒▒▓▓▒◦`Ѡ▌▒
```````͵͵▒▒▒▒▒▒▓▒▒▒▒▒▒▒▒▒▒▒▓▓▓▓▓▓▓▓▒▓▓▓▓▓███▓▓▓▒▒▒▓▓▓▒▒▒▒▒▒▓▓▒````Ѿ▒▒
```͵͵◦▒▒▓▓▓▒▒▓▒▒▒▒▒▒▒▒▒▒▓▒▒▓▓▓▓▒▒▒▒▓▒▓▓█▓▓▓▓▓▓▒▓▓▓▓▒▒▒▒▒▒▒▒▒`͵``Ѿ▒▒
`͵○▒▒▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▒▓▓▓▒▒▒▒▓▒▒▒▒▓▓▓▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒▒▒▒▒◦´◦◦͵͵Ѿ▒▒
͵▒▒▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▓▓▓▒▒▒▒▒▒▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒͵▒◦`◦´`͵Ѿ▒▒
▒▒▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▓▓▓▓▓▒▒▓▓▓▒▓▓▓▓▓▓▓▓▓▓▓▓███▓▓▓▓▒▒͵░▒͵░´`Ѿ▒▒
▒▒▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓▓▓▓▓▓▒▒▒▒▓▓▓▓▓▓▓███▓▓███▓▓▒░▒▒░▒◦░◦`´◄▒▒
▒▒▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓▓▓▓▓▓▓▒▒▓▓▓▒▓▓██▓▓▓▓▓▓▒```▒▒◦░▒▒▒◦`Ѡ▒◦
``░▒▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓▓▒▒▒▓▓▒▒▓████████▓▄¸▒▒▒░▒▒▒``▒▌▒
````░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒◦◦´`◦``░░▒▒▒▒▒▒▒░▒▓▓▒▒▓▓▓▓█████████▓▒▒▒͵◦````◄▒`◦
``````͵`▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒◦◦͵͵͵͵͵◦◦◦◦░░░▒▒▒▒▓▓▓▓▓▓▓▓████████████▓▒▒◦◦͵`Ὓ▒`◦
````͵͵͵▒▒▒▒▓▓▓▓▓▓▓▓▓▓▓▓▒▒▒◦◦◦◦`◦◦◦◦◦◦◦░░▒▒▒▓▓▓▓▓▓▓▓██████████████▓▒͵͵``Ὓ▒◦
```͵░▒▒▓▓▓▓▓▓▓▓▓▓▓▓██▓▒░͵◦͵͵´◦͵``◦◦◦`◦◦◦◦░▒▒▒▒▒▓▓▓▓████████████████▓▒͵͵`░▒◦
`͵◦▒▒▓▓▓███▓▓▓▓▓▓▓▓▓▒▒▒◦◦◦◦͵◦´``´``◦◦͵͵◦◦░▒▒▒▒▒▒▒Ѿ██▓██████████████▓χ͵`▐▒
͵͵░▒▒▓▓████▓▓▒▒▒▒▒▒▒▒▒▒◦░͵◦͵͵◦͵͵͵͵͵͵░░▒▒▒◦`````´```´````░▐█ȴ͵Ѿ████████████▓ȴ͵▐▒
░▒▓▓██████▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒◦´͵´`´`͵```´```͵`´░▓▓◦͵`○Ѿ███████████▓▒`´
▒▓▓▓███████▓▒▒▒▒▓▓▓▒▒▒▒▒▒▒▒▒▒▒▓▒▒◦͵͵͵͵͵͵͵͵͵͵͵͵͵͵͵͵░▒▒▒´░◦```Ѿ██████████▓▒͵
▓▓▓██████████▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▓▒▒▒▒▒▒░◦͵͵░▒▒▒▒▒͵░/``````´´`▒▀▀███████▓▒
▓▓██████████████▓███▓▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒◦`░´͵````````````´Ѡ███████▌
▓▓██████████████████▓▓▓▓▓▓█▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒´`´͵░▒͵͵͵͵`````````````Ѿ███████
▓▓█████████████████████▓▒▒▒▒▒▒▒▒◦◦◦░▒▒▒▒▒░░◦◦░▓▒◦░◦͵͵```````````Ѿ███████
▓▓█████████████████▓▓▓▒▒▒▒▒▒▒▒▒▒▒͵◦◦◦░▒▒▒▒▒͵░@▒◦░▒▒͵`````````͵͵Ѿ███████
▓▓████████████████▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒◦◦◦´͵◦◦░▒▒▒▒@▓▒▒▒▒◦͵͵``͵͵͵͵▒▒▒▓██████
▓▓███████████████▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒░▒◦░░░▒▒▒Ѡ▒▒▒▒▒▒▒͵░▒▒▒▒▒▓██████
▓███████████████▓▒▒▒▒▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒@▒▒▒▒▒▒▒▒▒▒▒▒▓▓▓▓█████
▓██████████████▓▒▒▒▒▒▓▒▒▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓▓▒▓████
▓▓████████████▓▒▒▒▒▒▒▒▓▒▒▓▓▒▒▒▒▒▒▒▒▒▒▒▒▓▒▒▓▒▒▒▒▒▒▒▒▒▓▒▓▓▓▓▓███
▓████████████▓▓▒▒▒▒▒▒▒▓▓▓▓▓▓▓▒▓▒▒▒▒▓▒▒▓▓▒▓▓▒▓▓▓▓▒▒▒▓▓▒▓▓▓▓▓███
▓███████████▓▓▓▒▒▒▒▒▒▒▒▓▓▓▓▓▓▓▓▓▓▒▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒▒▓▓▒▓▓▓▓▓████
████████████▓▓▓▒▒▒▒▓▓▒▓▓▓▓▓▓█▓█▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒▓▓██▓█████
████████████▓▓▓▒▒▒▒▓▓▒▓▓▓▓▓▓▓██▓▓▓▓▓█▓▓▓▓▓▓▓▓▓▓▓▓▒▓▓▓▓██▓█████
███████████▓▓▓▓▒▒▒▒▓▓▓▒▓▓▓▓▓▓███▓▓██▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓████████
███████████▓▓▓▓▒▒▒▒▓▓▓▓▓▓▓▓▓▓███████▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓████████
███████████▒▓▓▒▒▒▒▒▓▓▓▓▓▓██▓▓▓█████▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓████████
██████████▓▒▓▓▓▒▒▒▒▓▓▓▓▓▓▓██▓██████████▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓████████
█████████▓▓▒▓▓▒▒▒▒▓▓▓▓▓▓▓▓▓███████▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓████████
▓████████▒▓▒▓▓▒▒▒▓▓▓▓▓▓▓▓▓▓████████████▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒▓███████
▐███████▓▓▓▓▓▓▒▒▒▓▓▓▓▓▓▓▓▓▓█████████████▓▓▓▓▓▓▓▓▓▓▓▓▒▒▒Ѿ██████

There might be some problems viewing the images with some settings (browser, os, etc. ). For reference. Previous should look like this:





Some more tests with different free-width glyp-sets:





maanantai 6. kesäkuuta 2011

Screensavers for Symbian^3 devices

For some time now I've been waiting for downloadable screen-savers to arrive into Nokia's Ovi store. I hate the ones delivered within the device. Quite recently, Nokia published a new, pink N8 device with pre-installed "Pink Neon Clock"- utility which I instantly thought to be a new, nicer screen-saver. It wasn't !! It was a basic application which was advertised to "Easily be accessed by leaving it running on the background when locking the phone" ... I was wordless.... Well, if someone is willing to pay for that kind of crap, maybe someone would pay something for REAL screensaver as well.

Me and my friend decided to try and started working on new screensaver base which would be actually usable. Our goal was to make the savers look nice and still consume as little power as possible.. We succeeded pretty well. Our screensaver's take about 120-140mw of power (It runs about 2-3 days without reloading: This is the same than with OEM-screensavers) and the look, well, ... The beauty is in the eye of the observer: Your call. These our our first ones. A series of neon clocks in all of the "Nokia N8" colours:








We also made a quite nice banner for advertising. I'm not sure will it ever be actually visible in Ovi store, but nevertheless, it's there:



Later we enlarged the selection with a little different saver as well. Here is "dotclock". Very nice in my eyes. Reminds me of Terminator meets Fallout - style ;)




In our SVN- there are some more unpublished content still waiting for us to see is it worth publishing..

The screen-savers are on the Ovi store and you can buy your own copy from there. Our channel is:
http://store.ovi.com/publisher/peekpoke/

keskiviikko 6. huhtikuuta 2011

tiistai 1. maaliskuuta 2011

Qoat of the Hill


For some time now i've been working with mobile devices and Qt. Qt is a great library, but as a game developer I've found it difficult that it lacks a "true" OpenGL ES 2.0 support: Current versions offer only an encapsulated version "QtOpenGL" of it. QtOpenGL is used via "QGLWidget" which is a Qt's UI-component enabling OpenGL graphics inside it.
The encapsulation and modified syntax wouldn't be a problem if you could be sure you are always working only with Qt, but nowadays it's important to maintain as much portability as possible. Also, when software needs to be ported from other platforms to Symbian^3 (or other systems supported by Qt), this can be a very difficult issue.
We've been developing a "replacement" version of QGLWidget which would work as much like real QWidget as  pobssible, but directly with underlying native GLES2. This way the developer could use native GLES2 just like in most other platforms and still take advantage of Qt's great functionality.
We hope our work would help the developers exactly with the issues above and make devices supported by Qt more attractive especially to game developers.
In this shot you can see a game I've been developing within our replacement widget (GE::GameWindow). I've tried to keep it as simple as possible and still use lots different techniques.
Some details:
- Heavily simplified "Scorched earth"/Worms clone where you try to push your opponent down from randomly generated hill by shooting him.
- Everything is rendered with OpenGL ES 2.0
- Windows support (for easy debugging and fast development) is available with PowerVR's GLES2 emulation libraries.
- Landscape texture is generated from a set of base textures with shaders at run-time. (you can see it modifying when ammunitions "burn" it enough).
- Multilayer sky/ground system.
- Several background layers for creating more complex feeling for the scene.
- Particlesystem with fixed-points and nicely customizable type system. Each type can have its own program for rendering.
 You can check our project (including sources) at:
http://projects.forum.nokia.com/qoatofthehill

Some screenshots:





tiistai 18. tammikuuta 2011

Older stuff: Img2Img hider


I guess i should store some of my older stuff as well. Here is the "img2img" hider. The purpose of this software is to "hide" a smaller image into another. It takes two images as input, the "background" and a image to be blitted (Let's just call it "blit"-image). It tests the blit with all of the possible positions and angles through the background image and keeps record of the attributes with minimum error. These attributes will be outputted to the blitting phase. 

The blitting considers a large variety of attributes from the error-detector, source and target images. it tries to blend these two image (areas) morphing the background as much towards the blit-image as possible within the error-limits specified for it.

Easier to explain with a video, the "img2img"-hider in action:


Since i wrote a completely automated version which tries all of the possible combinations of several hundreds of different images there are LOTS of screenshots available. You can check tens of pictures in my Flickr account (http://www.flickr.com/photos/tuomoti/). 

Couple of examples. These are cropped from huge originals. NO other "by hand"-manipulation has been made:









sunnuntai 16. tammikuuta 2011

Custom CMYK-halftone printing

For a long time I've watched the images/prints in newspapers and commercials thinking how it is actually printed, with just a four colors overlapping. Forming beautiful little patterns. Some time ago I started to read about the techniques used and got more and more interested about it. There are "newsprint"-filters in almost every image-manipulation software (including GIMP), but they are not very good; I guess they are aimed for people who actually design data for real CMYK-printing, not for people who just want to create nice looking effects still using the full color space (and -scale) like me.

I decided to implement the effect with different design-considerations, aiming it to be able to look smooth without VERY high resolutions.  The program to be created should be able to "print" any image with as "real" halftone CMYK as possible, including "pressure", "ink-bleeding" and other physical elements affecting when the image is done the actual (physical) printing. 

Software is made with Qt and tested on Windows 7 and Linux. The graphics processing is completely custom and does not deploy Qt on any other part than providing loaders/savers for the images.






Couple of test videos:


(Edit: Another video with newer version uploaded):


A closer shot displaying the result software creates:




Processing of an image goes like this:
  • Calculate a gray scale mask with selected type (dot, lines with different powers, square).
  • Calculate the orientation matrices for each color-component with selected angels and size.
  • Use attribute “sizediv” to downscale the image with as high quality as possible
  • If enabled, convert the downscaled image into CMYK-color space. 
  • Create a target image with same dimensions with the source image
  • Loop though each pixel of the target image
  • Resample a color from downscaled CMYK(or RGBA) image.
  • Apply contrast (“overcut”)
  • Transform the  current coordinate with pre-calculated matrices for each color component and get mask values from these positions.
  • Apply noise to the mask values with selected noise-power and size.
  • Calculate a delta vector from (sampled_color_from_downscaled_source – mask_values_for_each_component)
  • Use attribute “pressure” as contrast for the deltavector.
  • Targetcolor = 128 + final deltavector.


Here it can be seen how the image changes when parameters are adjusted. rastersize, downscale, noise's different attributes, overcut (kind of a contrast) etc.

'







Of cource it can use different masks than "Dot" as well. The results will look quite different:



Lets see how it can be improved. Interesting times.