Monday, April 30, 2012

Perform Artistic SketchImage Effect on Image using ImageMagick in PHP

This is a really neat function, definitely something for those into image manipulation in the style of Gimp/Photoshop effects.  The parameters are a bit unusual, though, and should be explained.

The "Radius of the Gaussian" (first parameter) is the width of the brush being used with the Sketch effect.  The "Standard Deviation of the Gaussian" (second parameter) is how often and to what extent there are "white space" areas between brush strokes.  If the Standard Deviation is big, the white areas are fewer but longer and deeper, but small, the white areas are many and tiny.  Too big, and it'll be too noticable an effect.  Do not that the higher the Standard Deviation goes, the significantly greater amount of time it takes to do the processing, compared to the other parameters.  The third parameter is the easiest: the angle.  That's just the angle that the brush strokes are drawn at uniformly throughout the image.  At 0, it's left-to-right, and at 90, it's up-and-down.  Don't forget you can use a negative degree to set the angle for this effect.  Ideally, you're probably going to want something between 30 and 60 degrees, if you're particularly aiming for an "artistic" effect.

And now, a sample demonstration on a 600 x 450 resolution image :

<?php

        // Grab Image File Data
        // ---------------------------------------------
       
    $file_to_grab_with_location = "image_workshop_directory/test.bmp";
   
    $imagick_type = new Imagick();
   
        // Open File
        // ---------------------------------------------
   
    $file_handle_for_viewing_image_file = fopen($file_to_grab_with_location, 'a+');

    $imagick_type->readImageFile($file_handle_for_viewing_image_file);

        // Perform Function
        // ---------------------------------------------

            // Gaussian Radius of 60 pixels,
            //   Gaussian Standard Deviation of 7 pixels,
            //   and Angle of -35 degrees.
   
    $imagick_type->sketchImage(60, 7, -35);
   
        // Filename
        // ---------------------------------------------
       
    $file_to_save_with_location = "image_workshop_directory/test_result.bmp";

        // Save File
        // ---------------------------------------------
   
    $file_handle_for_saving_image_file = fopen($file_to_save_with_location, 'a+');

    $imagick_type->writeImageFile($file_handle_for_saving_image_file);
       
?>

An example using the effect on an ocean picture from google image search...



Note:  This function is perfect for creating a "Rain Effect" to any picture.  Line it up to +/- 35 degrees or higher to get the optimal use out of it that way.

Note:  You'd think that this would make the drawing go into a black-gray-white scale, because it's a "sketch", but no, it actually retains the color.  That gives you the option to do more effects to it, like Posterize or OilImage.  Or, just convert it to a black and white scale to get a "true" Sketch effect.

Official Function Page: http://www.php.net/manual/en/imagick.sketchimage.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, April 29, 2012

Peform Polaroid-Image Effect on Image using ImageMagick in PHP

At first, the polaroidImage function looked amazingly simple.  "It must simply give a border of a specified color, and then rotate the given image by a certain number of degrees."  It actually turns out to be a really neat function.  Not only does it create an image that looks like a Polaroid of the targetted file, but it gives it a slight bend and curl that simulates a real, physical photograph.  On top of that, it gives a minor, fuzz shadow to some of the borders that accentuate the entire "effect" of looking at a real, 3d photograph.  There are some essentials to know, though!

The first parameter, $properties, has absolutely no effect upon the image that I can tell.  The official documentation, in this point, is absurdly incorrect.  Ignore the first parameter -- it's worthless.  I suspect that this is a miswrite, and what is implied is that you need to edit the properties of the Imagick class object that you're doing the PolaroidImage to.  There are two colors: the border of the image, and the color of shadow.  Both are set with the setImageBorderColor and setImageBackgroundColor functions, conveniently.  Unfortunately, this function still seems to demand a blank value for "properties", and NULL doesn't do it apparently.

One final note of precaution: the color of the surface that the photograph lies on defaults to black for BMP files, and then to white to PNG files. (Weird, huh?)  (Update:  This appears to be in how browsers decide to render opacity in the background of the image, which I have not figured out how to set in this function.)  Others have noticed this as well, on what appears to be the best source of info on this function: http://valokuva.org/?p=37 .

The angle rotates clockwise.  If you want to rotate counter-clockwise, it's easy: just use negative numbers, which this function accepts.

