▼  Site Navigation Main Articles News Search  ▼  Anime + Manga Anime Reviews Anime Characters Gallery Screenshots Manga Reviews  ▼  Misc Links to Webcomics Bible Quotes About Older Musings
site version 7.3
PHP –– Image Processing –– part 1
written by: admin


Date Written: 8/12/08 Last Updated: 9/12/12

PHP has two families of code that deal with image manipulation.  The most commonly installed is PHP's image library.  This article will cover a few examples of what GD (Graphics Draw) can do and how it works.  Part 2 places more of an emphasis on the use of imagefilter.  Part 3 looks at generating images, such as gradient and semi–transparent images and begins to look at PHP's other image manipulation family –– ImageMagick.


Reduce image size with minimal loss in quality
 

This is the primary example image we will be looking at.


Images resized in the normal way width:25%; or width=100px; will pull the image and dynamically resize the image, but the filesize will still be 100 kb and load just as slow.  Not only that, but in many browsers there will be a loss in image quality when the image is resized and the image will appear grainy unless you are viewing the image using the Opera browser.

By using the following method to resize the image the quality will not be lost if you decide to use it to create a thumbnail that is smaller in size.  When resizing images this way the images will load faster and the loss in quality will be minimal.  No thumbnail file is created, but you don't need to generate a new image to get this effect.

Note:  This code was pulled from php.net and was altered very little.
<?php
// The file
$filename = 'http://www.animeviews.com/images/screenshots/cowboybebop27.JPG';
$percent = 0.25;

// Content type
header('Content-type: image/jpeg');

// Get new dimensions
list($width, $height) = getimagesize($filename);
$new_width = $width * $percent;
$new_height = $height * $percent;

// Resample
$image_p = imagecreatetruecolor($new_width, $new_height);
$image = imagecreatefromjpeg($filename);
imagecopyresampled($image_p, $image, 0, 0, 0, 0, $new_width, $new_height, $width, $height);

// Output
imagejpeg($image_p, null, 100);
?>

The image is outputted directly to your browser and looks like


Create and store a thumbnail image
It is recommended that you create a thumbnail version to store in your website because constantly resizing images is a bit processor heavy.  To do this we can modify the code above slightly to look like this:

<?php
// The file
$filename = 'http://www.animeviews.com/images/screenshots/cowboybebop27.JPG';
$percent = 0.25;

// Content type
header('Content-type: image/jpeg');

// Get new dimensions
list($width, $height) = getimagesize($filename);
$new_width = $width * $percent;
$new_height = $height * $percent;

// Resample
$image_p = imagecreatetruecolor($new_width, $new_height);
$image = imagecreatefromjpeg($filename);
imagecopyresampled($image_p, $image, 0, 0, 0, 0, $new_width, $new_height, $width, $height);

// Output
imagejpeg($image_p, null, 100);
$dest="try1.jpg";
imagejpeg($image_p,$dest);
?>


This code is the same as the first one listed above except for the added lines of:
$dest="try1.jpg";
imagejpeg($image_p,$dest);

This creates a destination file for your generated image.  The old image is not destroyed in the process.  An example of saving the new image is not in php.net, which is one of the reasons I made this article.

With this example I take and use it to create a thumbnail that looks like


List the image files in a directory
The following code is from phpparadise.  I am in the process of doing research to create a script that will take all of the images in a folder and create thumbnail versions in them.
<?php  
$imgdir = 'images';
$allowed_types = array('png','jpg','peg','gif','bmp');
$dimg = opendir($imgdir);  
while($imgfile = readdir($dimg))  
{
if(in_array(strtolower(substr($imgfile,-3)),$allowed_types))  
{  
  $a_img[] = $imgfile;  
}  
}
sort($a_img);  
$totimg = count($a_img);
for($x=0; $x < $totimg;)  
{
echo "$a_img[$x]<br>";
$x++;  
}  
?>



Copy one image onto another
The following seems to need php 5 when viewing with ie7.  Firefox and Opera both work fine at displaying the page.
<?php
header('Content-type: image/jpeg');
$dest = imagecreatefromjpeg('images/blood.JPG');
$src  = imagecreatefromjpeg('http://www.animeviews.com/images/screenshots/cowboybebop27.JPG');
list($width1, $height1) = getimagesize('http://www.animeviews.com/images/screenshots/cowboybebop27.JPG');
list($width2, $height2) = getimagesize('images/blood.JPG');
imagecopymerge($dest, $src, 0, 0, 0, 0, $width1, $height1, 50);
header("Content-Type: image/jpg");
imagejpeg($dest,null,100);
imagedestroy($dest);
imagedestroy($src);
?>

The above will copy file $src onto $dest.  The width of the image is fixed at whatever the width of the $dest file is.  The 50 listed above is the percentage of $src that will be overlayed onto the $dest image.
 +     =  


check if an image is truecolor or not
<?php
$filename = 'http://www.animeviews.com/images/screenshots/cowboybebop27.JPG';
$im = imagecreatefromjpeg($filename);
if (imageistruecolor($im)==false) {echo "$filename is not a truecolor image";}
else {echo "$filename is a truecolor image";}
?>



convert to palette image
The following will convert a truecolor image to a palette image and will output the number of colors used in the palette, not the number of colors that the image actually uses.  From what I can tell 256 is the highest number of different colors an image can have.

Remember, null means that the image will be output directly to your browser and not saved.
<?php
$filename = 'http://www.animeviews.com/images/screenshots/cowboybebop27.JPG';
$im = imagecreatefromjpeg($filename);
imagetruecolortopalette($im, false, 255);
print imagecolorstotal($im);
?>

