Archive for the 'images' Category

Load a photo in a canvas, then flip

Saturday, May 3rd, 2008

zlati-nathalie.jpg

Today our family went to the yearly photo session with the girls. We took one shot that can be looked normally, as well as upside down, so I was wondering can you flip an image using a canvas tag. Turns out, yes, you can and it's pretty easy.

» Demo is here.

How to load an image in a canvas tag?

Start unpretentiously with an empty canvas tag:

<canvas id="canvas"></canvas>

Now the javascript. Two variables to store a handle to the canvas element and the 2D context of the canvas:

var can = document.getElementById('canvas');
var ctx = can.getContext('2d');

Now let's load an image into the canvas. Using the new Image() constructor you can create an image object, then set its src property to point to the location of the image file. Then set an onload handler for the image which is an anonymous function to be called when the image is done loading. There you put the image inside the canvas using the drawImage() method of the canvas context.

var img = new Image();
img.onload = function(){
    can.width = img.width;
    can.height = img.height;
    ctx.drawImage(img, 0, 0, img.width, img.height);
}
img.src = 'zlati-nathalie.jpg';

You can also notice how the dimensions of the canvas are adjusted to match the dimensions of the image.

How to flip the image upside down

The canvas context provides a rotate() method. The rotation always happens around the top left corner of the image, so we first translate() the image to the bottom right. This way when the image is rotated, it fits back into the canvas. (There is also a one pixel correction, I have no idea why, just saw that the image wasn't flipping exactly otherwise). Assigning this functionality to the onclick:

can.onclick = function() {
    ctx.translate(img.width-1, img.height-1);
    ctx.rotate(Math.PI);
    ctx.drawImage(img, 0, 0, img.width, img.height);
};

C'est tout! Once again, the demo is here.

 

Canvas pie with tooltips

Saturday, March 8th, 2008

This is very flattering: Greg Houston took my script for DIY canvas pie and added tooltips and better colors logic. Here's the result, it's really nice, built with some MooTools. The tooltips are not supported in <canvas> but Creg used an image that overlays the pie and set the tooltips with an image map. Clever, isn't it?

I just used random colors for the pieces of the pie, but Greg knows better. Based on a tutorial by Jim Bumgardner, he was able to achieve much more pleasing, yet reliable results. Funny thing that Jim works in Yahoo! two floors above me (used to be even on the same floor).

Check the demo and the post, cool stuff, works in IE too!

 

YUI pie chart example

Wednesday, January 16th, 2008

If case you haven't noticed - YUI Charts hit the streets.

As with everything new, it's best shown and understood by example. So here's the simplest example of using a pie chart. Basically I took the example from the YUI page, changed all the paths to point to yahooapis.com (where YUI is hosted for free) and stripped everything that could be stripped (there's even no html or head tags, but turned out the body tag is required). The result is a short html with all dependencies satisfied.

OK, so here's the example, grab, paste, customize:
chart.html

 

Image fun with PHP - part 2

Tuesday, November 13th, 2007

This post is a demo of what the imagefilter() PHP function can do for you.

The Original

Nathalie

imagefilter() called with different filter constants

img_filter_brightness_5.png
Filter: IMG_FILTER_BRIGHTNESS
Code to reproduce:
<?php
$image
imagecreatefrompng('nathalie.png');
imagefilter($imageIMG_FILTER_BRIGHTNESS5);
imagepng($image'img_filter_brightness_5.png');
imagedestroy($image);
?>

img_filter_brightness_50.png
Filter: IMG_FILTER_BRIGHTNESS
Code to reproduce:
<?php
$image
imagecreatefrompng('nathalie.png');
imagefilter($imageIMG_FILTER_BRIGHTNESS50);
imagepng($image'img_filter_brightness_50.png');
imagedestroy($image);
?>

img_filter_brightness_100.png
Filter: IMG_FILTER_BRIGHTNESS
Code to reproduce:
<?php
$image
imagecreatefrompng('nathalie.png');
imagefilter($imageIMG_FILTER_BRIGHTNESS100);
imagepng($image'img_filter_brightness_100.png');
imagedestroy($image);
?>

img_filter_grayscale.png
Filter: IMG_FILTER_GRAYSCALE
Code to reproduce:
<?php
$image
imagecreatefrompng('nathalie.png');
imagefilter($imageIMG_FILTER_GRAYSCALE);
imagepng($image'img_filter_grayscale.png');
imagedestroy($image);
?>

img_filter_contrast_5.png
Filter: IMG_FILTER_CONTRAST
Code to reproduce:
<?php
$image
imagecreatefrompng('nathalie.png');
imagefilter($imageIMG_FILTER_CONTRAST5);
imagepng($image'img_filter_contrast_5.png');
imagedestroy($image);
?>

img_filter_contrast_-40.png
Filter: IMG_FILTER_CONTRAST
Code to reproduce:
<?php
$image
imagecreatefrompng('nathalie.png');
imagefilter($imageIMG_FILTER_CONTRAST, -40);
imagepng($image'img_filter_contrast_-40.png');
imagedestroy($image);
?>

img_filter_contrast_50.png
Filter: IMG_FILTER_CONTRAST
Code to reproduce:
<?php
$image
imagecreatefrompng('nathalie.png');
imagefilter($imageIMG_FILTER_CONTRAST50);
imagepng($image'img_filter_contrast_50.png');
imagedestroy($image);
?>

img_filter_colorize_100_0_0.png
Filter: IMG_FILTER_COLORIZE
Code to reproduce:
<?php
$image
imagecreatefrompng('nathalie.png');
imagefilter($imageIMG_FILTER_COLORIZE10000);
imagepng($image'img_filter_colorize_100_0_0.png');
imagedestroy($image);
?>

img_filter_colorize_0_100_0.png
Filter: IMG_FILTER_COLORIZE
Code to reproduce:
<?php
$image
imagecreatefrompng('nathalie.png');
imagefilter($imageIMG_FILTER_COLORIZE01000);
imagepng($image'img_filter_colorize_0_100_0.png');
imagedestroy($image);
?>

img_filter_colorize_0_0_100.png
Filter: IMG_FILTER_COLORIZE
Code to reproduce:
<?php
$image
imagecreatefrompng('nathalie.png');
imagefilter($imageIMG_FILTER_COLORIZE00100);
imagepng($image'img_filter_colorize_0_0_100.png');
imagedestroy($image);
?>

img_filter_colorize_100_100_-100.png
Filter: IMG_FILTER_COLORIZE
Code to reproduce:
<?php
$image
imagecreatefrompng('nathalie.png');
imagefilter($imageIMG_FILTER_COLORIZE100100, -100);
imagepng($image'img_filter_colorize_100_100_-100.png');
imagedestroy($image);
?>

img_filter_colorize_50_-50_50.png
Filter: IMG_FILTER_COLORIZE
Code to reproduce:
<?php
$image
imagecreatefrompng('nathalie.png');
imagefilter($imageIMG_FILTER_COLORIZE50, -5050);
imagepng($image'img_filter_colorize_50_-50_50.png');
imagedestroy($image);
?>

img_filter_edgedetect.png
Filter: IMG_FILTER_EDGEDETECT
Code to reproduce:
<?php
$image
imagecreatefrompng('nathalie.png');
imagefilter($imageIMG_FILTER_EDGEDETECT);
imagepng($image'img_filter_edgedetect.png');
imagedestroy($image);
?>

img_filter_emboss.png
Filter: IMG_FILTER_EMBOSS
Code to reproduce:
<?php
$image
imagecreatefrompng('nathalie.png');
imagefilter($imageIMG_FILTER_EMBOSS);
imagepng($image'img_filter_emboss.png');
imagedestroy($image);
?>

img_filter_gaussian_blur.png
Filter: IMG_FILTER_GAUSSIAN_BLUR
Code to reproduce:
<?php
$image
imagecreatefrompng('nathalie.png');
imagefilter($imageIMG_FILTER_GAUSSIAN_BLUR);
imagepng($image'img_filter_gaussian_blur.png');
imagedestroy($image);
?>

img_filter_selective_blur.png
Filter: IMG_FILTER_SELECTIVE_BLUR
Code to reproduce:
<?php
$image
imagecreatefrompng('nathalie.png');
imagefilter($imageIMG_FILTER_SELECTIVE_BLUR);
imagepng($image'img_filter_selective_blur.png');
imagedestroy($image);
?>

img_filter_mean_removal.png
Filter: IMG_FILTER_MEAN_REMOVAL
Code to reproduce:
<?php
$image
imagecreatefrompng('nathalie.png');
imagefilter($imageIMG_FILTER_MEAN_REMOVAL);
imagepng($image'img_filter_mean_removal.png');
imagedestroy($image);
?>

img_filter_smooth_5.png
Filter: IMG_FILTER_SMOOTH
Code to reproduce:
<?php
$image
imagecreatefrompng('nathalie.png');
imagefilter($imageIMG_FILTER_SMOOTH5);
imagepng($image'img_filter_smooth_5.png');
imagedestroy($image);
?>

img_filter_smooth_50.png
Filter: IMG_FILTER_SMOOTH
Code to reproduce:
<?php
$image
imagecreatefrompng('nathalie.png');
imagefilter($imageIMG_FILTER_SMOOTH50);
imagepng($image'img_filter_smooth_50.png');
imagedestroy($image);
?>

img_filter_negate.png
Filter: IMG_FILTER_NEGATE
Code to reproduce:
<?php
$image
imagecreatefrompng('nathalie.png');
imagefilter($imageIMG_FILTER_NEGATE);
imagepng($image'img_filter_negate.png');
imagedestroy($image);
?>

A lazy way to do sepia

In order to do sepia, first you do grayscale, then colorize. Here are some experiments:

sepia_100_50_0.png

<?php
$image
imagecreatefrompng('nathalie.png');
imagefilter($imageIMG_FILTER_GRAYSCALE);
imagefilter($imageIMG_FILTER_COLORIZE100500);
imagepng($image'sepia_100_50_0.png');
imagedestroy($image);
?>

sepia_100_70_50.png

<?php
$image
imagecreatefrompng('nathalie.png');
imagefilter($imageIMG_FILTER_GRAYSCALE);
imagefilter($imageIMG_FILTER_COLORIZE1007050);
imagepng($image'sepia_100_70_50.png');
imagedestroy($image);
?>

sepia_90_60_30.png

<?php
$image
imagecreatefrompng('nathalie.png');
imagefilter($imageIMG_FILTER_GRAYSCALE);
imagefilter($imageIMG_FILTER_COLORIZE906030);
imagepng($image'sepia_90_60_30.png');
imagedestroy($image);
?>

sepia_60_60_0.png

<?php
$image
imagecreatefrompng('nathalie.png');
imagefilter($imageIMG_FILTER_GRAYSCALE);
imagefilter($imageIMG_FILTER_COLORIZE60600);
imagepng($image'sepia_60_60_0.png');
imagedestroy($image);
?>

sepia_90_90_0.png

<?php
$image
imagecreatefrompng('nathalie.png');
imagefilter($imageIMG_FILTER_GRAYSCALE);
imagefilter($imageIMG_FILTER_COLORIZE90900);
imagepng($image'sepia_90_90_0.png');
imagedestroy($image);
?>

sepia_45_45_0.png

<?php
$image
imagecreatefrompng('nathalie.png');
imagefilter($imageIMG_FILTER_GRAYSCALE);
imagefilter($imageIMG_FILTER_COLORIZE45450);
imagepng($image'sepia_45_45_0.png');
imagedestroy($image);
?>

You can read about the right way to do sepia in Wikipedia, but I'd say that the fakes above look pretty good too.
You can try with different values for R, G and B, but hear this - the thing about sepia is that it's brownish-yellow.
Brown is something that has more red, little blue and the green exactly in between the red and the blue. So brown examples would be (200, 100, 0) or (150, 100, 50).
Yellow on the other hand is equal red and green and no blue, like (255, 255, 0). So if you want more brownish sepia, use the first pattern when calling the colorize filter.

About part one

Part one of the image fun is here, it contains code that more or less does the same things, but pixel by pixel, which is very slow, but also works in PHP4.
At the time of writing part one, imagefilter() funtion was probaly only in cvs, not part of the official PHP. imagefilter() is PHP5-only.

 

Image_Text 0.6 beta is out

Thursday, April 19th, 2007

» Download here

This is my first PEAR release and I was actually surprised how easy it is to package and roll out a release.

So you have your local copy of the CVS repository that contains the scripts you want to release as part of the package. In order to release, you need package.xml, a configuration file, which you can either create yourself or have a script (which uses PEAR_PackageFileManager) to create the xml file for you.

The pear command line tool does all the rest.

  1. pear convert - creates package2.xml based on your package.xml. (package2 is the newer improved version of package2.xml. You can actually use PEAR_PackageFileManager2 instead and skip this step)
  2. pear package - creates the package archive which then you upload to pear.php.net
  3. pear cvstag package2.xml - tags the cvs repository with a tag figured out from the package2. In my case the tag was RELEASE_0_6_0beta

Thanks!

As stated in the change log notes, many thanks go to Christian Weiske and James Pic for helping out with this release!

 

Laziest image resize in PHP

Wednesday, December 13th, 2006

Today I saw a post at digg.com on image resizing with PHP and there was quite a discussion. Let me share the laziest way (that I know of) how to do it - PEAR::Image_Transform is all it takes. Here goes:

<?php
require_once 'Image/Transform.php';
$i =& Image_Transform::factory('');

$i->load('test.jpg');
$i->fit(100,100);
$i->save('resized.png', 'png');
?>

In addition, the Image_Transform library offers diffferent ways (to skin the old cat) to resize an image - by given pixel value, only on the X axis, on Y, scalling in percentage and so on. And, of course, the library can do much more than resizing, as you can see in the API docs.

It supports all kinds of image manipulation extensions - GD, GD1, ImageMagick, NetPBM, Imlib… If you want to use a specific one, you set as a parameter to the factory() method. In the example above I passed an empty string, so it will try to figure out what's available in my PHP setup and use it, trying Imagick2 first, then GD, then Imlib.

You have setOption() and setOptions() methods if you want to play around with the image quality and those sort of things.