Now, for a brief demonstration of this function, with some fairly decent, standard parameters that should fit anyone's needs:

<?php

        // Grab Image File Data
        // ---------------------------------------------

    $file_to_grab_with_location = "image_workshop_directory/test.png"
   
        // Create ImageMagick Object Types
        // ---------------------------------------------

    $imagick_type = new Imagick();
    $draw_type = new ImagickDraw();
   
        // Open File
        // ---------------------------------------------
   
    $file_handle_for_viewing_image_file = fopen($file_to_grab_with_location, 'a+');

    $imagick_type->readImageFile($file_handle_for_viewing_image_file);

        // Perform Function: PolaroidImage
        // ---------------------------------------------

            // Polaroid Border Color:
            // ..............................................
   
    $imagick_type->setImageBorderColor( new ImagickPixel( "#CCCCCC" ) );

            // Polaroid Shadow Color:
            // ..............................................

    $imagick_type->setImageBackgroundColor( new ImagickPixel( "#000000" ) );

            // Call Function:
            // ..............................................

    $imagick_type->polaroidImage($draw_type, -10);
   
        // Save File
        // ---------------------------------------------
       
    $file_to_save_with_location = "image_workshop_directory/test_result.png"

    $file_handle_for_saving_image_file = fopen($file_to_save_with_location, 'a+');
    $imagick_type->writeImageFile($file_handle_for_saving_image_file);

?>

The following is an example using a GoogleImage search result for the word "Ocean":




Official Function Page: http://www.php.net/manual/en/imagick.polaroidimage.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

Peform Artistic Dithering-Posterize Effect on Image using ImageMagick in PHP

Originally, I thought the OrderedPosterizeImage function would be similar to the PosterizeImage function, or at least, any one of the Imagick class functions that produces an artistic effect (like the oilPaintImage function).  This function can be used for those purposes, but it is mostly geared toward print production.  The OrderedPosterize is simply a highly flexible dithering tool.  The intention essentially is to produce high-resolution imagery by means of using constant dots across a medium that vary in size according to the detail of the imagery.  Everyone has seen a dithered photograph inside of a newspaper, but the wiki page provides better examples: http://en.wikipedia.org/wiki/Dither .

The two parameters are unusual to someone who simply wants to get the use of this function without fussing too much about the Imagick class.

First parameter: The threshold_map is a set of "brushes" predefined by a very simple xml file.  They are: threshold, checks, o2x2, o3x3, o4x4, o8x8, h4x4a, h6x6a, h8x8a, h4x4o, h6x6o, h8x8o, h16x16o, c5x5b, c5x5w, c6x6b, c6x6w, c7x7b, and c7x7w.  These are the values you are expected to input as parameters for the Thershold_Map value.  Much better descriptions of these brush shapes available at the Imagick site: http://www.imagemagick.org/Usage/quantize/tmaps_list.txt .

Second parameter: The channel is any of the constants as predefined by the Imagick class.  In the code, the value looks like "imagick::CHANNEL_RED", but you have the "_value" options of: red, undefined, gray, cyan, green, magenta, blue, yellow, alpha, opacity, matte, black, index, all, and default.  More info here: http://www.php.net/manual/en/imagick.constants.php#imagick.constants.channel .

Finally, don't forget you can use bitwise operators on the second parameter.  That means you can use & to AND them, | to OR them, & to XOR them, and ~ to NEGATE them.  A valid parameter for the second parameter would be: "(((~imagick::CHANNEL_GREEN) ^ imagick::CHANNEL_YELLOW) | imagick::CHANNEL_MAGENTA)".  You can get extremely creative in this particular parameter.  And if you want to define your own brushes using simple XML, then that's also true of the first parameter, too.

Note:  You can use this function artistically.  How?  Use the orderedPosterizeImage to give the image some texture (a photo of a vase, for instance), and then use your OilPoint, Sketch, or Standard Posterize to give the image a cool effect.  Alone, though, seems pretty boring.

And now, a very simple demonstration :

