Imagick::paintOpaqueImage ignores translucent pixels - php

I noticed Imagick::paintOpaqueImage only operates on pixels with an alpha value of 1. This leaves converted images with lots of leftover pixels of the colors I'm trying to replace. Take for example this test image
And this code to replace the blue pixels with red ones.
$img->paintOpaqueImage('rgb(12,0,245)', 'rgb(255,0,0)', 0);
The result is only the solid blue pixels are replaced.
Note all the pixels in that test image (aside from the fully transparent ones) are the same color blue. The only difference is the alpha value. Also note I've used a value of 0 for the $fuzz parameter. Originally I was bumping this way up before I discovered what the real problem was, and that was causing its own undesirable results.
I've hacked together a solution using ImagickPixelIterator; it clones the current pixel and sets the alpha value of both the current pixel and cloned pixel to 1 to coerce ImagickPixel::isSimilar to work agnostically with regard to alpha values.
$img = new Imagick('./test-paint-opaque-image.png');
$iterator = new ImagickPixelIterator($img);
$target = new ImagickPixel('rgb(12,0,245)'); // blue
$fill = new ImagickPixel('rgb(255,0,0)'); // red
$fuzz = 0;
foreach($iterator as $pixels) {
foreach($pixels as $curPixel) {
// Modify the alpha of the comparePixel so it won't throw off the isSimilar() check
$comparePixel = clone $curPixel;
$fOrigAlpha = $curPixel->getColorValue(Imagick::COLOR_ALPHA);
// Bail on fully transparent pixels
if($fOrigAlpha == 0)
continue;
// It seems the only way isSimilar will work is when the alpha is 1 for both pixels...
$comparePixel->setColorValue(Imagick::COLOR_ALPHA, 1);
$curPixel->setColorValue(Imagick::COLOR_ALPHA, 1);
if($comparePixel->isSimilar($target, $fuzz)) {
$curPixel->setColorValue(Imagick::COLOR_RED, $fill->getColorValue(Imagick::COLOR_RED));
$curPixel->setColorValue(Imagick::COLOR_GREEN, $fill->getColorValue(Imagick::COLOR_GREEN));
$curPixel->setColorValue(Imagick::COLOR_BLUE, $fill->getColorValue(Imagick::COLOR_BLUE));
// Set the modified alpha back to what it was after the color change
if($fOrigAlpha > 0) {
echo "Setting alpha to $fOrigAlpha\n";
$curPixel->setColorValue(Imagick::COLOR_ALPHA, $fOrigAlpha);
}
}
}
$iterator->syncIterator();
}
The result is a shiny red image, with translucent (and fully transparent) pixels preserved as I would like.
The main problem, and what finally brings me to my question is that this method is wicked slow. Is there a way to use PHP Imagick::paintOpaqueImage directly to make this sort of color transformation?

You can deactivate the alpha channel prior to replacing the color value then reactivate it again after with setImageAlphaChannel(), like so:
$img = new Imagick('./test-paint-opaque-image.png');
$img->setImageAlphaChannel(Imagick::ALPHACHANNEL_DEACTIVATE);
$img->opaquePaintImage('rgb(12,0,245)', 'rgb(255,0,0)', 0, false);
$img->setImageAlphaChannel(Imagick::ALPHACHANNEL_ACTIVATE);
$img->writeImage('./out.png');
Result:

Related

How to clean background captcha image using imagick