The following will change the truecolor image to a palette image and will output it to your browser.  Try decreasing the number of colors in the image so that you can see that the script is working.
<?php
header('Content-type: image/jpeg');
$filename = 'http://www.animeviews.com/images/screenshots/cowboybebop27.JPG';
$im = imagecreatefromjpeg($filename);
imagetruecolortopalette($im, false, 255);
imagejpeg($im, null, 100);
?>
Before converting the image to a palette image the image will look like


After converting to a palette image the highest quality image will look like



convert one color in a jpg image to another
<?php
header('Content-type: image/jpeg');
$filename = 'http://www.animeviews.com/images/screenshots/cowboybebop27.JPG';
$im = imagecreatefromjpeg($filename);
imagetruecolortopalette($im, false, 255);
$ig = imagecolorat($im, 20, 20);
imagecolorset($im, $ig, 0, 0, 255);
imagejpeg($im, null, 100);
?>
The above will produce something that looks like this



image effects
using image filter you can apply many different special effects to your image.  
For more see PHP –– Image processing –– part 2


change the palette of an image
The following code will use the palette from $filename1 and apply it to the $filename image.  It can be fun to play with.  You can use it to redraw an image using only 2 or as many as 256 specific colors if you want.
<?php
header('Content-type: image/jpeg');
$filename = 'http://www.animeviews.com/images/screenshots/cowboybebop27.JPG';
$filename1 = 'http://www.animeviews.com/images/pops/williameyesbig.jpg';
$im  = imagecreatefromjpeg($filename);
$im1 = imagecreatefromjpeg($filename1);
imagetruecolortopalette($im, false, 255);
imagetruecolortopalette($im1, false, 255);
imagepalettecopy($im, $im1);
imagejpeg($im, null, 100);
?>

Using some of the above code I could create a script that would take an image, use a palette from a different image that I created that has 5 specific colors (or 2 or 20) and apply it to the first image.  If I create a program that will allow me to change the color of any of the 5 colors to any other color using a submit form I could have a greater amout of control over an image.

using the palette from the image

and applying it to

we get something that looks like



a poor way of determining which colors are used in a given image
<pre><?php
$filename = 'http://www.animeviews.com/images/screenshots/cowboybebop27.JPG';
$im = imagecreatefromjpeg($filename);
imagetruecolortopalette($im, false, 25);
$a= imagecolorstotal($im);
$e=0;
while ($b<$a){
$x=rand(0,255);
$y=rand(0,255);
$z=rand(0,255);
    $result = imagecolorclosest($im, $x, $y, $z);
$e++;
    $result=imagecolorsforindex($im, $result);
    $result="({$result['red']}, {$result['green']}, {$result['blue']})";
    $arry[]="$result";
$arry=array_unique($arry);
$b=count($arry);
if ($e>10000){break;}
}
natsort($arry);
$arry=array_values($arry);
print_r($arry);echo"
number of colors in image palette=$a
number of colors located=$b
It is very likely that the total number of colors used in the image is about the same as the number of colors located.";
?></pre>

The output will look something like the following:
Array
(
    [0] => (66, 70, 81)
    [1] => (101, 102, 101)
    [2] => (121, 115, 112)
    [3] => (130, 89, 87)
    [4] => (231, 178, 172)
    [5] => (246, 244, 239)
    [6] => (255, 255, 255)
)

number of colors in image palette=25
number of colors located=7

It is very likely that the total number of colors used in the image is about the same as the number of colors located.

Note: just because the number of colors in the palette is 25 does not mean that the image will use all 25 colors in the image.  In this example only 7 colors were used and so only 7 colors were detected.

This is a poor script because the code finds the colors used through trial and error.  The results are still pretty accurate, but there is a very small margin of error.  If you run the script 2 or 3 times you may see that a color was missed in one of the executions of the script.


Randomize the colors in an image
<?php
header('Content-type: image/jpeg');
$filename = 'http://www.animeviews.com/images/screenshots/cowboybebop27.JPG';
$im = imagecreatefromjpeg($filename);
imagetruecolortopalette($im, false, 25);
$e=0;
while ($e<10000){
$x=rand(0,255);
$y=rand(0,255);
$z=rand(0,255);
$result = imagecolorclosest($im, $x, $y, $z);
$e++;
$exact[]=$result;
$result=imagecolorsforindex($im, $result);
$result="{$result['red']},{$result['green']},{$result['blue']}";
$arry[]="$result";
$arry =array_unique($arry);
$exact=array_unique($exact);
}
$e=0;
$b=count($arry);
natsort($arry);
natsort($exact);
$arry=array_values($arry);
$exact=array_values($exact);
shuffle($arry);
while($e<=$b)
{
$arry[$e]=explode(',',$arry[$e]);
imagecolorset($im,$exact[$e],$arry[$e][0],$arry[$e][1],$arry[$e][2]);
$e++;
}
imagejpeg($im, null, 100);
?>
The image will always look different everytime you run it.  This script gathers all of the colors that are used in the image and just rearranges them.

The following example is one of those program runs.  


Here is the image before the colors were rearranged.

I know the picture quality has gone down a bit.  This is because I limited the palette size to 25 different colors.  I did this because at higher palette sizes it takes too long to run and rearranging the colors looks rather bad.
Change the number 25 on line 6 to raise or lower the number of colors that are used for the palette.  Try not to raise it too high or else it takes too long to run and may be too taxing on your server (causing you to get your web account suspended).

For completeness here is what the image would look like if we changed palette size to 90.



Links


TAGS: images, php
copyright 2005–2024