Page 1 of 2

A Fun Experience with IM

Posted: 2010-10-11T10:15:59-07:00
by immortal26
I thought I would share a very neat little experiment using distort Shepards command and a couple of other to get the result.

Here is the code used ( I used PHP to make it dynamic to run a database creating multiple image... which rendered VERY fast .. 80 images in a minute ):

Code: Select all

$path = "/opt/local/bin/";
$font = "font/Impact.ttf";
$bg = "back/banner.jpg";

$name = strtoupper($name);

$label = "WE NEED ".$name." ON OUR TEAM!\nGO DOGS!";

$final = $path."convert -size 1163x338 -background none -gravity center -font ".$font." -fill '#1c33cf' label:'".$label."'   caption.png";
exec($final, $result);

list($fwidth, $fheight) = getimagesize('caption.png');

$final = $path."convert caption.png  -distort Shepards  ' 0,0,70,-25  150,0,170,5  288,0,310,7   500,0,500,3   675,0,675,10   824,0,824,10  1000,0,900,5          0,".$fheight.",45,350       ".$fwidth.",0,1095,-10   ".$fwidth.",".$fheight.",1000,350  '   caption.png";
exec($final, $result);

$final = $path."convert ".$bg." caption.png  -compose linear-burn -geometry +10+10 -colorspace CMYK -composite ".$count.".jpg";
exec($final, $result);
and the results? here it is: http://core.kpcdigital.com/mvp/stadium/louisiana/2.jpg

The $name and $count you see is from a script that runs this script that goes through a csv file getting the name and auto incrementing from 1 on $count.

Pretty nice results... love the linear-burn from -compose too.

Well hope some may find it useful and the power of what ImageMagick can do.

P.S: This is a cmyk image... to get best results, save to computer to see correct colors.

Re: A Fun Experience with IM

Posted: 2010-10-11T10:17:41-07:00
by fmw42
It might be nice if you could post links to your input and resulting images.

Re: A Fun Experience with IM

Posted: 2010-10-11T10:18:36-07:00
by immortal26
Yup, forgot about that, edited first post... and added a P.S at bottom.

Re: A Fun Experience with IM

Posted: 2010-10-11T10:33:58-07:00
by fmw42
So what did you use Shepards to do?

Re: A Fun Experience with IM

Posted: 2010-10-11T10:43:05-07:00
by Bonzo
I get a missing image :(

Re: A Fun Experience with IM

Posted: 2010-10-11T10:49:19-07:00
by immortal26
Bonzo try right clicking on the link itself and click save as (it is a cmyk image and doesn't display in all browsers)

I used shepards distort to contour the text to the banner being held by the guys, and a linear-burn to get some of the wrinkles on the banner to come through.
The banner being held is actually blank as you can see here:
http://core.kpcdigital.com/mvp/stadium/ ... banner.jpg

Note: the banner.jpg is also cmyk so if you aren't using a browser that displays cmyk images you have to right click and save as.

Re: A Fun Experience with IM

Posted: 2010-10-11T12:01:38-07:00
by Bonzo
I should have known that immortal26 as we were discussing that a couple of months ago - its my age!

Very effective and the image shows up OK in chrome.

Re: A Fun Experience with IM

Posted: 2010-10-11T12:31:05-07:00
by roadrunner
Great sample there. Can you share your method of loading the names from the CSV? I've been creating mega long bash scripts and think this php method might ease my pains.

Thanks!

Re: A Fun Experience with IM

Posted: 2010-10-11T14:08:54-07:00
by immortal26
No Problem.

Code: Select all

<?php
//use the setting below if your php's auto_detect_line_endings is turned off
ini_set('auto_detect_line_endings', 1);
// read the csv file into a multi-dimensional array
$row = 0;
$handle = fopen("mycsvfile.csv", "r");
$orders = array();

$i=0;
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
    if ($row == 0) {
        foreach($data as $d) { /*do nothing (it's the top row */ }
        $row++;
    }
    else {
        $c=0;
        foreach($data as $d) {
            $orders[$i][$c] = $d;
            $c++;
        }
        $i++;
    }
}
fclose($handle);

// Now it's all in the $orders array, let's loop through grab the names and include our imagemagick script.
$count = 1;
foreach($orders as $o =>$keys) {
    $name = $keys[2]." ".$keys[4];
    echo $name;
    include('banner.php');
    $count++;
}
There it is, quick and simple. Note when it's reading in the csv i run an if statement to skip the headers of the csv file (you can remove it if your csv doesn't have headers)

Re: A Fun Experience with IM

Posted: 2010-10-11T18:49:53-07:00
by anthony
I see you used Distort Shepards to distort the outside of the input rectangular image
to match the distorted rectangle of the original banner. Nice.

This would be a good example for IM Examples.
Can we get a link to the original too?

I can then plot the before and after 'control points' so people can better see the distortion movements.

Re: A Fun Experience with IM

Posted: 2010-10-11T19:01:52-07:00
by anthony
You could probably improve the results by first padding and resizing the text image source
to a specific size appropriate for the banner.

That should remove the need to insert "$fwidth" and "$fheight" tags into the Shepards distortion, whcih would not handle aspect ratio conversions very well with such a few number of points.

Re: A Fun Experience with IM

Posted: 2010-10-12T06:48:52-07:00
by immortal26
Hey Anthony,

You are more than welcome to download these images and use them on IM examples. (reason for download is that will not permanently be where they are now).

Feel free to mess around with the padding and such so you can show better examples on IM examples.

Here is the banner (save and convert to rgb before use):
http://core.kpcdigital.com/mvp/stadium/ ... banner.jpg

