This effect takes a lot of time and memory so the first thing it needs to do is disable the default time limit with set_time_limit(). At the end of each row it destroys or unsets the variables. Larger images may still run out of memory.
To create the 3D landscape effect in the images above the scrip first uses shearImage() and scaleImage() to make it into a flattened parallelogram so it looks like it is flat on a table and you are looking over it. Next it uses getimagewidth(), getimageheight() and getimageformat() to get the new size and the format to create a pallet to write the 3D image onto. Finally it iterates through every pixel calculating a gray value, making a vertical line that is proportional in height to the gray value and has the original color and drawing the lines onto the pallet image. Since tall lines starting at the bottom of the image will overlap shorter lines near the top you get a 3D landscape effect.
<?php
//set php script timeout, 0 to disable
set_time_limit(0);
# starting image
$url = "http://eclecticdjs.com/mike/temp/ball/fract6.jpg";
# $url = "http://eclecticdjs.com/mike/images/avatar.jpg";
# name of finished image
$file = "3d_fractal.jpg";
# $file = "3d_avatar.jpg";
# Read image as blob
$blob = file_get_contents("$url");
# make new imagick object from blob
$image = new imagick();
$image->readImageBlob("$blob");
# scale it down
$image->scaleimage(200, 0);
$image->shearImage("transparent", 45,0);
# scale it to make it look like it is laying down
$w = $image->getimagewidth();
$h = $image->getimageheight();
$image->scaleimage($w, $h/2);
# Get image stats
$w = $image->getimagewidth();
$h = $image->getimageheight();
$format = $image->getimageformat();
#### Make a pallet to draw on
$pallete = new Imagick;
$pallete->newimage($w,$h*2, "blue");
$p_w = $image->getimagewidth();
$p_h = $image->getimageheight();
$dif = $p_h-$h;
$pallete->setimageformat("$format");
####
$row = new ImagickPixelIterator($image);
$x = 1;
# loop through all points
while ( $row->getNextIteratorRow() )
{
while ( $x <= $w)
{
# get (r,g,b) and grey value
$point = $image->getImagePixelColor( $x, $y );
$color = $point->getColor();
$r = $color[r];
$g = $color[g];
$b = $color[b];
# Calculate grayscale
$grey = ($r+$g+$b)/25;
$grey =(int)$grey;
# Make line with height proportional to grayscale
$line = new ImagickDraw;
$line->setfillcolor("rgb($r,$g,$b)");
$line->setstrokecolor("rgb($r,$g,$b)");
#$line->setstrokewidth(1);
$line_height = $y-$grey;
$offset = 75;
$y = $row->getIteratorRow();
$start_y = $y+$offset;
$end_y = $y-$grey+$offset;
$line->line( $x, $start_y, $x, $end_y);
# draw the line
$pallete->drawimage($line);
# Free up memory
$point->destroy();
$line->destroy();
unset($color);
$x++;
}
$x = 1;
$y++;
}
$pallete->scaleimage(250, 150);
# write pallet
$pallete->writeimage( "$file");
#header("content-type:image/$format");
header("Location:$file");echo $pallete;
exit;
?>
|
|
|