A few days ago I got a help request from a user: "How do you change pixel color during the iteration with ImagickPixelIterator". My initial response was that ImagickPixelIterator is read-only.
Well, I have to admit I was wrong. After searching trough ImageMagick docs I stumbled across an example and noticed that PixelIterator (and therefor ImagickPixelIterator) is not read-only after all. I have tried the code like in this example before; without the syncIterator call after each row. After adding the Imagick::syncIterator call everything worked as expected.
This example will work with Imagick 2.1.0 (the RC1 was released yesterday) but with a little tweaking it should work with 2.0.x too.
-
<?php
-
-
/* Create new object with the image */
-
$im = new Imagick( "strawberry.png" );
-
-
/* Get iterator */
-
$it = $im->getPixelIterator();
-
-
/* Loop trough pixel rows */
-
foreach( $it as $row => $pixels )
-
{
-
/* For every second row */
-
if ( $row % 2 )
-
{
-
/* Loop trough the pixels in the row (columns) */
-
foreach ( $pixels as $column => $pixel )
-
{
-
/* Paint every second pixel black*/
-
if ( $column % 2 )
-
{
-
$pixel->setColor( "black" );
-
}
-
}
-
}
-
-
/* Sync the iterator, this is important
-
to do on each iteration */
-
$it->syncIterator();
-
}
-
-
/* Display the image */
-
echo $im;
-
-
?>
The source image:
The result image:
Trackback: PHPDeveloper.org
Pingback: developercast.com » Mikko Koppanen’s Blog: ImagickPixelIterator is not read-only after all…
#1 by kakapo on November 16, 2007 - 8:40 am
Quote
Mikko, how to set one color of a image to transparent? My program is below,but it not works.
/* Create new object with the image */
$im = new Imagick( “logo.gif” );
$blue = new ImagickPixel(‘#025AA4′);
$it = $im->getPixelIterator();
foreach( $it as $row => $pixels )
{
foreach ( $pixels as $column => $pixel )
{
$color = $pixel->getColorValue (imagick::COLOR_ALPHA );
if($pixel->isSimilar($blue,1)){
$pixel->setColor( “transparent” );
//$pixel->setColorValue(imagick::COLOR_ALPHA ,0);
}
}
$it->syncIterator();
}
/* Display the image */
header( “Content-Type: image/gif” );
echo $im;
#2 by Mikko Koppanen on November 16, 2007 - 9:19 am
Quote
Hello again kakapo,
Try calling $im->setImageMatte( true ); right after you clear the object!
#3 by kakapo on November 16, 2007 - 10:32 am
Quote
Oh! Thanks! i works! here is my code:
getImageWidth();
$logo_height = $logo->getImageHeight();
$im = new Imagick(“glitter_blue.gif”);
$new_im = new Imagick();
$new_im->setFormat(“gif”);
foreach ($im as $image){
repeatPic($new_im,$image,$logo_width,$logo_height);
$new_im->compositeImage($logo,Imagick::COMPOSITE_OVER,0,0);
}
header( “Content-Type: image/gif” );
echo $new_im->getImagesBlob();
die;
/**
* replace one color to another color or transparent
* @param imagick $im
* @param string $color
* @param string $replacecolor
* @return void
*/
function replaceOneColorOfImage(& $im,$color=’white’,$replacecolor=’black’){
$im ->setImageMatte( true );
$color_pix = new ImagickPixel($color);
$it = $im->getPixelIterator();
foreach( $it as $row => $pixels )
{
foreach ( $pixels as $column => $pixel )
{
$color = $pixel->getColorValue (imagick::COLOR_ALPHA );
if($pixel->isSimilar($color_pix,1.732)){
$pixel->setColor( $replacecolor );
//$pixel->setColorValue(imagick::COLOR_OPACITY ,0.3);
}
}
$it->syncIterator();
}
}
/**
* repeat a pic to a big size
* @param imagick $new_im
* @param imagick $image
* @param integer $width
* @param integer $height
* @return void
*/
function repeatPic(&$new_image,$image,$width,$height){
$new_image->newImage($width,$height,new ImagickPixel(“transparent”));
$org_width = $image->getImageWidth();
$org_height = $image->getImageHeight();
for ($i=0,$c=ceil($width%$org_width);$icompositeImage($image,Imagick::COMPOSITE_OVER,$org_width*$i,$org_height*$j);
}
}
}
?>
original pic:
http://www.kakapo.cn/imagick/glitter_blue.gif
http://www.kakapo.cn/imagick/logo.gif
example result pic:
http://www.kakapo.cn/imagick/animate.gif
#4 by kakapo on November 16, 2007 - 10:42 am
Quote
what’s wrong, my code are stripped? the whole below:
———————————–
$logo = new Imagick(“logo.gif”);
replaceOneColorOfImage($logo,”#025AA4″,’transparent’);
$logo_width = $logo->getImageWidth();
$logo_height = $logo->getImageHeight();
$im = new Imagick(“glitter_blue.gif”);
$new_im = new Imagick();
$new_im->setFormat(“gif”);
foreach ($im as $image){
repeatPic($new_im,$image,$logo_width,$logo_height);
$new_im->compositeImage($logo,Imagick::COMPOSITE_OVER,0,0);
}
header( “Content-Type: image/gif” );
echo $new_im->getImagesBlob();
die;
/**
* replace one color to another color or transparent
* @param imagick $im
* @param string $color
* @param string $replacecolor
* @return void
*/
function replaceOneColorOfImage(& $im,$color=’white’,$replacecolor=’black’){
$im ->setImageMatte( true );
$color_pix = new ImagickPixel($color);
$it = $im->getPixelIterator();
foreach( $it as $row => $pixels )
{
foreach ( $pixels as $column => $pixel )
{
$color = $pixel->getColorValue (imagick::COLOR_ALPHA );
if($pixel->isSimilar($color_pix,1.732)){
$pixel->setColor( $replacecolor );
//$pixel->setColorValue(imagick::COLOR_OPACITY ,0.3);
}
}
$it->syncIterator();
}
}
/**
* repeat a pic to a big size
* @param imagick $new_im
* @param imagick $image
* @param integer $width
* @param integer $height
* @return void
*/
function repeatPic(&$new_image,$image,$width,$height){
$new_image->newImage($width,$height,new ImagickPixel(“transparent”));
$org_width = $image->getImageWidth();
$org_height = $image->getImageHeight();
for ($i=0,$c=ceil($width%$org_width);$icompositeImage($image,Imagick::COMPOSITE_OVER,$org_width*$i,$org_height*$j);
}
}
}
#5 by Mikko Koppanen on November 16, 2007 - 10:45 am
Quote
kakapo,
You should put a link to the source code. If you paste it here it loses most of the formatting (tabs especially).
#6 by kakapo on November 16, 2007 - 10:48 am
Quote
God! It can’t be read! The codes of function are wrong after postting.
#7 by Mikko Koppanen on November 16, 2007 - 10:53 am
Quote
kakapo,
Can you send me the code via email to mkoppanen@php.net? I can write a small post about it here. Please include an url where you want me to link the credits.
#8 by kakapo on November 16, 2007 - 10:58 am
Quote
ok, I’m sorry!the example is here.http://www.kakapo.cn/blog/read.php?127
#9 by kakapo on November 19, 2007 - 11:32 am
Quote
Mikko, how to draw a image like this? http://www.kakapo.cn/imagick/mirror.png
#10 by open source cms on November 26, 2007 - 11:24 am
Quote
Looks great ;]
#11 by childporn on May 21, 2008 - 10:31 pm
Quote
http://childporn.all-nintendo-wii.info/index.html childporn
#12 by John.G. Sujith Kumar on July 16, 2009 - 3:25 pm
Quote
Hi Mikko,
thanks a lot for your wonderful code ,I did a code for Red eye filter based on your code,just change the syntax,it can be use for regional pixel iterations.
————————————————————————————-
function redI(){
/* Create new object with the image */
$im = new Imagick( “kingfisher.jpg” );
/* Get iterator */
$it = $im->getPixelRegionIterator(50,50,50,50);
/* Loop trough pixel rows */
foreach( $it as $row => $pixels ){
/* For every second row */
if ( $row % 2 ){
/* Loop trough the pixels in the row (columns) */
foreach ($pixels as $column => $pixel ){
/* Paint every second pixel black*/
if ($column % 2 ){
$pixel->setColor( “black” );
}
}
}
/* Sync the iterator, this is important to do on each iteration */
$it->syncIterator();
}
header( “Content-Type: image/png” );
echo $im;
}
#13 by Kaveh on November 23, 2009 - 5:59 pm
Quote
Hi;
I tried to test this codes to see that mu server work for Imagemagick but doesn’t work so i thought that maybe my address to .png is wrong ,thanks for your advice:
i put the codes in test.php
strawberry.png and test.php in same folder
and the first code as is:
$im = new Imagick( “strawberry.png” );
is this right?
thanks
Pingback: Imagick blog » Blog Archive » ImagickPixelIterator is not read-only after all..
#14 by Japan 2 Day Diet Lingzhi on May 6, 2010 - 6:09 am
Quote
Good post, but i try to run this code and it makes an error,,.,,.,,,
/**
* replace one color to another color or transparent
* @param imagick $im
* @param string $color
* @param string $replacecolor
* @return void
*/
whats the meaning of it?
#15 by Alejandro on July 29, 2010 - 5:30 pm
Quote
Hi. I’ve been reading and searching but I can’t find anything and either figure out how to create a text image with transparente background. Could someone please help me on this?…
Here’s my code.
newImage (500, 500, $pixel);
$image->setImageMatte (true);
// Black text
$pixel->setColor (‘white’);
// Font properties
$draw->setFont (‘Bookman-DemiItalic’);
$draw->setFontSize ( 30 );
$draw->setGravity (Imagick::GRAVITY_WEST);
$draw->setFillColor ($pixel);
$texto = ‘muerto, muerto…’.”\n”.’muertooooooooooooooo’;
// Create text
$image->annotateImage ($draw, 50, 0, 0, $texto);
// Give image a format
$image->setImageFormat (‘png24′);
$image->writeImage (‘composite.png’);
// Output the image with headers
header (‘Content-type: image/png’);
?>