I try to clean background captcha image using php imagick method and i used convert method as an alternative on console but i got same result. But it's not really worked.
Then i will use tesseract ocr for getting captcha code. There is a code for tesseract:
tesseract -psm 7 captcha.png output
Captcha image:
captcha
There is my code:
//Example Tutorial::backgroundMasking
function backgroundMasking()
{
//Load the image
$imagick = new \Imagick(realpath('captchaa.png'));
$backgroundColor = "rgb(162, 234, 160)";
$fuzzFactor = 0.1;
// Create a copy of the image, and paint all the pixels that
// are the background color to be transparent
$outlineImagick = clone $imagick;
$outlineImagick->transparentPaintImage(
$backgroundColor, 0, $fuzzFactor * \Imagick::getQuantum(), false
);
// Copy the input image
$mask = clone $imagick;
// Deactivate the alpha channel if the image has one, as later in the process
// we want the mask alpha to be copied from the colour channel to the src
// alpha channel. If the mask image has an alpha channel, it would be copied
// from that instead of from the colour channel.
$mask->setImageAlphaChannel(\Imagick::ALPHACHANNEL_DEACTIVATE);
//Convert to gray scale to make life simpler
$mask->transformImageColorSpace(\Imagick::COLORSPACE_GRAY);
// DstOut does a "cookie-cutter" it leaves the shape remaining after the
// outlineImagick image, is cut out of the mask.
$mask->compositeImage(
$outlineImagick,
\Imagick::COMPOSITE_DSTOUT,
0, 0
);
// The mask is now black where the objects are in the image and white
// where the background is.
// Negate the image, to have white where the objects are and black for
// the background
$mask->negateImage(false);
$fillPixelHoles = false;
if ($fillPixelHoles == true) {
// If your image has pixel sized holes in it, you will want to fill them
// in. This will however also make any acute corners in the image not be
// transparent.
// Fill holes - any black pixel that is surrounded by white will become
// white
$mask->blurimage(2, 1);
$mask->whiteThresholdImage("rgb(10, 10, 10)");
// Thinning - because the previous step made the outline thicker, we
// attempt to make it thinner by an equivalent amount.
$mask->blurimage(2, 1);
$mask->blackThresholdImage("rgb(255, 255, 255)");
}
//Soften the edge of the mask to prevent jaggies on the outline.
$mask->blurimage(2, 2);
// We want the mask to go from full opaque to fully transparent quite quickly to
// avoid having too many semi-transparent pixels. sigmoidalContrastImage does this
// for us. Values to use were determined empirically.
$contrast = 15;
$midpoint = 0.7 * \Imagick::getQuantum();
$mask->sigmoidalContrastImage(true, $contrast, $midpoint);
// Copy the mask into the opacity channel of the original image.
// You are probably done here if you just want the background removed.
$imagick->compositeimage(
$mask,
\Imagick::COMPOSITE_COPYOPACITY,
0, 0
);
// To show that the background has been removed (which is difficult to see
// against a plain white webpage) we paste the image over a checkboard
// so that the edges can be seen.
// Create the check canvas
$canvas = new \Imagick();
$canvas->newPseudoImage(
$imagick->getImageWidth(),
$imagick->getImageHeight(),
"pattern:checkerboard"
);
// Copy the image with the background removed over it.
$canvas->compositeimage($imagick, \Imagick::COMPOSITE_OVER, 0, 0);
$max = $imagick->getQuantumRange();
$max = $max["quantumRangeLong"];
$canvas->thresholdimage(0.77 * $max);
$canvas->negateImage(false, \Imagick::CHANNEL_ALL);
//Output the final image
$canvas->setImageFormat('png');
header("Content-Type: image/png");
echo $canvas->getImageBlob();
}
Result captcha image: enter image description here
what can i do for getting better result?

How to set color of a pixel using imagick for php (imagemagick)?