And here is the after shot (save and convert to rgb before use):
http://core.kpcdigital.com/mvp/stadium/louisiana/2.jpg

Re: A Fun Experience with IM

Posted: 2010-10-13T06:39:22-07:00
by immortal26
Hi Anthony,

I think you posted in the wrong topic, but thats okay I'm sure somebody can move it... but.
I've been trying out this morphology option but I can't seem to get this dot font down to one pixel for each dot.
Here is the font, maybe you can give me some ideas?:
http://core.kpcdigital.com/mvp/stadium/bc/font/dot.ttf

Thanks Man,
Immortal

Re: A Fun Experience with IM

Posted: 2010-10-13T07:58:48-07:00
by immortal26
Actually this worked pretty good.
( Forgive the PHP variables but you get the gist of it)

Code: Select all

$final = $path."convert -size ".$fwidth."x".$fheight." -background white  -font ".$font." -kerning 40 -interline-spacing -10 -gravity center -fill black caption:\"".$text."\" -monochrome  final.png";
exec($final, $result);
Added monochrome here to make it pure black and white.
Next for distortion: (again forgive the php variables)

Code: Select all

$final = $path."convert final.png  -distort Perspective '     0 , 0 , ".($TLx)." , ".($TLy)."        0 , ".$fheight." , ".($BLx)." , ".($BLy)."        ".$fwidth." , 0 , ".($TRx)." , ".($TRy)."       ".$fwidth." , ".$fheight." , ".($BRx)." , ".($BRy)."  '  -monochrome   final.png";
exec($final, $result);
Which you can see at the end added another monochrome.
Now:

Code: Select all

$final = $path."autotrace  -output-format svg -remove-adjacent-corners -corner-always-threshold 0   -output-file final.svg final.png";
exec($final, $result);
Give's me an svg file with ... example:

Code: Select all

<?xml version="1.0" standalone="yes"?>
<svg width="2096" height="482">
<path style="fill:#ffffff; stroke:none;" d="M0 0L0 482L2096 482L2096 0L0 0z"/>
<path style="fill:#000000; stroke:none;" d="M541 15L542 16L541 15M635 15L636 16L635 15M728 16L729 17L728 16M789....... ></svg>
So now I determine the coordinates using php's simplexml_load_file to get it all in an array.. then:

Code: Select all

foreach ($xml->path as $s) {
    if ($s['style'] != 'fill:#ffffff; stroke:none;') {
			$coords = explode(' ', $s['d']);
			$bc = 0;
			foreach($coords as $coo) {
				if ($bc == 1) {
					$rbm = rand(1,4);
					$x = strrchr($coo, 'M');
					$x = str_replace('M', '', $x);
					$y = substr($coo, 0, strpos($coo, 'M'));
					if ($y != '' || $x != '')
					echo $x."<br />".$y."<br /><br />";
					$final .= 'bitmap/bc'.$rbm.'.tif -geometry +'.($x+$PX-$TLx-30).'+'.($y+$PY-$TLy-10).' -composite ';
				}
				else {
					$bc++;
				}
			}
	}
}
$final .= $count.'.jpg';
exec($final, $result);
In final result's it gives me ONE member at each point! Hooray!
Instead of having a multicolor svg file, I get a 2 color in which you see I skip the white and get the coords from the black (which is the text).
Not sure if you know php well but you can see I'm parsing through the d= in the svg getting x,y as x = whatever is behind an "M" and y = what's in front of the "M" ignoring spaces... Works Well!

Re: A Fun Experience with IM

Posted: 2010-10-13T19:32:18-07:00
by anthony
anthony wrote:Very good.

I gather you use a 'dot' font to draw the name, then distort that to fit the background image, and then replace each 'dot' with a small human figure, before it is overlaid on the background image.

Very tricky. and you obviously a lot of fun to create it.

What did you use for the 'dot replacement'

Looking close you can see some figures 'doubled up'. You may like to look at some type of morphology to convert any large dot to a single dot before converting 'dots to people'.
immortal26 wrote:Hi Anthony,

I think you posted in the wrong topic, but thats okay I'm sure somebody can move it... but.
I've been trying out this morphology option but I can't seem to get this dot font down to one pixel for each dot.
Here is the font, maybe you can give me some ideas?:
http://core.kpcdigital.com/mvp/stadium/bc/font/dot.ttf

Thanks Man,
Immortal
Actually I hadn't! But at the time I looked at your links I saw a picture of a stadium filled with a large crowd, but an empty field, but then the same picture with lots on 'little' people standing around so as to form letters of a name.

The links are now (original)
http://core.kpcdigital.com/mvp/stadium/ ... lorida.png
With the result
http://core.kpcdigital.com/mvp/stadium/ ... /final.jpg

I still like to know how you placed all those ant-like people!

As for the 'dot' font. After distorting, I would first so a threshold on the image to make it binary, then would use a Morphology Thinning transform to repeatedly remove 'edge' from the image until you get a single dot.

For example...

Code: Select all

convert -font Dot -pointsize 144  label:Anthony \
          -trim +repage -bordercolor white -border 5 -negate anthony_dots.gif
Image
Use morphology Thinning to convert the dots to single points.

Code: Select all

convert anthony_dots.gif -threshold 80% \
          -morphology Thinning:-1 'LineEnds;Corners;Edges' anthony_pixels.gif 
Image
Distort and enhance to single dots again

Code: Select all

convert anthony_pixels.gif  +distort Affine '0,0 0,0  0,1 .5,.2  1,0 1,-.2'\
            -threshold 10% -morphology  Thinning 'LineEnds;Corners;Edges'  anthony_final.gif 
Image