There is a big disclaimer that should be made to all those about to venture on ImageMagick programming using PHP: the great, vast majority of WAMP (Windows-Apache-MySQL-PHP) servers do not support ImageMagick commands at all, since it is a "different package," and there appears to be no way to install ImageMagick through standard Add/Remove Applications within Linux (as far as standard Debian linux releases go). It's very easy to get Apache/PHP running in either Windows or Linux with pretty much any standard OS/distro supported so that you can run all of your own code on your own computer. But that's definitely not the case when you want Imagick to cooperate with your Apache server and your PHP code!
It took me almost an entire week just to get Apache/PHP/ImageMagick working all together nice and happily so that I could run my own PHP code on my own machine (natively, too). So, I decided to simply write down the steps, to help anyone else out who could need help.
Guide to Building an Apache/PHP/Imagick Server with Linux/CentOS 6.4:::
1. Install CentOS 6.4. (Theoretically, other versions of CentOS should work as well, but I simply chose the most recent one.) Also, you can very easily emulate CentOS within Windows (for instance, the unfree choice of VMWare).
2. Install PHP, PHP-Common, PHP-extensions, etc., from standard Application Package Manager ("Add/Remove Programs", usually in system tools somewhere). (You don't have to worry about Apache, because that comes with CentOS 6.4 anyway.)
3. Open up a terminal and enter admin mode with the command "su". You'll need a password for this.
4. Enter this command: yum install ImageMagick ImageMagick-devel
5. Enter this command: pecl install imagick
6. Modify php.ini and include the line "extension=imagick.so". This file is located at "/etc/php.ini" normally. The line must be exactly inserted in the section of "Dynamic Extensions", which begins with this commented out text:
--------------------------------
;;;;;;;;;;;;;;;;;;;;;;
; Dynamic Extensions ;
;;;;;;;;;;;;;;;;;;;;;;
--------------------------------
Use the "search" feature of gedit to find the text. Add the extension below the commented out note in this section so that the result looks like:
--------------------------------
;;;;
; Note: packaged extension modules are now loaded via the .ini files
; found in the directory /etc/php.d; these are loaded by default.
;;;;
extension=imagick.so
--------------------------------
Putting the extension directly at the top caused me serious permission issues in running Imagick code. Also, with CentOS, the permissions automatically disable user control for this php.ini. Enter the following terminal command: "chown [YOUR-USERNAME] -R /etc/php.ini", without the quotes to get control to modify it. Note to insert your username where it states "[YOUR-USERNAME]".
7. Enter this command: "service httpd restart", without quotes, from admin mode. This restarts Apache/PHP/PHP's extensions now that you've installed ImageMagick. If this gives you an error, just try "service httpd start".
My favorite part about this method is that you can update your system with issuing the "yum update" command and then the "yum upgrade" command -- and the Apache/PHP/Imagick combination will still be working perfectly! Unlike some other guides out there for this, you don't need to rely on antiquated, unsupported versions that can be nearly impossible to find. Also, you don't need to worry about the MySQL, Hash, MBString, Exif packages, because they all seem to be installed and properly cooperating with PHP automatically after installing PHP from the Application Manager. This solution makes everything work well together.
The root directory of your public files is located at /var/www/html/. Normally, this folder is not owned by the user, so you'll get a permission error when trying to add files or folders to it. Correct that with entering admin mode in the terminal/command-line window ("su" command) and entering the following command: "chown [YOUR-USERNAME] -R /var/www/html/", without quotes. Again, replace "[YOUR-USERNAME]" with your actual user name. (Warning: The first time I did this, I was lazy and entered the command for only the "/var/" folder, which prevented my system ever from booting. It would always freeze with the notorious and googleable error-message: "Could not update ICEauthority file /var/lib/gdm/.ICEauthority". So, make sure to change ownership only for "/var/www/html/".)
To view your root directory files as compiled, resultant, PHP pages, open up a browser and enter "127.0.0.1" as the address. So, a file in your root directory would be accessed at the following URL in your browser: http://127.0.0.1/your.file.php . If you get a "could not connect" error message, try the command "service httpd start" at the terminal window from admin mode. (You have to start this service manually every time the machine boots, although there's plenty of ways to automate it.)
I hope this helps! I tried a hundred different guides on getting Apache/PHP/Imagick to work together and none of them worked. Don't give up! ImageMagick is a package of really neat imaging functions!
Open Software Coders of the World, You Have Nothing to Lose but Your Proprietary Chains! (...delivering advice for users of PHP/Linux/Apache)
Showing posts with label imagick. Show all posts
Showing posts with label imagick. Show all posts
Thursday, May 30, 2013
Monday, July 2, 2012
Image Rendering Intent in the ImageMagick Package of PHP
The Rendering Intent variable exists in ImageMagick to provide support for ICC Color Profiles. There are five results that one can expect to get from the getRenderingIntent function, which are the predefined constants for Rendering Intent within ImageMagick. These values look like "imagick::RENDERINGINTENT_UNDEFINED", with "_VALUE" values of: undefined, saturation, perceptual, absolute, and relative. Printed out, Undefined is 0, Saturation is 1, Perceptual is 2, Absolute is 3, and Relative is 4.
The official ImageMagick documentation provides good light on what these values indicate. ( http://www.imagemagick.org/RMagick/doc/constants.html#RenderingIntent ) Undefined means "no intent," Saturation means "A rendering intent that specifies the saturation of the pixels in the image is preserved perhaps at the expense of accuracy in hue and lightness," Perceptual Intent means "A rendering intent that specifies the full gamut of the image is compressed or expanded to fill the gamut of the destination device. Gray balance is preserved but colorimetric accuracy might not be preserved," Absolute Intent means "Absolute colorimetric," and Relative Intent means "Relative colorimetric."
Every time I ran this function, it always produced the same result: #2, indicating Perceptual Intent. But this makes sense, since the ImageMagick documentation notes about the Rendering Intent, "Typically, the user or application will set the rendering intent dynamically at runtime or embedding time." The ImageMagick documentation also recommended the following link to better understand Rendering Intent in terms of Colorspace Profiles: http://www.cambridgeincolour.com/tutorials/color-space-conversion.htm .
Some sample code :
<?php
// Author: holdoffhunger@gmail.com
// Imagick Type
// ---------------------------------------------
$imagick_type = new Imagick();
// Open File
// ---------------------------------------------
$file_to_grab = "image_workshop_directory/test.jpg";
$file_handle_for_viewing_image_file = fopen($file_to_grab, 'a+');
// Grab File
// ---------------------------------------------
$imagick_type->readImageFile($file_handle_for_viewing_image_file);
// Get Rendering Intent Values
// ---------------------------------------------
$imagick_rendering_intent = $imagick_type->getImageRenderingIntent();
switch($imagick_rendering_intent)
{
case '0':
$image_rendering_intent_evaluated = "Undefined";
break;
case '1':
$image_rendering_intent_evaluated = "Saturation";
break;
case '2':
$image_rendering_intent_evaluated = "Perceptual";
break;
case '3':
$image_rendering_intent_evaluated = "Absolute";
break;
case '4':
$image_rendering_intent_evaluated = "Relative";
break;
}
// Print Rendering Intent Values
// ---------------------------------------------
print("# $imagick_rendering_intent - $image_rendering_intent_evaluated");
?>
Official Function Page: http://www.php.net/manual/en/imagick.getimagerenderingintent.php
// Note: All code appearing on the PHP Revolution blog by the blog owner is released under the Hacktivismo Enhanced-Source Software License Agreement (HESSLA), unless otherwise noted. http://www.hacktivismo.com/about/hessla.php
The official ImageMagick documentation provides good light on what these values indicate. ( http://www.imagemagick.org/RMagick/doc/constants.html#RenderingIntent ) Undefined means "no intent," Saturation means "A rendering intent that specifies the saturation of the pixels in the image is preserved perhaps at the expense of accuracy in hue and lightness," Perceptual Intent means "A rendering intent that specifies the full gamut of the image is compressed or expanded to fill the gamut of the destination device. Gray balance is preserved but colorimetric accuracy might not be preserved," Absolute Intent means "Absolute colorimetric," and Relative Intent means "Relative colorimetric."
Every time I ran this function, it always produced the same result: #2, indicating Perceptual Intent. But this makes sense, since the ImageMagick documentation notes about the Rendering Intent, "Typically, the user or application will set the rendering intent dynamically at runtime or embedding time." The ImageMagick documentation also recommended the following link to better understand Rendering Intent in terms of Colorspace Profiles: http://www.cambridgeincolour.com/tutorials/color-space-conversion.htm .
Some sample code :
<?php
// Author: holdoffhunger@gmail.com
// Imagick Type
// ---------------------------------------------
$imagick_type = new Imagick();
// Open File
// ---------------------------------------------
$file_to_grab = "image_workshop_directory/test.jpg";
$file_handle_for_viewing_image_file = fopen($file_to_grab, 'a+');
// Grab File
// ---------------------------------------------
$imagick_type->readImageFile($file_handle_for_viewing_image_file);
// Get Rendering Intent Values
// ---------------------------------------------
$imagick_rendering_intent = $imagick_type->getImageRenderingIntent();
switch($imagick_rendering_intent)
{
case '0':
$image_rendering_intent_evaluated = "Undefined";
break;
case '1':
$image_rendering_intent_evaluated = "Saturation";
break;
case '2':
$image_rendering_intent_evaluated = "Perceptual";
break;
case '3':
$image_rendering_intent_evaluated = "Absolute";
break;
case '4':
$image_rendering_intent_evaluated = "Relative";
break;
}
// Print Rendering Intent Values
// ---------------------------------------------
print("# $imagick_rendering_intent - $image_rendering_intent_evaluated");
?>
Official Function Page: http://www.php.net/manual/en/imagick.getimagerenderingintent.php
// Note: All code appearing on the PHP Revolution blog by the blog owner is released under the Hacktivismo Enhanced-Source Software License Agreement (HESSLA), unless otherwise noted. http://www.hacktivismo.com/about/hessla.php
Sunday, July 1, 2012
Image Orientation in the ImageMagick Package of PHP
Using the getImageOrientation function, you'll get the Orientation value for an image as defined within the EXIF file format. That means you will get back an integer representation one of the Orientation constants for ImageMagick, which looks like " imagick::ORIENTATION_UNDEFINED", with "_VALUE" values of: undefined (0), topleft (1), topright (2), bottomright (3), bottomleft (4), lefttop (5), righttop (6), rightbottom (7), and leftbottom (8). When printed out directly, these predefined constants produce the number in parenthesis. The undefined being set to 0 makes sense, since -- according to Wikipedia -- EXIF allows for eight possible values for an image (and not every image has a set of EXIF properties).
The EXIF Orientation is also called "the Rotation," again, according to Wikipedia: http://en.wikipedia.org/wiki/Exchangeable_image_file_format . What's the point of that? According to the official ImageMagick documentation, it's to rotate a photograph so that it is properly oriented after the shot. This really seems to be a camera thing, since the ImageMagick documentation mentions: "If you pointed your camera almost straight up or down, the EXIF orientation setting may not resolve correctly. The same goes for angled or slanted shots. The orientation (and cameras) just have no senses for these situations." ( http://www.imagemagick.org/Usage/photos/ )
If you're having trouble getting this function to show the value for Image Orientation, then use the function and parameters of getImageProperties('*', FALSE); . This produces an array of all properties associated with an image, and one of them will have the key value of exif:Orientation. If it doesn't, then that means you will be getting back a zero from this function, indicating an "Undefined" orientation.
Some sample code :
<?php
// Author: holdoffhunger@gmail.com
// Imagick Type
// ---------------------------------------------
$imagick_type = new Imagick();
// Open File
// ---------------------------------------------
$file_to_grab = "image_workshop_directory/test.jpg";
$file_handle_for_viewing_image_file = fopen($file_to_grab, 'a+');
// Grab File
// ---------------------------------------------
$imagick_type->readImageFile($file_handle_for_viewing_image_file);
// Get Orientation Values
// ---------------------------------------------
$imagick_orientation = $imagick_type->getImageOrientation();
switch($imagick_orientation)
{
case '0':
$imagick_orientation_evaluated = "Undefined";
break;
case '1':
$imagick_orientation_evaluated = "Top-Left";
break;
case '2':
$imagick_orientation_evaluated = "Top-Right";
break;
case '3':
$imagick_orientation_evaluated = "Bottom-Right";
break;
case '4':
$imagick_orientation_evaluated = "Bottom-Left";
break;
case '5':
$imagick_orientation_evaluated = "Left-Top";
break;
case '6':
$imagick_orientation_evaluated = "Right-Top";
break;
case '7':
$imagick_orientation_evaluated = "Right-Bottom";
break;
case '8':
$imagick_orientation_evaluated = "Left-Bottom";
break;
}
// Print Orientation Values
// ---------------------------------------------
print("# $imagick_orientation - $imagick_orientation_evaluated");
?>
Official Function Page: http://www.php.net/manual/en/imagick.getimageorientation.php
// Note: All code appearing on the PHP Revolution blog by the blog owner is released under the Hacktivismo Enhanced-Source Software License Agreement (HESSLA), unless otherwise noted. http://www.hacktivismo.com/about/hessla.php
The EXIF Orientation is also called "the Rotation," again, according to Wikipedia: http://en.wikipedia.org/wiki/Exchangeable_image_file_format . What's the point of that? According to the official ImageMagick documentation, it's to rotate a photograph so that it is properly oriented after the shot. This really seems to be a camera thing, since the ImageMagick documentation mentions: "If you pointed your camera almost straight up or down, the EXIF orientation setting may not resolve correctly. The same goes for angled or slanted shots. The orientation (and cameras) just have no senses for these situations." ( http://www.imagemagick.org/Usage/photos/ )
If you're having trouble getting this function to show the value for Image Orientation, then use the function and parameters of getImageProperties('*', FALSE); . This produces an array of all properties associated with an image, and one of them will have the key value of exif:Orientation. If it doesn't, then that means you will be getting back a zero from this function, indicating an "Undefined" orientation.
Some sample code :
<?php
// Author: holdoffhunger@gmail.com
// Imagick Type
// ---------------------------------------------
$imagick_type = new Imagick();
// Open File
// ---------------------------------------------
$file_to_grab = "image_workshop_directory/test.jpg";
$file_handle_for_viewing_image_file = fopen($file_to_grab, 'a+');
// Grab File
// ---------------------------------------------
$imagick_type->readImageFile($file_handle_for_viewing_image_file);
// Get Orientation Values
// ---------------------------------------------
$imagick_orientation = $imagick_type->getImageOrientation();
switch($imagick_orientation)
{
case '0':
$imagick_orientation_evaluated = "Undefined";
break;
case '1':
$imagick_orientation_evaluated = "Top-Left";
break;
case '2':
$imagick_orientation_evaluated = "Top-Right";
break;
case '3':
$imagick_orientation_evaluated = "Bottom-Right";
break;
case '4':
$imagick_orientation_evaluated = "Bottom-Left";
break;
case '5':
$imagick_orientation_evaluated = "Left-Top";
break;
case '6':
$imagick_orientation_evaluated = "Right-Top";
break;
case '7':
$imagick_orientation_evaluated = "Right-Bottom";
break;
case '8':
$imagick_orientation_evaluated = "Left-Bottom";
break;
}
// Print Orientation Values
// ---------------------------------------------
print("# $imagick_orientation - $imagick_orientation_evaluated");
?>
Official Function Page: http://www.php.net/manual/en/imagick.getimageorientation.php
// Note: All code appearing on the PHP Revolution blog by the blog owner is released under the Hacktivismo Enhanced-Source Software License Agreement (HESSLA), unless otherwise noted. http://www.hacktivismo.com/about/hessla.php
Tuesday, June 26, 2012
Alternate Hash Algorithms for ImageMagick's GetImageSignature in PHP
The getImageSignature function for the ImageMagick package in PHP returns only the SHA-256 hash value for an image. There are not any other algorithms available for it within the ImageMagick package, but fortunately, this is PHP and you have a wide array of hashing algorithms to use on any image file. The function hash_algos() will return an array of hashing algorithms available in PHP and the function hash_file() will take three parameters (one for the algorithm to use, one for the filename, and an optional variable for binary output). Instead of being limited to the SHA-256 algorithm of the getImageSignature function, you could use SHA-1, SHA-384, SHA-512, Whirlpool, HAVAL, Salsa, Gost, Adler32, CRC32, or MD5, among others and variations of these.
However, the SHA-256 result of the hash_file() function performed on a file does not return the same result as the SHA-256 of the getImageSignature() function. This leads me to believe that the SHA-256 of the getImageSignature() might be performed on the Imagick object itself, instead of the file, whereas the hash_file() function is clearly performed on the file itself. That's just a guess, though.
Some sample code for the alternate hashing algorithm, with every algorithm performed on the image file :
<?php
// Author: holdoffhunger@gmail.com
// Set File for Hashing Function
// ---------------------------------------------------
$filename_with_folder_for_hashing = "image_workshop/test_file.bmp";
// Acquire Dynamic Hashing Algorithm List
// ---------------------------------------------------
$php_dynamic_hash_algorithms = hash_algos();
// Count Dynamic Hashing Algorithm List
// ---------------------------------------------------
$number_of_dynamic_hash_algorithms = count($php_dynamic_hash_algorithms);
// Parse Dynamic Hashing Algorithm List
// ---------------------------------------------------
for($i = 0; $i < $number_of_dynamic_hash_algorithms; $i++)
{
// Get Current Hashing Algorithm
// ---------------------------------------------------
$current_hashing_algorithm = $php_dynamic_hash_algorithms[$i];
// Perform Hashing on File
// ---------------------------------------------------
$current_hashing_algorithm_hex_result = hash_file($current_hashing_algorithm, $filename_with_folder_for_hashing, FALSE);
// Print Hashed Results
// ---------------------------------------------------
print("$current_hashing_algorithm Algorithm ::: $current_hashing_algorithm_hex_result");
print("<br><br>");
}
?>
Example Results:
...........................
md2 Algorithm ::: 03205df9c6717d74f1f003c66f58e98a
md4 Algorithm ::: b2a204a2e5c3968d2abd5dc372fbee10
md5 Algorithm ::: b9d92a61714b221d24c7730d4764ca82
sha1 Algorithm ::: 8db4c92346c26568b13ea43fbcf514e37942a41a
(and so on for 34 more algorithms)...
Official Function Page: http://www.php.net/manual/en/imagick.getimagesignature.php
// Note: All code appearing on the PHP Revolution blog by the blog owner is released under the Hacktivismo Enhanced-Source Software License Agreement (HESSLA), unless otherwise noted. http://www.hacktivismo.com/about/hessla.php
However, the SHA-256 result of the hash_file() function performed on a file does not return the same result as the SHA-256 of the getImageSignature() function. This leads me to believe that the SHA-256 of the getImageSignature() might be performed on the Imagick object itself, instead of the file, whereas the hash_file() function is clearly performed on the file itself. That's just a guess, though.
Some sample code for the alternate hashing algorithm, with every algorithm performed on the image file :
<?php
// Author: holdoffhunger@gmail.com
// Set File for Hashing Function
// ---------------------------------------------------
$filename_with_folder_for_hashing = "image_workshop/test_file.bmp";
// Acquire Dynamic Hashing Algorithm List
// ---------------------------------------------------
$php_dynamic_hash_algorithms = hash_algos();
// Count Dynamic Hashing Algorithm List
// ---------------------------------------------------
$number_of_dynamic_hash_algorithms = count($php_dynamic_hash_algorithms);
// Parse Dynamic Hashing Algorithm List
// ---------------------------------------------------
for($i = 0; $i < $number_of_dynamic_hash_algorithms; $i++)
{
// Get Current Hashing Algorithm
// ---------------------------------------------------
$current_hashing_algorithm = $php_dynamic_hash_algorithms[$i];
// Perform Hashing on File
// ---------------------------------------------------
$current_hashing_algorithm_hex_result = hash_file($current_hashing_algorithm, $filename_with_folder_for_hashing, FALSE);
// Print Hashed Results
// ---------------------------------------------------
print("$current_hashing_algorithm Algorithm ::: $current_hashing_algorithm_hex_result");
print("<br><br>");
}
?>
Example Results:
...........................
md2 Algorithm ::: 03205df9c6717d74f1f003c66f58e98a
md4 Algorithm ::: b2a204a2e5c3968d2abd5dc372fbee10
md5 Algorithm ::: b9d92a61714b221d24c7730d4764ca82
sha1 Algorithm ::: 8db4c92346c26568b13ea43fbcf514e37942a41a
(and so on for 34 more algorithms)...
Official Function Page: http://www.php.net/manual/en/imagick.getimagesignature.php
// Note: All code appearing on the PHP Revolution blog by the blog owner is released under the Hacktivismo Enhanced-Source Software License Agreement (HESSLA), unless otherwise noted. http://www.hacktivismo.com/about/hessla.php
Friday, June 22, 2012
Determine Clipping Path Defaults for an Image in PHP with ImageMagick
By using the PHP function for getImageUnits, you get back an integer representing the evaluation of a predefined, PATHUNITS constant of the ImageMagick package. You only have four values for this. They look like "imagick::PATHUNITS_UNDEFINED", with _VALUE value's being: undefined, userspace, userspaceonuse, and objectboundingbox. Undefined, if printed, is a 0, userspace is a 1, userspaceonuse is a 2, and objectboundingbox is a 3.
What's the use of knowing the Clipping Path Unit default for an image? According to the Wikipedia article for "Clipping Path", a Clipping Path is "a closed vector path, or shape, used to cut out a 2D image in image editing software. Anything inside the path will be included after the clipping path is applied; anything outside the path will be omitted from the output."
The official ImageMagick documentation provides only two valid values coming into or out of the clipping path unit value, one being userSpaceOnUse and the other being ObjectBoundingBox. The only definitions provided: "If userSpaceOnUse, the contents of the clipping path represent values in the current user coordinate system in place at the time when the clipping path is referenced. if objectBoundingBox, then the user coordinate system for the contents of the clipping path is established using the bounding box of the object to which the clipping path is applied. The default is userSpaceOnUse." http://www.imagemagick.org/RMagick/doc/rvgclip.html
In personal experimentation, all JPEG and GIF files have provided '0' for "Undefined" on this function, and all BMP and PNG files have provided '2' for "UserSpaceOnUse" on this function.
And some sample code :
<?php
// Author: holdoffhunger@gmail.com
// Imagick Type
// ---------------------------------------------
$imagick_type = new Imagick();
// Open File
// ---------------------------------------------
$file_to_grab = "image_workshop_directory/test.gif";
$file_handle_for_viewing_image_file = fopen($file_to_grab, 'a+');
// Grab File
// ---------------------------------------------
$imagick_type->readImageFile($file_handle_for_viewing_image_file);
// Get Image Units
// ---------------------------------------------
$image_page = $imagick_type->getImageUnits();
// Interpret Units Value
// ---------------------------------------------
switch($image_units)
{
case imagick::PATHUNITS_UNDEFINED:
$image_units_printable = "Undefined";
break;
case imagick::PATHUNITS_USERSPACE:
$image_units_printable = "User Space";
break;
case imagick::PATHUNITS_USERSPACEONUSE:
$image_units_printable = "User Space On Use";
break;
case imagick::PATHUNITS_OBJECTBOUNDINGBOX:
$image_units_printable = "Object Bounding Box";
break;
}
// Print Units Value
// ---------------------------------------------
print(" Image Units: # $image_units -- $image_units_printable .");
?>
Official Function Page: http://www.php.net/manual/en/imagick.getimageunits.php
// Note: All code appearing on the PHP Revolution blog by the blog owner is released under the Hacktivismo Enhanced-Source Software License Agreement (HESSLA), unless otherwise noted. http://www.hacktivismo.com/about/hessla.php
What's the use of knowing the Clipping Path Unit default for an image? According to the Wikipedia article for "Clipping Path", a Clipping Path is "a closed vector path, or shape, used to cut out a 2D image in image editing software. Anything inside the path will be included after the clipping path is applied; anything outside the path will be omitted from the output."
The official ImageMagick documentation provides only two valid values coming into or out of the clipping path unit value, one being userSpaceOnUse and the other being ObjectBoundingBox. The only definitions provided: "If userSpaceOnUse, the contents of the clipping path represent values in the current user coordinate system in place at the time when the clipping path is referenced. if objectBoundingBox, then the user coordinate system for the contents of the clipping path is established using the bounding box of the object to which the clipping path is applied. The default is userSpaceOnUse." http://www.imagemagick.org/RMagick/doc/rvgclip.html
In personal experimentation, all JPEG and GIF files have provided '0' for "Undefined" on this function, and all BMP and PNG files have provided '2' for "UserSpaceOnUse" on this function.
And some sample code :
<?php
// Author: holdoffhunger@gmail.com
// Imagick Type
// ---------------------------------------------
$imagick_type = new Imagick();
// Open File
// ---------------------------------------------
$file_to_grab = "image_workshop_directory/test.gif";
$file_handle_for_viewing_image_file = fopen($file_to_grab, 'a+');
// Grab File
// ---------------------------------------------
$imagick_type->readImageFile($file_handle_for_viewing_image_file);
// Get Image Units
// ---------------------------------------------
$image_page = $imagick_type->getImageUnits();
// Interpret Units Value
// ---------------------------------------------
switch($image_units)
{
case imagick::PATHUNITS_UNDEFINED:
$image_units_printable = "Undefined";
break;
case imagick::PATHUNITS_USERSPACE:
$image_units_printable = "User Space";
break;
case imagick::PATHUNITS_USERSPACEONUSE:
$image_units_printable = "User Space On Use";
break;
case imagick::PATHUNITS_OBJECTBOUNDINGBOX:
$image_units_printable = "Object Bounding Box";
break;
}
// Print Units Value
// ---------------------------------------------
print(" Image Units: # $image_units -- $image_units_printable .");
?>
Official Function Page: http://www.php.net/manual/en/imagick.getimageunits.php
// Note: All code appearing on the PHP Revolution blog by the blog owner is released under the Hacktivismo Enhanced-Source Software License Agreement (HESSLA), unless otherwise noted. http://www.hacktivismo.com/about/hessla.php
Monday, May 28, 2012
Yet Another Way for Detecting Height x Width for an Image in PHP with ImageMagick
The PHP function 'getImagePage' will return values indicating the height and width of an image, just like the getHeight and getWidth, except these values are returned as an array. There's also two other values returned in the array with the key values of 'x' and 'y'. After running this function on animated .Gif's, super-compressed jpeg's, bmp's, png's, and every type of awkward file format you could think of, I kept getting back the result of '0' for both the 'x' and 'y' associated values in the returned array. It's likely that these indicate the "start-positions" of the width and height, compared to the "end-values" you receive for accessing the values associated with the keys 'width' and 'height'.
Oddly enough, the PHP function 'getPage' will return an array with the same exact keys, except the values all default to '0', making it much less useful than the function 'getImagePage'.
And some sample code :
<?php
// Author: holdoffhunger@gmail.com
// Imagick Type
// ---------------------------------------------
$imagick_type = new Imagick();
// Open File
// ---------------------------------------------
$file_to_grab = "image_workshop_directory/test.gif";
$file_handle_for_viewing_image_file = fopen($file_to_grab, 'a+');
// Grab File
// ---------------------------------------------
$imagick_type->readImageFile($file_handle_for_viewing_image_file);
// Get Image Page
// ---------------------------------------------
$image_page = $imagick_type->getImagePage();
// Print Iteration Value Interpreted
// ---------------------------------------------
print_r($image_page);
?>
Expected Result :
Array
(
[width] => 600
[height] => 450
[x] => 0
[y] => 0
)
Official Function Page: http://www.php.net/manual/en/imagick.getimagepage.php
// Note: All code appearing on the PHP Revolution blog by the blog owner is released under the Hacktivismo Enhanced-Source Software License Agreement (HESSLA), unless otherwise noted. http://www.hacktivismo.com/about/hessla.php
Oddly enough, the PHP function 'getPage' will return an array with the same exact keys, except the values all default to '0', making it much less useful than the function 'getImagePage'.
And some sample code :
<?php
// Author: holdoffhunger@gmail.com
// Imagick Type
// ---------------------------------------------
$imagick_type = new Imagick();
// Open File
// ---------------------------------------------
$file_to_grab = "image_workshop_directory/test.gif";
$file_handle_for_viewing_image_file = fopen($file_to_grab, 'a+');
// Grab File
// ---------------------------------------------
$imagick_type->readImageFile($file_handle_for_viewing_image_file);
// Get Image Page
// ---------------------------------------------
$image_page = $imagick_type->getImagePage();
// Print Iteration Value Interpreted
// ---------------------------------------------
print_r($image_page);
?>
Expected Result :
Array
(
[width] => 600
[height] => 450
[x] => 0
[y] => 0
)
Official Function Page: http://www.php.net/manual/en/imagick.getimagepage.php
// Note: All code appearing on the PHP Revolution blog by the blog owner is released under the Hacktivismo Enhanced-Source Software License Agreement (HESSLA), unless otherwise noted. http://www.hacktivismo.com/about/hessla.php
Saturday, May 26, 2012
Detecting an Animate-able Image in PHP for Linux Server Image-Processing
By using the PHP function getImageIterations, you'll receive back a value indicating the animated nature of the image. You'll get back a '0' for a still image that is not animate-able (like a .BMP or a .JPEG file) and a '1' for an animate-able image (like an animated .GIF file).
I have been unable to get any other results from this function, after extensive use. There is some discussion among the ImageMagick user's group saying that the Iterations should indicate the number of times an animated .Gif file repeats itself. However, it's possible that either modern browsers default the value to infinity or that this ImageMagick functionality is only available at the Linux command-line. See more at the discussion group here: http://studio.imagemagick.org/pipermail/magick-users/2002-October/005814.html
And some sample code :
<?php
// Author: holdoffhunger@gmail.com
// Imagick Type
// ---------------------------------------------
$imagick_type = new Imagick();
// Open File
// ---------------------------------------------
$file_to_grab = "image_workshop_directory/test.gif";
$file_handle_for_viewing_image_file = fopen($file_to_grab, 'a+');
// Grab File
// ---------------------------------------------
$imagick_type->readImageFile($file_handle_for_viewing_image_file);
// Get Image Iterations
// (Detect Animated Image Versus Non-Animated Image)
// ---------------------------------------------
$image_iterations = $imagick_type->getImageIterations();
// Print Iteration Value Interpreted
// ---------------------------------------------
if($image_iterations == 1)
{
print("$file_to_grab *IS* an animate-able image.");
}
else
{
print("$file_to_grab *IS NOT* an animate-able image.");
}
?>
Official Function Page: http://www.php.net/manual/en/imagick.getimageiterations.php
// Note: All code appearing on the PHP Revolution blog by the blog owner is released under the Hacktivismo Enhanced-Source Software License Agreement (HESSLA), unless otherwise noted. http://www.hacktivismo.com/about/hessla.php
I have been unable to get any other results from this function, after extensive use. There is some discussion among the ImageMagick user's group saying that the Iterations should indicate the number of times an animated .Gif file repeats itself. However, it's possible that either modern browsers default the value to infinity or that this ImageMagick functionality is only available at the Linux command-line. See more at the discussion group here: http://studio.imagemagick.org/pipermail/magick-users/2002-October/005814.html
And some sample code :
<?php
// Author: holdoffhunger@gmail.com
// Imagick Type
// ---------------------------------------------
$imagick_type = new Imagick();
// Open File
// ---------------------------------------------
$file_to_grab = "image_workshop_directory/test.gif";
$file_handle_for_viewing_image_file = fopen($file_to_grab, 'a+');
// Grab File
// ---------------------------------------------
$imagick_type->readImageFile($file_handle_for_viewing_image_file);
// Get Image Iterations
// (Detect Animated Image Versus Non-Animated Image)
// ---------------------------------------------
$image_iterations = $imagick_type->getImageIterations();
// Print Iteration Value Interpreted
// ---------------------------------------------
if($image_iterations == 1)
{
print("$file_to_grab *IS* an animate-able image.");
}
else
{
print("$file_to_grab *IS NOT* an animate-able image.");
}
?>
Official Function Page: http://www.php.net/manual/en/imagick.getimageiterations.php
// Note: All code appearing on the PHP Revolution blog by the blog owner is released under the Hacktivismo Enhanced-Source Software License Agreement (HESSLA), unless otherwise noted. http://www.hacktivismo.com/about/hessla.php
Wednesday, May 23, 2012
Get the Maximum Memory Use Allowed in PHP for Linux Server Image-Processing
By using the PHP function getResourceLimit, you'll be given the maximum allowed amount of a particular type of resource. The integer returned is the number of bytes allowed to the resource you specified in the input parameter. For the input parameter options, you have the predefined ResourceType constants for the ImageMagick package. In the code, they look like imagick::RESOURCETYPE_AREA, but you have "_VALUE" options of: undefined, area, disk, file, map, and memory.
What do each of these particular values represent? The ImageMagick official documentation is helpful in that matter. File indicates "maximum number of open pixel cache files", Area indicates "maximum area in bytes of any one image that can reside in the pixel cache memory", Memory indicates "maximum amount of memory in bytes to allocate for the pixel cache", map indicates "maximum amount of memory map in bytes to allocate for the pixel cache", and disk indicates "maximum amount of disk space in bytes permitted for use by the pixel cache". This is according to the Official ImageMagick Architecture page: http://www.imagemagick.org/script/architecture.php .
The Official ImageMagick Resource page has more information on how these parameters function. For instance, the files limit documentation mentions that when a user goes over the limit, any more files that are "cached to disk are closed and reopened on demand." (Again, a performance hit.) See that page here: http://www.imagemagick.org/script/resources.php .
What happens when someone exceeds their limit? It doesn't cause the PHP script to error out, but simply, it relocates their user activity to non-cache memory (i.e.: virtual memory, which is slow). So, even if you're worried about the limit, it really only indicates the point in a server at which a user's request is devalued compared to other user requests.
And remember, you can always set the defaults in the policy.xml file on your own server.
Some sample code :
<?php
// Author: holdoffhunger@gmail.com
// Imagick Type
// ---------------------------------------------
$imagick_type = new Imagick();
// Open File
// ---------------------------------------------
$file_to_grab = "image_workshop_directory/test.gif";
$file_handle_for_viewing_image_file = fopen($file_to_grab, 'a+');
// Grab File
// ---------------------------------------------
$imagick_type->readImageFile($file_handle_for_viewing_image_file);
// Get/Display Resource Values
// ---------------------------------------------
print("Undefined: ");
print($imagick_type->getResourceLimit(imagick::RESOURCETYPE_UNDEFINED));
print("<br><br>Area: ");
print($imagick_type->getResourceLimit(imagick::RESOURCETYPE_AREA));
print("<br><br>Disk: ");
print($imagick_type->getResourceLimit(imagick::RESOURCETYPE_DISK));
print("<br><br>File: ");
print($imagick_type->getResourceLimit(imagick::RESOURCETYPE_FILE));
print("<br><br>Map: ");
print($imagick_type->getResourceLimit(imagick::RESOURCETYPE_MAP));
print("<br><br>Memory: ");
print($imagick_type->getResourceLimit(imagick::RESOURCETYPE_MEMORY));
?>
Official Function Page: http://www.php.net/manual/en/imagick.getresourcelimit.php
// Note: All code appearing on the PHP Revolution blog by the blog owner is released under the Hacktivismo Enhanced-Source Software License Agreement (HESSLA), unless otherwise noted. http://www.hacktivismo.com/about/hessla.php
What do each of these particular values represent? The ImageMagick official documentation is helpful in that matter. File indicates "maximum number of open pixel cache files", Area indicates "maximum area in bytes of any one image that can reside in the pixel cache memory", Memory indicates "maximum amount of memory in bytes to allocate for the pixel cache", map indicates "maximum amount of memory map in bytes to allocate for the pixel cache", and disk indicates "maximum amount of disk space in bytes permitted for use by the pixel cache". This is according to the Official ImageMagick Architecture page: http://www.imagemagick.org/script/architecture.php .
The Official ImageMagick Resource page has more information on how these parameters function. For instance, the files limit documentation mentions that when a user goes over the limit, any more files that are "cached to disk are closed and reopened on demand." (Again, a performance hit.) See that page here: http://www.imagemagick.org/script/resources.php .
What happens when someone exceeds their limit? It doesn't cause the PHP script to error out, but simply, it relocates their user activity to non-cache memory (i.e.: virtual memory, which is slow). So, even if you're worried about the limit, it really only indicates the point in a server at which a user's request is devalued compared to other user requests.
And remember, you can always set the defaults in the policy.xml file on your own server.
Some sample code :
<?php
// Author: holdoffhunger@gmail.com
// Imagick Type
// ---------------------------------------------
$imagick_type = new Imagick();
// Open File
// ---------------------------------------------
$file_to_grab = "image_workshop_directory/test.gif";
$file_handle_for_viewing_image_file = fopen($file_to_grab, 'a+');
// Grab File
// ---------------------------------------------
$imagick_type->readImageFile($file_handle_for_viewing_image_file);
// Get/Display Resource Values
// ---------------------------------------------
print("Undefined: ");
print($imagick_type->getResourceLimit(imagick::RESOURCETYPE_UNDEFINED));
print("<br><br>Area: ");
print($imagick_type->getResourceLimit(imagick::RESOURCETYPE_AREA));
print("<br><br>Disk: ");
print($imagick_type->getResourceLimit(imagick::RESOURCETYPE_DISK));
print("<br><br>File: ");
print($imagick_type->getResourceLimit(imagick::RESOURCETYPE_FILE));
print("<br><br>Map: ");
print($imagick_type->getResourceLimit(imagick::RESOURCETYPE_MAP));
print("<br><br>Memory: ");
print($imagick_type->getResourceLimit(imagick::RESOURCETYPE_MEMORY));
?>
Official Function Page: http://www.php.net/manual/en/imagick.getresourcelimit.php
// Note: All code appearing on the PHP Revolution blog by the blog owner is released under the Hacktivismo Enhanced-Source Software License Agreement (HESSLA), unless otherwise noted. http://www.hacktivismo.com/about/hessla.php
Tuesday, May 22, 2012
Get the Number of Frames in a GIF File in PHP with the ImageMagick Package
The getIteratorIndex function of the ImageMagick function works on any type of image, but it is built for measuring the number of frames in an animated .gif file. For non-animated image files, like regular .bmp or .jpg files, this function will always return the number '0', meaning that there is only one frame. Counting starts from zero with this function, so a .gif file with five different frames will return a value of '4' on this. Highly repetitive, but psychedelic animated GIF's are often anywhere between 10 and 30 frames, but a .gif file that is nothing more than video footage converted to a datafile may have hundreds of frames.
According to Wikipedia (in the article for "Graphics Interchange Format"), an animated GIf image is an image that uses the GIF standard "which allows various images (frames) in the file to be painted with time delays." This function won't get you the amount of time that delays between each frame, but it will give you the number of unique frames in a .gif file. This will tell you how complicated or simple the animation may be.
Is the 'getIteratorIndex' function not working for you? Try the 'getImageIndex' function, which produces the same exact result.
Some sample code :
<?php
// Author: holdoffhunger@gmail.com
// Imagick Type
// ---------------------------------------------
$imagick_type = new Imagick();
// Open File
// ---------------------------------------------
$file_to_grab = "image_workshop_directory/test.gif";
$file_handle_for_viewing_image_file = fopen($file_to_grab, 'a+');
// Grab File
// ---------------------------------------------
$imagick_type->readImageFile($file_handle_for_viewing_image_file);
// Get Image Type Value
// ---------------------------------------------
$image_iterator_index = $imagick_type->getIteratorIndex();
// Print Image Type Value
// ---------------------------------------------
print("Number of Unique Frames in the .GIF File: $image_iterator_index");
?>
Official Function Page: http://www.php.net/manual/en/imagick.getiteratorindex.php
// Note: All code appearing on the PHP Revolution blog by the blog owner is released under the Hacktivismo Enhanced-Source Software License Agreement (HESSLA), unless otherwise noted. http://www.hacktivismo.com/about/hessla.php
According to Wikipedia (in the article for "Graphics Interchange Format"), an animated GIf image is an image that uses the GIF standard "which allows various images (frames) in the file to be painted with time delays." This function won't get you the amount of time that delays between each frame, but it will give you the number of unique frames in a .gif file. This will tell you how complicated or simple the animation may be.
Is the 'getIteratorIndex' function not working for you? Try the 'getImageIndex' function, which produces the same exact result.
Some sample code :
<?php
// Author: holdoffhunger@gmail.com
// Imagick Type
// ---------------------------------------------
$imagick_type = new Imagick();
// Open File
// ---------------------------------------------
$file_to_grab = "image_workshop_directory/test.gif";
$file_handle_for_viewing_image_file = fopen($file_to_grab, 'a+');
// Grab File
// ---------------------------------------------
$imagick_type->readImageFile($file_handle_for_viewing_image_file);
// Get Image Type Value
// ---------------------------------------------
$image_iterator_index = $imagick_type->getIteratorIndex();
// Print Image Type Value
// ---------------------------------------------
print("Number of Unique Frames in the .GIF File: $image_iterator_index");
?>
Official Function Page: http://www.php.net/manual/en/imagick.getiteratorindex.php
// Note: All code appearing on the PHP Revolution blog by the blog owner is released under the Hacktivismo Enhanced-Source Software License Agreement (HESSLA), unless otherwise noted. http://www.hacktivismo.com/about/hessla.php
Monday, May 21, 2012
Understanding Image Type in PHP with the ImageMagick Package
The function PHP 'getImageType' will return an integer, with that value being equal to the evaluated value of the IMGType Constants as defined by the ImageMagick class. When accessing them, they look like "imagick::IMGTYPE_PALETTE", but with "_VALUE" values of: undefined, bilevel, grayscale, grayscalematte, palette, palettematte, truecolor, truecolormatte, colorseparation, colorseparationmatte, and optimize. If you were to print out these values, you would have '0' for undefined, '1' for bilevel, '2' for grayscale, and so on.
For a BMP picture drawn in paint, I got back the value # 4 - Palette. For a BMP or JPEG photograph of the ocean or jungle, I got back the value # 6 - Truecolor. For an animated GIF file, I got back the value # 5 - Palette Matte. For a black-and-white JPEG drawing, I got back the value # 2 - Grayscale. These are the most common results I have gotten back with this function.
Some sample code :
<?php
// Author: holdoffhunger@gmail.com
// Imagick Type
// ---------------------------------------------
$imagick_type = new Imagick();
// Open File
// ---------------------------------------------
$file_to_grab = "image_workshop_directory/test.bmp";
$file_handle_for_viewing_image_file = fopen($file_to_grab, 'a+');
// Grab File
// ---------------------------------------------
$imagick_type->readImageFile($file_handle_for_viewing_image_file);
// Get Image Type Value
// ---------------------------------------------
$image_type = $imagick_type->getImageType();
// Interpret Image Type Value
// ---------------------------------------------
switch($image_type)
{
case imagick::IMGTYPE_UNDEFINED:
$image_type_title = "Undefined";
break;
case imagick::IMGTYPE_BILEVEL:
$image_type_title = "Bilevel";
break;
case imagick::IMGTYPE_GRAYSCALE:
$image_type_title = "Grayscale";
break;
case imagick::IMGTYPE_GRAYSCALEMATTE:
$image_type_title = "Grayscale Matte";
break;
case imagick::IMGTYPE_PALETTE:
$image_type_title = "Palette";
break;
case imagick::IMGTYPE_PALETTEMATTE:
$image_type_title = "Palette Matte";
break;
case imagick::IMGTYPE_TRUECOLOR:
$image_type_title = "Truecolor";
break;
case imagick::IMGTYPE_TRUECOLORMATTE:
$image_type_title = "Truecolor Matte";
break;
case imagick::IMGTYPE_COLORSEPARATION:
$image_type_title = "Color Separation";
break;
case imagick::IMGTYPE_COLORSEPARATIONMATTE:
$image_type_title = "Color Separation Matte";
break;
case imagick::IMGTYPE_OPTIMIZE:
$image_type_title = "Optimize";
break;
}
// Print Image Type Value
// ---------------------------------------------
print("# $image_type - $image_type_title");
?>
Official Function Page: http://www.php.net/manual/en/imagick.getimagetype.php
// Note: All code appearing on the PHP Revolution blog by the blog owner is released under the Hacktivismo Enhanced-Source Software License Agreement (HESSLA), unless otherwise noted. http://www.hacktivismo.com/about/hessla.php
For a BMP picture drawn in paint, I got back the value # 4 - Palette. For a BMP or JPEG photograph of the ocean or jungle, I got back the value # 6 - Truecolor. For an animated GIF file, I got back the value # 5 - Palette Matte. For a black-and-white JPEG drawing, I got back the value # 2 - Grayscale. These are the most common results I have gotten back with this function.
Some sample code :
<?php
// Author: holdoffhunger@gmail.com
// Imagick Type
// ---------------------------------------------
$imagick_type = new Imagick();
// Open File
// ---------------------------------------------
$file_to_grab = "image_workshop_directory/test.bmp";
$file_handle_for_viewing_image_file = fopen($file_to_grab, 'a+');
// Grab File
// ---------------------------------------------
$imagick_type->readImageFile($file_handle_for_viewing_image_file);
// Get Image Type Value
// ---------------------------------------------
$image_type = $imagick_type->getImageType();
// Interpret Image Type Value
// ---------------------------------------------
switch($image_type)
{
case imagick::IMGTYPE_UNDEFINED:
$image_type_title = "Undefined";
break;
case imagick::IMGTYPE_BILEVEL:
$image_type_title = "Bilevel";
break;
case imagick::IMGTYPE_GRAYSCALE:
$image_type_title = "Grayscale";
break;
case imagick::IMGTYPE_GRAYSCALEMATTE:
$image_type_title = "Grayscale Matte";
break;
case imagick::IMGTYPE_PALETTE:
$image_type_title = "Palette";
break;
case imagick::IMGTYPE_PALETTEMATTE:
$image_type_title = "Palette Matte";
break;
case imagick::IMGTYPE_TRUECOLOR:
$image_type_title = "Truecolor";
break;
case imagick::IMGTYPE_TRUECOLORMATTE:
$image_type_title = "Truecolor Matte";
break;
case imagick::IMGTYPE_COLORSEPARATION:
$image_type_title = "Color Separation";
break;
case imagick::IMGTYPE_COLORSEPARATIONMATTE:
$image_type_title = "Color Separation Matte";
break;
case imagick::IMGTYPE_OPTIMIZE:
$image_type_title = "Optimize";
break;
}
// Print Image Type Value
// ---------------------------------------------
print("# $image_type - $image_type_title");
?>
Official Function Page: http://www.php.net/manual/en/imagick.getimagetype.php
// Note: All code appearing on the PHP Revolution blog by the blog owner is released under the Hacktivismo Enhanced-Source Software License Agreement (HESSLA), unless otherwise noted. http://www.hacktivismo.com/about/hessla.php
Understanding Image SHA-256 Hash Values in PHP with the ImageMagick Package
The getImageSignature function returns the SHA-256 hash value, which is 256 bits (or 32 bytes) in length. SHA-256 is part of the SHA-2 set of cryptographic hash functions designed by the NSA, which also includes SHA-224, SHA-384, and SHA-512. According to Wikipedia, there are some security flaws in it similar to the set of SHA-1 hash functions, which should be fixed with SHA-3, eventually. Unlike MD5 or the SHA-1 set of cryptographic functions, SHA-2 has had no collisions discovered yet (a collision is an incident where two different pieces of data result in the same hash value from the hashing function). For the time being, it seems to be the most efficient method for creating a small (32-byte), uniquely-identifiable, generally-secure value for either a file or a piece of data.
Some sample code :
<?php
// Author: holdoffhunger@gmail.com
// Imagick Type
// ---------------------------------------------
$imagick_type = new Imagick();
// Open File
// ---------------------------------------------
$file_to_grab = "image_workshop_directory/test.bmp";
$file_handle_for_viewing_image_file = fopen($file_to_grab, 'a+');
// Grab File
// ---------------------------------------------
$imagick_type->readImageFile($file_handle_for_viewing_image_file);
// Get Image SHA-256 Signature / Hash Value
// ---------------------------------------------
$imagick_type_signature = $imagick_type->getImageSignature();
// Print Image Signature / Hash Value
// ---------------------------------------------
print($imagick_type_signature);
?>
Results of this done on a standard BMP image :
cb2f387a7b23d11340ad1f5ba9c765125ea6b2d50a0d25412abe1ce568adac68
Official Function Page: http://www.php.net/manual/en/imagick.getimagesignature.php
// Note: All code appearing on the PHP Revolution blog by the blog owner is released under the Hacktivismo Enhanced-Source Software License Agreement (HESSLA), unless otherwise noted. http://www.hacktivismo.com/about/hessla.php
Some sample code :
<?php
// Author: holdoffhunger@gmail.com
// Imagick Type
// ---------------------------------------------
$imagick_type = new Imagick();
// Open File
// ---------------------------------------------
$file_to_grab = "image_workshop_directory/test.bmp";
$file_handle_for_viewing_image_file = fopen($file_to_grab, 'a+');
// Grab File
// ---------------------------------------------
$imagick_type->readImageFile($file_handle_for_viewing_image_file);
// Get Image SHA-256 Signature / Hash Value
// ---------------------------------------------
$imagick_type_signature = $imagick_type->getImageSignature();
// Print Image Signature / Hash Value
// ---------------------------------------------
print($imagick_type_signature);
?>
Results of this done on a standard BMP image :
cb2f387a7b23d11340ad1f5ba9c765125ea6b2d50a0d25412abe1ce568adac68
Official Function Page: http://www.php.net/manual/en/imagick.getimagesignature.php
// Note: All code appearing on the PHP Revolution blog by the blog owner is released under the Hacktivismo Enhanced-Source Software License Agreement (HESSLA), unless otherwise noted. http://www.hacktivismo.com/about/hessla.php
Subscribe to:
Comments (Atom)