I have get the image pixel of an image at the particular point using getImagePixelColor.
$pixel = $image -> getImagePixelColor($x,$y);
Now I have modified that pixel's color using some method and now I want to set the new color of that pixel.
How can I do ?
There is a setColor function. But I got the pixel from the Imagick class. But the setColor function is in the ImagickPixel class. So how can I do it ?
ImagickPixel::setColor() is the correct function but it is also necessary to sync the pixel Iterator so your manipulations are written back to the image.
Here is a short yet (almost) complete example that reads an image file, manipulates each pixel, and dumps it to a browser:
$img = new Imagick('your_image.png');
$iterator = $img->getPixelIterator();
foreach ($iterator as $row=>$pixels) {
foreach ( $pixels as $col=>$pixel ){
$color = $pixel->getColor(); // values are 0-255
$alpha = $pixel->getColor(true); // values are 0.0-1.0
$r = $color['r'];
$g = $color['g'];
$b = $color['b'];
$a = $alpha['a'];
// manipulate r, g, b and a as necessary
//
// you could also read arbitrary pixels from
// another image with similar dimensions like so:
// $otherimg_pixel = $other_img->getImagePixelColor($col,$row);
// $other_color = $otherimg_pixel->getColor();
//
// then write them back into the iterator
// and sync it
$pixel->setColor("rgba($r,$g,$b,$a)");
}
$iterator->syncIterator();
}
header('Content-type: '.$img->getFormat());
echo $img->getimageblob();
->getImagePixelColor() returns an ImagickPixel object anyways, so $pixel->setColor(...); is all you need:
Ref: http://php.net/manual/en/imagick.getimagepixelcolor.php

Detect main colors in an image with PHP