<?php
   
        // Filename
        // ---------------------------------------------

    $file_to_grab_with_location = "graphics_engine/image_workshop_directory/ordered_posterize_source.bmp"
   
    $imagick_type = new Imagick();
   
        // Open File
        // ---------------------------------------------
   
    $file_handle_for_viewing_image_file = fopen($file_to_grab_with_location, 'a+');
   
    $imagick_type->readImageFile($file_handle_for_viewing_image_file);
   
        // Perform Function
        // ---------------------------------------------
   
    $imagick_type->orderedPosterizeImage("o2x2", imagick::CHANNEL_GREEN);
   
        // Save File
        // ---------------------------------------------

    $file_to_save_with_location = "graphics_engine/image_workshop_directory/ordered_posterize_result.bmp"
   
    $file_handle_for_saving_image_file = fopen($file_to_save_with_location, 'a+');
   
    $imagick_type->writeImageFile($file_handle_for_saving_image_file);

?>

The following is an example using a GoogleImage search result for the word "Ocean":



Official Function Page: http://www.php.net/manual/en/imagick.orderedposterizeimage.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

Giving a Charcoal Drawing Effect to an Image using ImageMagick in PHP

The PHP Function charcoalImage is really neat, but the parameters for this function are really scary.  Radius of the Gaussian and Standard Deviation of the Gaussian?  After playing with it for a little bit, I think I put it together.  The Gaussian is the "brush" (in Gimp/Photoshop jargin), the radius is simply the radius of the brush, and the standard deviation is the level of variation among the sizes of the brush imprints.  The $radius parameter can be anything from 0 to as high a number as you can think, but once you beyond 10, 20, or 30 pixels, depending on the image size, the whole image gets blurred beyond useful recognition.  The $sigma, being the standard deviation, should be smaller than your radius to get the desired effect.  Think of it as "Charcoal Brushes of $radius Pixels Size, with each brush being as much as $sigma Pixels bigger or smaller than that."

For an average 500 x 500 pixel image, you'll probably want a $radius of 3 to 5 and a $sigma of 1 to 3, but you can go as far as 10 pixels generally before the image is blurred beyond recognition.  (At the moment, $radius: 5 / $sigma: 2 is the perfect blend for this 400x400 image that I'm working on right now.)

There was not too help from the official documentation site for this project, either: http://www.imagemagick.org/RMagick/doc/image1.html .  The authors there note: "You can alter the intensity of the effect by changing the radius and sigma arguments."  So, my description here of the functioning is based mostly on experience rather than documentation, which is difficult to find.

The following is the entire code for applying the effect to an image.  This code will open the specified file, it will apply the charcoalImage effect to it, and then it will save it to another specified file.  The arguments are served up through POST data, and the only functions of the ImageMagick class that are used are the readImageFile, charcoalImage, and writeImageFile, as so :

<?php

        // Grab Inbound Data -- Function Parameters
        // --------------------------------------------------
       
    $inbound_gaussian_radius = $_POST['radius_of_gaussian'];
    $inbound_standard_deviation = $_POST['standard_deviation_of_gaussian'];

        // Grab Inbound Data -- Read-File and Write-File
        // --------------------------------------------------

    $filename_for_function = $_POST['file_target'];
    $inbound_save_as_filename = $_POST['saveable_result_file'];
       
        // Grab Image File Data
        // ---------------------------------------------
       
    $folder_location = "images/workshop/";
    $file_to_grab_with_location = $folder_location . $filename_for_function;
   
    $imagick_type = new Imagick();
   
        // Open File
        // ---------------------------------------------
           
    $file_handle_for_viewing_image_file = fopen($file_to_grab_with_location, 'a+');
   
        // Read File
        // ---------------------------------------------
   
    $imagick_type->readImageFile($file_handle_for_viewing_image_file);
   
        // Perform Function
        // ---------------------------------------------
       
    $imagick_type->charcoalImage($inbound_gaussian_radius, $inbound_standard_deviation);
   
        // Save File
        // ---------------------------------------------
       
    $folder_location = "images/workshop/";
    $file_to_grab_with_location = $folder_location . $inbound_save_as_filename;
           
    $file_handle_for_saving_image_file = fopen($file_to_grab_with_location, 'a+');
   
        // Write File
        // ---------------------------------------------
   
    $imagick_type->writeImageFile($file_handle_for_saving_image_file);
       
?>

The following is an example using a GoogleImage search result for the word "Ocean":

 

Official Function Page: http://www.php.net/manual/en/imagick.charcoalimage.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

Verifying and Viewing Info on Your ImageMagick Installation in PHP

You will probably want to take a look at the basic package statistics for Imagick when getting to work with it.  This will provide you with the simple understanding that you have the right package and version numbers installed for PHP that you think you have :

