Create an image with PHP pixel by pixel
It’s pretty easy to create an image with PHP pixel by pixel. I wanted a simple good looking graphic to show how close I am to completing my swimming goal, but I didn’t want to edit and upload a new picture every day. I decided I wanted a simple text file to edit. I made a text file with a 20×20 grid of ‘o’s and replace an o with an x for every quarter mile I swim. So really what we end up doing is making a PNG file with PHP from an ASCII file.
Here’s the grid at the moment
xxxxxxxooooooooooooo oooooooooooooooooooo oooooooooooooooooooo oooooooooooooooooooo oooooooooooooooooooo oooooooooooooooooooo oooooooooooooooooooo oooooooooooooooooooo oooooooooooooooooooo oooooooooooooooooooo oooooooooooooooooooo oooooooooooooooooooo oooooooooooooooooooo oooooooooooooooooooo oooooooooooooooooooo oooooooooooooooooooo oooooooooooooooooooo oooooooooooooooooooo oooooooooooooooooooo oooooooooooooooooooo
Pretty simple, right? Now I just needed a way to use that to make a pretty bitmap. Fortunately PHP has got all the tools for this.
First we create an image object:
$img = imagecreatetruecolor($width,$height);
Now we need to read in the text file (‘swim’) and iterate over each character to see what it is:
$log = file_get_contents('swim');
$rows = explode("\n",$log);
foreach($rows as $y => $row){
$columns = str_split($row);
foreach($columns as $x => $column){
// process each letter here!
}
Inside the inner loop we’ll use a switch statement to decide what to do based on what letter we find.
// Inner loop code
switch($column){
case 'x':
$color = imagecolorallocate($img,0,0,0);
break;
case 'o':
$color = imagecolorallocate($img,0,255,255);
break;
default:
$color = imagecolorallocate($img,125,125,125);
}
imagesetpixel($img,$x,$y,$color);
Finally we print out the image
header('Content-Type: image/png');
imagepng($img);
imagedestroy($img);
Now, the above code creates a usable image, but it’s only 20×20 pixels and the colors are kind of boring so I added the following two enhancements :
1) Enlarge the bitmap
I set the initial height and width with a variable instead of hard coding them, then re-use them here. $new_img will be $scale times larger than the original. Obviously, we will use $new_img in the imagepng() function to print it out instead of the smaller image.
$new_img = imagecreate($scale * $width,$scale * $height); imagecopyresized($new_img,$img,0,0,0,0,$scale * $width,$scale * $height,$width,$height);
2) Add some color variation
I used the Gimp to find the RGB color ranges I wanted to use. I then put the minimum and maximum values into the rand function and every pixel will get a random different color within the range.
$color = imagecolorallocate($img,0,rand(216,255),rand(150,255));
My final script looks like this:
<?php
$width = 20;
$height = 20;
$scale = 10;
$img = imagecreatetruecolor($width,$height);
$black = imagecolorallocate($img,255,255,255);
$log = file_get_contents('swim');
$rows = explode("\n",$log);
foreach($rows as $y => $row){
$columns = str_split($row);
foreach($columns as $x => $column){
switch($column){
case 'x':
$color = imagecolorallocate($img,30,rand(0,100),rand(60,150));
break;
case 'o':
$color = imagecolorallocate($img,0,rand(216,255),rand(150,255));
break;
default:
$color = $black;
}
imagesetpixel($img,$x,$y,$color);
}
}
$new_img = imagecreate($scale * $width,$scale * $height);
imagecopyresized($new_img,$img,0,0,0,0,$scale * $width,$scale * $height,$width,$height);
header('Content-Type: image/png');
imagepng($new_img);
imagedestroy($new_img);
imagedestroy($img);
The final image looks like this:
You can refresh this page to see that the image changes each time.