I am trying to replicate the functionality that Dribbble.com does with detecting the predominant colors in an Image. In the image below you can see a screenshot from Dribbble.com that shows the 8 predominant colors in the image to the left. Here is the actual page in the image http://dribbble.com/shots/528033-Fresh-Easy?list=following
I need to be able to do this in PHP, once I get the colors I need I will save them to a database so the processing does not need to be run on every page load.
After some research on how to get these colors out of an Image, some people said you simply examine an image pixel by pixel and then save the colors that occur the most. Other say there is more to it and that getting the colors that exist the most frequent won't give the desired affect. They say you need to Quantize the image/colors (I am lost at this point).
In the image below the Dribble shot below is a Javascript library that does the same thing, that page can be viewed here http://lokeshdhakar.com/projects/color-thief/
Viewing the source of that page I can see there is a Javascript file named quantize.js and the results are really good. So I am hoping to be able to do what that Javascript library does but with PHP and GD/ImageMagick
I had found this function that will return the colors and count in an Image with PHP but the results are different from the Javascript version above and the Dribble results
/**
* Returns the colors of the image in an array, ordered in descending order, where the keys are the colors, and the values are the count of the color.
*
* #return array
*/
function Get_Color()
{
if (isset($this->image))
{
$PREVIEW_WIDTH = 150; //WE HAVE TO RESIZE THE IMAGE, BECAUSE WE ONLY NEED THE MOST SIGNIFICANT COLORS.
$PREVIEW_HEIGHT = 150;
$size = GetImageSize($this->image);
$scale=1;
if ($size[0]>0)
$scale = min($PREVIEW_WIDTH/$size[0], $PREVIEW_HEIGHT/$size[1]);
if ($scale < 1)
{
$width = floor($scale*$size[0]);
$height = floor($scale*$size[1]);
}
else
{
$width = $size[0];
$height = $size[1];
}
$image_resized = imagecreatetruecolor($width, $height);
if ($size[2]==1)
$image_orig=imagecreatefromgif($this->image);
if ($size[2]==2)
$image_orig=imagecreatefromjpeg($this->image);
if ($size[2]==3)
$image_orig=imagecreatefrompng($this->image);
imagecopyresampled($image_resized, $image_orig, 0, 0, 0, 0, $width, $height, $size[0], $size[1]); //WE NEED NEAREST NEIGHBOR RESIZING, BECAUSE IT DOESN'T ALTER THE COLORS
$im = $image_resized;
$imgWidth = imagesx($im);
$imgHeight = imagesy($im);
for ($y=0; $y < $imgHeight; $y++)
{
for ($x=0; $x < $imgWidth; $x++)
{
$index = imagecolorat($im,$x,$y);
$Colors = imagecolorsforindex($im,$index);
$Colors['red']=intval((($Colors['red'])+15)/32)*32; //ROUND THE COLORS, TO REDUCE THE NUMBER OF COLORS, SO THE WON'T BE ANY NEARLY DUPLICATE COLORS!
$Colors['green']=intval((($Colors['green'])+15)/32)*32;
$Colors['blue']=intval((($Colors['blue'])+15)/32)*32;
if ($Colors['red']>=256)
$Colors['red']=240;
if ($Colors['green']>=256)
$Colors['green']=240;
if ($Colors['blue']>=256)
$Colors['blue']=240;
$hexarray[]=substr("0".dechex($Colors['red']),-2).substr("0".dechex($Colors['green']),-2).substr("0".dechex($Colors['blue']),-2);
}
}
$hexarray=array_count_values($hexarray);
natsort($hexarray);
$hexarray=array_reverse($hexarray,true);
return $hexarray;
}
else die("You must enter a filename! (\$image parameter)");
}
So I am asking if anyone knows how I can do such a task with PHP? Possibly something exist already that you know of or any tips to put me a step closer to doing this would be appreciated
Here's exactly what you're looking for in PHP: https://github.com/thephpleague/color-extractor
Example :
use League\ColorExtractor\Palette;
$palette = Palette::fromFilename('some/image.png');
$topEightColors = $palette->getMostUsedColors(8);
This is my simple method to get the main color of an image
$image=imagecreatefromjpeg('image.jpg');
$thumb=imagecreatetruecolor(1,1);
imagecopyresampled($thumb,$image,0,0,0,0,1,1,imagesx($image),imagesy($image));
$mainColor=strtoupper(dechex(imagecolorat($thumb,0,0)));
echo $mainColor;
You need to scale down the picture and you will get the main colors of the picture. If you need 4 colors in the pallet, scale it down to about 8x8, 6 colors to about 12x8 and so on...
imagecopyresized for scaled down image then check every pixels and store them in array imagecolorat($image,px,py)
Try this out
<?php
// EXAMPLE PICTURE
$url='https://www.nordoff-robbins.org.uk/sites/default/files/google.jpg';
//var_dump(getColorPallet($url));
echoColors(getColorPallet($url));
function echoColors($pallet){ // OUTPUT COLORSBAR
foreach ($pallet as $key=>$val)
echo '<div style="display:inline-block;width:50px;height:20px;background:#'.$val.'"> </div>';
}
function getColorPallet($imageURL, $palletSize=[16,8]){ // GET PALLET FROM IMAGE PLAY WITH INPUT PALLET SIZE
// SIMPLE CHECK INPUT VALUES
if(!$imageURL) return false;
// IN THIS EXEMPLE WE CREATE PALLET FROM JPG IMAGE
$img = imagecreatefromjpeg($imageURL);
// SCALE DOWN IMAGE
$imgSizes=getimagesize($imageURL);
$resizedImg=imagecreatetruecolor($palletSize[0],$palletSize[1]);
imagecopyresized($resizedImg, $img , 0, 0 , 0, 0, $palletSize[0], $palletSize[1], $imgSizes[0], $imgSizes[1]);
imagedestroy($img);
//CHECK IMAGE
/*header("Content-type: image/png");
imagepng($resizedImg);
die();*/
//GET COLORS IN ARRAY
$colors=[];
for($i=0;$i<$palletSize[1];$i++)
for($j=0;$j<$palletSize[0];$j++)
$colors[]=dechex(imagecolorat($resizedImg,$j,$i));
imagedestroy($resizedImg);
//REMOVE DUPLICATES
$colors= array_unique($colors);
return $colors;
}
?>
Works perfect for me.
The page you linked to has a link to the source code on GitHub so if you want to know exactly how they are doing you could replicate their source in PHP.
The big difference between how they are doing it and how you are doing it, is that they are using clustering to find the color. Instead of rounding the color when they store it, they are storing all of the raw colors in an array. Then they loop through this array until they find a cluster that has the highest ratio of points in the cluster to number of colors in the cluster. The center point of this is the most common color. The palette is then defined by the next highest sets of clusters, with some logic to prevent near complete overlap of the clusters.
Try this: http://www.coolphptools.com/color_extract
Works with JPEG and PNG.
And best!: no hustle with composer, just require_once
require_once 'colorextract/colors.inc.php';
$ex=new GetMostCommonColors();
$num_results=20;
$reduce_brightness=1;
$reduce_gradients=1;
$delta=24;
$colors=$ex->Get_Color( 'image.png', $num_results, $reduce_brightness, $reduce_gradients, $delta);
print_r($colors);
give you something like this:
Array (
[3060a8] => 0.55827380952381
[f0a848] => 0.19791666666667
[000000] => 0.069642857142857
[483018] => 0.02047619047619
[786018] => 0.01827380952381
[183060] => 0.01797619047619
[4878a8] => 0.016011904761905
[181800] => 0.015119047619048
[a87830] => 0.014345238095238
[a8c0d8] => 0.011904761904762
[6090c0] => 0.01172619047619
[d89030] => 0.011011904761905
[90a8d8] => 0.0071428571428571
[ffffff] => 0.0070238095238095
[604830] => 0.006547619047619
[f0f0f0] => 0.0063095238095238
[d8d8f0] => 0.005297619047619
[c0d8d8] => 0.0044047619047619
[f0f0ff] => 0.00041666666666667
[181830] => 0.00011904761904762 )
I tried it with different images and it seems reliable.
The idea of getting the predominant colors of the image is a bit tricky, because for example the most frequent pixel color could be so widely scattered in the image that it is not perceived as a predominant color at all.
I think an algorithm like Color coherence vector will be good enough to overcome this issue, because it clusters the colors into coherent and incoherent (which is quite intuitive), and then you can use them to discard those false positive predominant colors.
I see it is an easy algorithm to implement, this tutorial Image Retrieval: Color Coherence Vector describes describes its steps with examples of how it works and there is even a matlab implementation mentioned at the end of it.
I have a Unix bash shell script with ImageMagick called dominantcolor that may do what you want. See my scripts web site at http://www.fmwconcepts.com/imagemagick/index.php. You an run it from PHP exec(). See my pointers for use on my home page.
Input:
dominantcolor -n 6 -p all -s save plate.png
count,hexcolor
586,#5ECADC
520,#AFA85D
469,#3C3126
462,#B9C8BB
258,#488A70
205,#B06928
The -n 6 is the desired number of colors in the color quantization. The -p all means print all counts and colors for the resulting 6 colors. The -s save indictates to save a swatch image.
Colors below are shown with the dominant color on the left and decreasing count colors towards the right according to the list above.