(Note:  Imagick::getImageMagickLicense is a function that produces an error in PHP Version 5.2.17.)

The Politics:  This was originally posted with the ImageMagick class, but was then removed, either because it's too simple or because it points out another broken, undocumented function in PHP.

<?php

        // Grab and Display Copyright Information
        // ---------------------------------------------------

    $imagick_copyright = Imagick::getCopyright();
   
    print("&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<b><u>ImageMagick Copyright:</u></b><br>");
    print("$imagick_copyright<br>");
   
    print("<br>");
   
        // Grab and Display License Information
        // ---------------------------------------------------

//    $imagick_license = Imagick::getImageMagickLicense();
   
    print("&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<b><u>ImageMagick License:</u></b><br>");
    print("$imagick_license<br>");
   
    print("<br>");
   
        // Grab and Display Package Name Information
        // ---------------------------------------------------

    $imagick_package_name = Imagick::getPackageName();
   
    print("&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<b><u>ImageMagick Package Name:</u></b><br>");
    print("$imagick_package_name<br>");
   
    print("<br>");
   
        // Grab and Display Version Information
        // ---------------------------------------------------

    $imagick_version = Imagick::getVersion();
   
    $imagick_version_number = $imagick_version['versionNumber'];
    $imagick_version_string = $imagick_version['versionString'];
   
    print("&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<b><u>ImageMagick Version:</u></b><br>");
    print("Number: $imagick_version_number<br>");
    print("String: $imagick_version_string<br>");
   
    print("<br>");
   
        // Grab and Display Release Date Information
        // ---------------------------------------------------

    $imagick_release_date = Imagick::getReleaseDate();
   
    print("&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<b><u>ImageMagick Release Date:</u></b><br>");
    print("$imagick_release_date<br>");
   
    print("<br>");
   
        // Grab and Display Home URL Information
        // ---------------------------------------------------

    $imagick_homeurl = Imagick::getHomeURL();
   
    print("&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<b><u>ImageMagick Home URL:</u></b><br>");
    print("$imagick_homeurl<br>");

?>

Example Output:
(I had to disable the license option,
since it appears to be invalid on my
current install.)
---------------------------------------

        ImageMagick Copyright:
Copyright (C) 1999-2012 ImageMagick Studio LLC

        ImageMagick License:
ERROR -- Function not callable!

        ImageMagick Package Name:
ImageMagick

        ImageMagick Version:
Number: 1654
String: ImageMagick 6.7.6-1 2012-04-09 Q16 http://www.imagemagick.org

        ImageMagick Release Date:
2012-04-09

        ImageMagick Home URL:
/usr/[...Some URL on my Server]

Official Function Page: http://php.net/manual/en/book.imagick.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

Return a List of the Colors Used in an Image in PHP

The function getImageColors is a PHP function that is supposed to return the number of unique colors used in an image.  It is broken and it never worked.  It returns a blank string.  Besides, it sounds like a limited function.  Also, I wanted to get an array with each $key value being the RGB of the pixel, and each $value value being the number of times that pixel occurs.  Basically, a frequency list of colors and how often they have appeared for a particular image.  For example, you would have "1 / 0 / 0" for red as a $key value, and "25" for the number of times that pixel color was in the image.  So, I wrote some code to do that, using a combination of readImageFile, getImageWidth, getImageHeight, getImagePixelColor, and a simple x/y parser, like so :