find memory usage

I have a table with 150x150 cells which each have a colored background and a small image/symbol in them. Additionally each cell can have zero or more of it's borders set also. The user can change and add borders and change the cell color and cell. This all works pretty well using jquery and it is just a plain html table.
At the end of the user experience I am making a pdf of this table for them to download. This is a big job and takes a while, which is not my main concern now. jQuery gathers the table data in an array and sends it to php to recreate it as an image using the gd library.
So for each cell I was drawing a rectangle of the correct color on a large image, loading the symbol image and resampling it on to the large image, drawing the borders and imagedestroy the symbol image, it worked but took 1 minute. I changed my strategy to make a small colored rectangke impose the image on it and cache it in an array to be quickly used again. That sped my time up and brought it down to 30ish seconds, but now I am exhausting memory.
I am breaking the table down into 50 cell blocks so each fits on a page, each block is made into an image and saved to disk, the next is made and saved, etc. Each time the gd image is destroyed. Then all the blocks are inserted into the pdf.
So after all that, my question is how do I figure out where the memory is being used so I can try to free it up? I have posted the main function I think is causing the issue below. In my test there are up to 30 different symbols/colors images that are 25pxX25px, these are the images that are cached in an array.
I hope I have provided enough info and my problem is clear enough.
Thank you for your time,
Todd
//make one "block" of stitches returns image file name.
//function makeStitchChartBlock($img, $startX, $startY, $endX, $endY, $caption, $brand){
function makeStitchChartBlock($stitchChartArray, $startX, $startY, $endX, $endY, $caption, $brand,$blockNumber){
global $threadColours;
$stitchCache=array();
$saveTo = 'result'.$blockNumber.'.jpeg';
// calculate size of block
$numRows=($endY-$startY);
$numColumns=($endX-$startX);
$heightOfBlock = $numRows*SYMBOL_SIZE; //in pixels --- used to determine size of image to make for block
$widthOfBlock = $numColumns*SYMBOL_SIZE; //in pixels
//----plus any extra for captions grid lines
$heightOfBlock += (($endY-$startY)+1); //each stitch has a grid line before it and the last one also has on after it
$widthOfBlock += (($endX-$startX)+1);
// create image size of block to put stitches in
$newBlockImage = imagecreatetruecolor($widthOfBlock,$heightOfBlock);
$backStitchColor = imagecolorallocate($newBlockImage, 0, 0, 0);
// insert caption????
//draw grid lines
//$newBlockImage = addGridToImage($newBlockImage);
//keep track of where to start next cell top left
$blockX=0;
$blockY=0;
for($y = $startY; $y < $endY; $y++){ //for each pixel in height, move down 1 "row" each iteration
//echo "<tr>";
for($x = $startX; $x < $endX; $x++){ // "draws" a row (for each y pixel)
//rgb(75, 90, 60)
//x and y are column and row #'s
list($r, $g, $b) = getRGBs($stitchChartArray[$y][$x][0]); //get the rgb values for the cell
$stitchColor = imagecolorallocate($newBlockImage, $r, $g, $b);
//calculate x & y start positons
$stitchStartX=($blockX*SYMBOL_SIZE)+$blockX+1; //account for each previous stitch and the grid line, then add one for new grid line
$stitchStartY=($blockY*SYMBOL_SIZE)+$blockY+1;
$stitchEndX=$stitchStartX+(SYMBOL_SIZE);
$stitchEndY=$stitchStartY+(SYMBOL_SIZE);
/* make a symbol cell image with/without color and save it in the cache */
if(!isset($stitchCache[$r][$g][$b]))
{
//create new image
$stitchCache[$r][$g][$b] = imagecreatetruecolor(SYMBOL_SIZE,SYMBOL_SIZE);
$stitchCacheColor = imagecolorallocate($stitchCache[$r][$g][$b], $r, $g, $b);
//draw colored rectangle
imagefilledrectangle($stitchCache[$r][$g][$b], 0, 0, SYMBOL_SIZE-1, SYMBOL_SIZE-1, $stitchCacheColor);
//add the symbol
$symbolFile=$stitchChartArray[$y][$x][1];
if($symbolFile){
$symbolImage = imagecreatefrompng($symbolFile);
imagecopyresampled ($stitchCache[$r][$g][$b],$symbolImage,0,0,0,0,SYMBOL_SIZE-1,SYMBOL_SIZE-1,imagesx($symbolImage), imagesy($symbolImage) );
imagedestroy($symbolImage);
}
}
//add image from cache to the block image
imagecopyresampled ($newBlockImage,$stitchCache[$r][$g][$b],$stitchStartX, $stitchStartY,0,0,SYMBOL_SIZE,SYMBOL_SIZE,SYMBOL_SIZE,SYMBOL_SIZE);
//add the backstitch lines(borders)
if($stitchChartArray[$y][$x][2]>1) //top
{
imagefilledrectangle($newBlockImage, $stitchStartX, $stitchStartY, $stitchEndX, $stitchStartY+1, $backStitchColor);
}
if($stitchChartArray[$y][$x][3]>1) //right
{
imagefilledrectangle($newBlockImage, $stitchEndX-1, $stitchStartY, $stitchEndX, $stitchEndY, $backStitchColor);
}
if($stitchChartArray[$y][$x][4]>1) //bottom
{
imagefilledrectangle($newBlockImage, $stitchStartX, $stitchEndY-1, $stitchEndX, $stitchEndY, $backStitchColor);
}
if($stitchChartArray[$y][$x][5]>1) //left
{
imagefilledrectangle($newBlockImage, $stitchStartX, $stitchStartY, $stitchStartX+1, $stitchEndY, $backStitchColor);
}
//advance x position
$blockX++;
}
//advance y position
//reset x
$blockX=0;
$blockY++;
}
imagejpeg($newBlockImage, $saveTo);
imagedestroy($newBlockImage);
//dump stitch cache
foreach($stitchCache as $r)
{
foreach($r as $g)
{
foreach($g as $b=>$data)
{
imagedestroy($data);
}
}
}
return $saveTo;
}
I would start (if you haven't already) by getting a good IDE and a debugger as these will be invaluable tools. In this instance you may be able to use a profiler to work out where the memory is being used. Failing that some good ole' manual debugging code, say
$memory = memory_get_usage();
as the first line inside your inner loop. Then when you step through using the debugger you'll be able to see where the memory is ramping up.
btw, using global variables is generally not a good idea. You might want to pass in $threadColours as a parameter or look at other ways of getting that data into the function.

PHP image color analysis with transparency

I am currently working on an application that needs to analyse a number of images and figure out what color they're closest to.
Therefore I found a code snippet that does exactly that:
function analyzeImageColors($im, $xCount =3, $yCount =3)
{
//get dimensions for image
$imWidth =imagesx($im);
$imHeight =imagesy($im);
//find out the dimensions of the blocks we're going to make
$blockWidth =round($imWidth/$xCount);
$blockHeight =round($imHeight/$yCount);
//now get the image colors...
for($x =0; $x<$xCount; $x++) { //cycle through the x-axis
for ($y =0; $y<$yCount; $y++) { //cycle through the y-axis
//this is the start x and y points to make the block from
$blockStartX =($x*$blockWidth);
$blockStartY =($y*$blockHeight);
//create the image we'll use for the block
$block =imagecreatetruecolor(1, 1);
//We'll put the section of the image we want to get a color for into the block
imagecopyresampled($block, $im, 0, 0, $blockStartX, $blockStartY, 1, 1, $blockWidth, $blockHeight );
//the palette is where I'll get my color from for this block
imagetruecolortopalette($block, true, 1);
//I create a variable called eyeDropper to get the color information
$eyeDropper =imagecolorat($block, 0, 0);
$palette =imagecolorsforindex($block, $eyeDropper);
$colorArray[$x][$y]['r'] =$palette['red'];
$colorArray[$x][$y]['g'] =$palette['green'];
$colorArray[$x][$y]['b'] =$palette['blue'];
//get the rgb value too
$hex =sprintf("%02X%02X%02X", $colorArray[$x][$y]['r'], $colorArray[$x][$y]['g'], $colorArray[$x][$y]['b']);
$colorArray[$x][$y]['rgbHex'] =$hex;
//destroy the block
imagedestroy($block);
}
}
//destroy the source image
imagedestroy($im);
return $colorArray;
}
Problem is that whenever I provide an image with transparency, GDLib consinders the transparency to be black, thus producing a wrong (much darker) output than is really the case.
For example this icon where the white area around the arrow is actually transparent:
example http://img651.imageshack.us/img651/995/screenshot20100122at113.png
Can anyone tell me how to work around this?
You need imageColorTransparent(). http://www.php.net/imagecolortransparent
Transparency is a property of the image, not of a color. So use something like $transparent = imagecolortransparent($im) to see if there is any transparency on your image, then just ignore that color in your $colorArray or have some other way to identify the transparent color in the return from your function. That all depends on how you're using the returned data.
--M

Categories