<?php

        // Test File
        // ---------------------------------------------

            // Note: This file was just a picture of a 5x5 red square
            //    inside of a gigantic 521x512 blue square, and
            //    then I did a bunch of random, yellow zigzags.

    $file_to_grab_with_location = "test.jpg";

    $imagick_type = new Imagick();
           
        // Open File
        // ---------------------------------------------
                   
    $file_handle_for_viewing_image_file = fopen($file_to_grab_with_location, 'a+');
    $imagick_type->readImageFile($file_handle_for_viewing_image_file);
   
        // Preset Information
        // ---------------------------------------------

    $frequency_list_of_values = array();
   
        // Parse Pixels
        // ---------------------------------------------
       
    $image_resolution_width = $imagick_type->getImageWidth();
    $image_resolution_height = $imagick_type->getImageHeight();
       
    print("Image Resolution:  Width - $image_resolution_width / Height - $image_resolution_height<br><br>");
   
        // Parse Image Top-to-Bottom (Y-Variable)
        // ---------------------------------------------
   
    for($y = 0; $y < $image_resolution_height; $y++)
    {
            // Parse Image Left-to-Right (X-Variable)
            // ---------------------------------------------
       
        for($x = 0; $x < $image_resolution_width; $x++)
        {
       
                // Image Pixel Color
                // ---------------------------------------------
       
            $pixel_to_examine = $imagick_type->getImagePixelColor($x,$y);
           
            $pixel_to_examine_color_value_red = $pixel_to_examine->getColorValue(imagick::COLOR_RED);
            $pixel_to_examine_color_value_green = $pixel_to_examine->getColorValue(imagick::COLOR_GREEN);
            $pixel_to_examine_color_value_blue = $pixel_to_examine->getColorValue(imagick::COLOR_BLUE);

                // Set Key Value
                // ---------------------------------------------
       
            $key_value =    $pixel_to_examine_color_value_red    .    " / "    .
                    $pixel_to_examine_color_value_green    .    " / "    .
                    $pixel_to_examine_color_value_blue            ;
   
                // Increment Array Entry for Color
                // ---------------------------------------------
                   
            if(isset($frequency_list_of_values[$key_value]) == TRUE)
            {
                $temp = $frequency_list_of_values[$key_value];
                $temp++;
                $frequency_list_of_values[$key_value] = $temp;
            }
            else
            {
                $frequency_list_of_values[$key_value] = 1;
            }
        }
    }
               
        // Print Out Array of Values
        // ---------------------------------------------
   
    print("<pre>");
    print_r($frequency_list_of_values);
    print("</pre>");

/*

    Results:
    ------------------

Image Resolution: Width - 521 / Height - 512

Array
(
    [1 / 0 / 0] => 25
    [0 / 0 / 1] => 264107
    [1 / 1 / 0] => 2620
)

*/

?>

How I programmed it into my own Image-Content Management System:



Official Function Page: http://www.php.net/manual/en/imagick.getimagecolors.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

Finding and Returning a Pixel Color Value with the ImageMagick Class in PHP

When getting a color value back with getColorValue, you are free to use any color scheme: either the Red/Green/Blue (RGB) scheme or the Cyan/Magenta/Yellow/blacK (CMYK) scheme.  For RGB, this function works with the constant values of "COLOR_RED", "COLOR_GREEN", and "COLOR_BLUE," and for CMYK, this function works with the constant values of "COLOR_CYAN", "COLOR_MAGENTA", "COLOR_YELLOW", and "COLOR_BLACK".  As a programmer, the main question you're probably asking yourself is "How do I know if one pixel's color is different from the others?"  That seems to be defined as a unique combination of RGB *or* CMYK values.  Each RGB set of values with have a unique set of CMYK values for only that set of RGB values, so an RGB of 1/0.5/0.5 with have a unique set of CMYK values, shared only by the other pixels of the same exact RGB values.

Why the CMYK?  Because that is the standard for printing, or to quote the Imagick site, "As such for printing we use four colored inks: Cyan, Magenta, Yellow, and blacK; and define images using these inks, to form a CMYK color space."  By being a "color space", you get the choice of working with either RGB or CMYK when defining a pixel as being unique among a set of pixels.  But you are completely free to go with either RGB or CMYK.  For more on it from the Imagick Site:

http://www.imagemagick.org/Usage/color_basics/

Some code that demonstrates both methods:

<?php

        // Grab Pixel
        // ---------------------------------------------------

    $pixel_one = $imagick_type->getImagePixelColor(0,0);

        // Grab Alpha/Opacity Values
        // ---------------------------------------------------
   
    $pixel_one_color_value_alpha = $pixel_one->getColorValue(imagick::COLOR_ALPHA);
    $pixel_one_color_value_opacity = $pixel_one->getColorValue(imagick::COLOR_OPACITY);

        // Grab Red/Green/Blue (RGB) Values
        // ---------------------------------------------------
   
    $pixel_one_color_value_red = $pixel_one->getColorValue(imagick::COLOR_RED);
    $pixel_one_color_value_green = $pixel_one->getColorValue(imagick::COLOR_GREEN);
    $pixel_one_color_value_blue = $pixel_one->getColorValue(imagick::COLOR_BLUE);

        // Grab Cyna/Magenta/Yellow/blacK (CMYK) Values
        // ---------------------------------------------------
   
    $pixel_one_color_value_cyan = $pixel_one->getColorValue(imagick::COLOR_CYAN);
    $pixel_one_color_value_magenta = $pixel_one->getColorValue(imagick::COLOR_MAGENTA);
    $pixel_one_color_value_yellow = $pixel_one->getColorValue(imagick::COLOR_YELLOW);
    $pixel_one_color_value_black = $pixel_one->getColorValue(imagick::COLOR_BLACK);

        // Print Results
        // ---------------------------------------------------
   
    print("Alpha: $pixel_one_color_value_alpha<br>");
    print("Opacity: $pixel_one_color_value_opacity<br><br>");

    print("---------------------------------------------<br><br>");
   
    print("Red: $pixel_one_color_value_red<br>");
    print("Green: $pixel_one_color_value_green<br>");
    print("Blue: $pixel_one_color_value_blue<br><br>");
   
    print("Cyan: $pixel_one_color_value_cyan<br>");
    print("Magenta: $pixel_one_color_value_magenta<br>");
    print("Yellow: $pixel_one_color_value_yellow<br>");
    print("Black: $pixel_one_color_value_black<br><br>");

    /*
            Example Results : : :
            -----------------------

Alpha: 1
Opacity: 0

---------------------------------------------

Red: 1
Green: 0.501960784314
Blue: 0.501960784314

Cyan: 1
Magenta: 0.501960784314
Yellow: 0.501960784314
Black: 0

    */

?>

Official Function Page: http://php.net/manual/en/imagickpixel.getcolorvalue.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

Find Filetype of Filename in PHP

Something you may eventually want to do is to know the type of file simply by the suffix of the filename.  Functions like finfo_file and mime_ content_ type come close, but they don't actually list the filename suffix (like "txt" for "readme.txt"), and this filetype function seems to list "directory" or "file" only.

Knowing the filename suffix can be very useful, especially when managing a filesystem that has copies.  It's better to name the copy of a file as "readme(copy-1).txt" rather than "readme.txt(copy-1)", since the latter option probably isn't going to cooperate so well with your text editor/reader.  Here's a little code below that returns the suffix of a filename in a string.  It returns both the prefix and the suffix of the filename :

<?php

        // Example Filename: "Homepage.php"
        // ------------------------------------

    $file_name = "Homepage.php";

        // Filename Data
        // ------------------------------------

    $length_of_filename = strlen($file_name);
    $last_char = substr($file_name, $length_of_filename - 1, 1);

        // Parse Filename Backwards
        // ------------------------------------
   
    for($i_parse_name = 0; $i_parse_name < $length_of_filename; $i_parse_name++)
    {

            // Gather Data and Detect
            // ------------------------------------
       
        $last_char = substr($file_name, $length_of_filename - $i_parse_name + 2, 1);
       
        if($last_char == ".")
        {
            $filename_suffix = substr($file_name, $length_of_filename - $i_parse_name + 2, $i_parse_name);
            $filename_prefix = substr($file_name, 0, $length_of_filename - strlen($filename_suffix));
            $i_parse_name = $length_of_filename;
        }
    }
   
        // Print Results
        // ------------------------------------
               
    print("Filetype Results -- $filename_prefix ||| $filename_suffix");

        // Example Results:
        // ------------------------------------
        //    Filetype Results -- Homepage ||| .php

?>

Other examples:

"Best.Page.in.the.Universe.xml"
    Filetype Results -- Best.Page.in.the.Universe ||| .xml

"Best.Page.in.the.Universe.xml5789"
    Filetype Results -- Best.Page.in.the.Universe ||| .xml5789

"Home.awesome.page.php"
    Filetype Results -- Home.awesome.page ||| .php

Official Function Page: http://www.php.net/manual/en/function.filetype.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

Return Date Difference for Two Time() Integers in PHP

I wanted to have a formatted time difference function that worked with two time() integer results and formatted the results, such as "X Years, Y Months, Z Weeks, etc.."  The following is that function, and it's designed to be modifiable, so you could easily cut out the standard Years / Months / Weeks / Days / Hours / Minutes / Seconds Format, and go to whatever format you prefer in whatever order you prefer.

Note:  This is apparently very useful for those using older versions of PHP, where the date_diff function isn't implemented!

<?php

        // Define Input
        // --------------------------------------

            // Example Time Difference
       
    $start_time_for_conversion = 0;
    $end_time_for_conversion = 123456;
   
    $difference_of_times = $end_time_for_conversion - $start_time_for_conversion;
   
    $time_difference_string = "";
   
    for($i_make_time = 6; $i_make_time > 0; $i_make_time--)
    {
        switch($i_make_time)
        {
                // Handle Minutes
                // ........................
               
            case '1';
                $unit_title = "Minute(s)";
                $unit_size = 60;
                break;
               
                // Handle Hours
                // ........................
               
            case '2';
                $unit_title = "Hour(s)";
                $unit_size = 3600;
                break;
               
                // Handle Days
                // ........................
               
            case '3';
                $unit_title = "Day(s)";
                $unit_size = 86400;
                break;
               
                // Handle Weeks
                // ........................
               
            case '4';
                $unit_title = "Week(s)";
                $unit_size = 604800;
                break;
               
                // Handle Months (31 Days)
                // ........................
               
            case '5';
                $unit_title = "Month(s)";
                $unit_size = 2678400;
                break;
               
                // Handle Years (365 Days)
                // ........................
               
            case '6';
                $unit_title = "Year(s)";
                $unit_size = 31536000;
                break;
        }
   
        if($difference_of_times > ($unit_size - 1))
        {
            $modulus_for_time_difference = $difference_of_times % $unit_size;
            $seconds_for_current_unit = $difference_of_times - $modulus_for_time_difference;
            $units_calculated = $seconds_for_current_unit / $unit_size;
            $difference_of_times = $modulus_for_time_difference;
   
            $time_difference_string .= "$units_calculated $unit_title, ";
        }
    }
   
        // Handle Seconds
        // ........................
   
    $time_difference_string .= "$difference_of_times Second(s)";

            // Example Result: "1 Day(s), 10 Hour(s), 17 Minute(s), 36 Second(s)"

?>

One other example: 123456789 = "3 Year(s), 10 Month(s), 3 Week(s), 2 Day(s), 21 Hour(s), 33 Minute(s), 9 Second(s)"

Official Function Page: http://www.php.net/manual/en/function.date-diff.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

Get the Time() Result for the "Next Holiday" or "Next Month" in PHP

Something I often want to do is find out the first of the next month and to get the time() result for it.  By using a combination of date() and strtotime(), you can do that:

<?php

        // Example Time() Integer (for Thu, 15 Mar, 2012)

    $time_to_handle_for_next_month_conversion = 1331835943;

        // Date Conversions
   
    $interpretted_day = date('d', $time_to_handle_for_next_month_conversion);
    $interpretted_month = date('F', $time_to_handle_for_next_month_conversion);
    $interpretted_month_lowercased = strtolower($interpretted_month);
    $interpretted_year = date('Y', $time_to_handle_for_next_month_conversion);

        // Preset Day

    $new_day = 1;

        // Handle Case: December
   
    if($interpretted_month_lowercased == "december")
    {
        $new_month = "January";
        $new_year = $interpretted_year + 1;
    }
    else
    {

        // Handle All Other Cases

        switch($interpretted_month_lowercased)
        {
            case 'january':
                $new_month = "February";
                break;
               
            case 'february':
                $new_month = "March";
                break;
               
            case 'march':
                $new_month = "April";
                break;
               
            case 'april':
                $new_month = "May";
                break;
               
            case 'may':
                $new_month = "June";
                break;
               
            case 'june':
                $new_month = "July";
                break;
               
            case 'july':
                $new_month = "August";
                break;
               
            case 'august':
                $new_month = "September";
                break;
               
            case 'september':
                $new_month = "October";
                break;
               
            case 'october':
                $new_month = "November";
                break;
               
            case 'november':
                $new_month = "December";
                break;
        }
   
        $new_year = $interpretted_year;
    }

    $new_date_string =         $new_day        . " " .
                    $new_month        . " " .
                    $new_year;
                   
        // Results
                   
    $first_day_of_the_next_month_time_integer = strtotime($new_date_string);

        // Result = 1333256400 (Sun, 1 Apr, 2012)

?>

Note:  You could easily modify this function to return the "next Ramadan," "the next Halloween," "the next New Years," etc., and place a counter for how many more days, months, hours, etc., you need to wait for it.

Official Function Page: http://php.net/manual/en/function.time.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