Results 1 to 8 of 8

Thread: determine colors used in an image

  1. #1
    Join Date
    Jan 2007
    Location
    Davenport, Iowa
    Posts
    2,385
    Thanks
    100
    Thanked 113 Times in 111 Posts

    Default determine colors used in an image

    I am learning more about the GD library of functions in php. I also know that it is a bit processor heavy, so I am trying to figure out a way to determine which colors are used in an image.

    Let's say I take a jpeg image and convert it to palette form with 125 possible colors using the function imagetruecolortopalette(). I then use imagecolorstotal() to determine that the image only has 100 different colors in its image. That is still 100 different colors from a possible 16.7 million different colors. I can use imagecolorclosest() to discover the exact value of any one color that is closest to say the color black.

    Now that I know the value of that one color that came closest to the color black I could convert all of that color in the image to white to get it out of the way and rescan the image for the next closest color to black.

    While this would work, it would also be incredibly taxing on the server if I were to actually use the method described above. Can anyone describe a better way to determine the values of the 100 colors that are used in this hypothetical image that is not so processor heavy?

    What I have described is the best way I can think of so far. I'll try to post some php later so people can get a better idea of how this code would look in action.

  2. #2
    Join Date
    Jan 2007
    Location
    Davenport, Iowa
    Posts
    2,385
    Thanks
    100
    Thanked 113 Times in 111 Posts

    Default

    Still, working on it. Here is the latest script I am using:
    PHP Code:
    <pre><?php
    $filename 
    'http://www.animeviews.com/images/pops/maincontent1.JPG';
    $im imagecreatefromjpeg($filename); 
    imagetruecolortopalette($imfalse255);
    $aimagecolorstotal($im);
    echo
    "$a";
    $g=$a;
    $a++;
    $b=0;
    $c=0;
    $d=0;
    $e=0;
    while (
    $b<$a){
    $x=rand(0,255);
    $y=rand(0,255);
    $z=rand(0,255);
        
    $result imagecolorclosest($im$x$y$z);
    $c++;
    ##if ($c>255){$d++;$c=255;}
    ##if ($d>255){$e++;$d=255;}
    $e++;
        
    $result imagecolorsforindex($im$result);
        
    $result "({$result['red']}{$result['green']}{$result['blue']})";
        
    $arry[]="$result";
    $arry=array_unique($arry);
    $b=count($arry);
    if (
    $b>254){break;}
    if (
    $e>10000){break;}
    }
    print_r($arry);Echo"<br><br>$b";
    ?></pre>
    It will generate random colors to check until it either finds all of the colors or goes through 10000 tries; which ever comes first.

    EDIT: The following is better:
    PHP Code:
    <pre><?php
    $filename 
    'http://www.animeviews.com/images/pops/maincontent1.JPG';
    $im imagecreatefromjpeg($filename); 
    imagetruecolortopalette($imfalse25);
    $aimagecolorstotal($im);
    echo
    "$a";
    $e=0;
    while (
    $b<$a){
    $x=rand(0,255);
    $y=rand(0,255);
    $z=rand(0,255);
        
    $result imagecolorclosest($im$x$y$z);
    $e++;
        
    $result=imagecolorsforindex($im$result);
        
    $result="({$result['red']}{$result['green']}{$result['blue']})";
        
    $arry[]="$result";
    $arry=array_unique($arry);
    $b=count($arry);
    if (
    $e>10000){break;}
    }
    asort($arry);
    print_r($arry);Echo"<br><br>
    number of colors in image=
    $a
    <br>number of colors located=
    $b
    <br>Number of tries=
    $e<br>";
    ?></pre>
    It seems that one of my errors was that imagecolorstotal() determines how many colors are in the palette; not how many colors were used from the palette.

    On a side note I am not all that good at using the semicolon in a sentence :?.
    Last edited by james438; 09-12-2008 at 10:32 PM. Reason: punctuation

  3. #3
    Join Date
    Mar 2006
    Location
    Illinois, USA
    Posts
    12,164
    Thanks
    265
    Thanked 690 Times in 678 Posts

    Default

    I think there are optimization functions specifically for this, if you want to output a gif, for example. I'm not quite sure on which would work best for you at the moment, but they're worth looking into.
    Your method is incredibly inefficient, not that you're coding it wrong, because you have to manually run through pixels. GD isn't incredibly slow, in some ways, but when you're running through individual pixels, as is needed to do most anything manually, it will be.
    Any built in function will likely be faster, if it exists, if for nothing else than that it may be able to avoid some of the steps you're required to take per pixel.
    (The slowest functions in GD, when I'm working on stuff, I find, are getting and setting pixel colors. The rest, the math, etc., isn't that bad.)
    Daniel - Freelance Web Design | <?php?> | <html>| español | Deutsch | italiano | português | català | un peu de français | some knowledge of several other languages: I can sometimes help translate here on DD | Linguistics Forum

  4. #4
    Join Date
    Jan 2007
    Location
    Davenport, Iowa
    Posts
    2,385
    Thanks
    100
    Thanked 113 Times in 111 Posts

    Default

    Thank you for reading. Yes, it is incredibly inefficient, but sadly it is the most efficient way I can think of. I have spent a lot of time scanning the many functions in the GD library listed at php.net, but so far I have been unable to find anything that will display the colors used in an image that is either truecolor or preferably palette format. I am rather surprised that I have not been able to find a built in function that does this. imagecolorclosest() is the best that I can find thus far.

    Not even all that sure why I am trying to figure this out. Just curious I guess

    Ah, well. Thanks for for the tips and explanations!

  5. #5
    Join Date
    Mar 2006
    Location
    Illinois, USA
    Posts
    12,164
    Thanks
    265
    Thanked 690 Times in 678 Posts

    Default

    As I said, this is the fault of GD, not your approach. GD is, unfortunately, nearly worthless sometimes, because it's just such a pain to run.

    I'm not really sure what you're going for, and there might be a way to find more info, though if you're just curious about this specifically, not sure if there's an answer. But if you want to accomplish something with those colors, for example, there might be another method.
    Daniel - Freelance Web Design | <?php?> | <html>| español | Deutsch | italiano | português | català | un peu de français | some knowledge of several other languages: I can sometimes help translate here on DD | Linguistics Forum

  6. #6
    Join Date
    Jan 2007
    Location
    Davenport, Iowa
    Posts
    2,385
    Thanks
    100
    Thanked 113 Times in 111 Posts

    Default

    heh, I thought you were agreeing with me that my code was poorly written as opposed to GD being poorly designed . I can misunderstand people in forums that way.

    I kinda like GD. I don't really have mauch experience with image manipulation using any other program like photoshop or what not. Why do you find GD a pain to run sometimes? I probably just like it because it is a rather new discovery for as to what else PHP can do.

    Possible uses I see include:
    • automatically resize images submitted to a website with minimal loss in quality
    • generate thumbnails of all the images in a folder
    • creeate rounded corners, generate images with words written on it for a password protection against robots
    • use it to analyze a picture for general image manipulation (fun).

    In this case my curiosity lies in what GD's potential could be for my site and also to figure out a way to best create a program that better answers the post located in: UNSOLVED: Dynamically changing colors and resizing image.

    It is a little frustrating though, because I would figure that there would be a better way to determine what the specific colors are that are used in an image as opposed to the hunt and peck method that I am resorting to. I also can not see any reliable way to determine exactly how many colors are used in an image .

    No real questions here I guess. I think I may have what I need to design a simple image manipulation program that will take a jpeg file and allow the casual user to alter the different colors in an image how they want. I am rather curious what an image would look like if I were to randomize the colors .

  7. #7
    Join Date
    Mar 2006
    Location
    Illinois, USA
    Posts
    12,164
    Thanks
    265
    Thanked 690 Times in 678 Posts

    Default

    No, you were right. I'm saying that there may be another method, using something more efficient in GD, to get your END GOAL done, and somehow bypass this (slow) step.

    GD is slow and hard to work with. It has a lot of potential. I don't dislike it, exactly, but it's frustrating to work with. If you do something complex enough, it will take too much server processing power (my account got suspended once, just for running a single script a few times that was generating a pattern-based image).

    For some of the simpler uses, it's fine. And for smaller images, especially, it's good.


    So, ok, for your real application you'd want to shift the colors in an image randomly while keeping the distributions of any certain color the same?

    That would look really odd, and probably not be visibly related to the old image.
    Daniel - Freelance Web Design | <?php?> | <html>| español | Deutsch | italiano | português | català | un peu de français | some knowledge of several other languages: I can sometimes help translate here on DD | Linguistics Forum

  8. #8
    Join Date
    Jan 2007
    Location
    Davenport, Iowa
    Posts
    2,385
    Thanks
    100
    Thanked 113 Times in 111 Posts

    Default

    Yes, I am at a bit of an impasse with this script as far as making it more efficient. In other words this is as efficient as I know how to make it at present. I have been over and over the functions in the GD library, but have not found one that will help.

    I finished my little toy script by the way
    PHP Code:
    <?php
    header
    ('Content-type: image/jpeg');
    $filename 'http://www.animeviews.com/images/screenshots/cowboybebop27.JPG';
    $im imagecreatefromjpeg($filename); 
    imagetruecolortopalette($imfalse25);
    $e=0;
    while (
    $e<10000){
    $x=rand(0,255);
    $y=rand(0,255);
    $z=rand(0,255);
    $result imagecolorclosest($im$x$y$z);
    $e++;
    $exact[]=$result;
    $result=imagecolorsforindex($im$result);
    $result="{$result['red']},{$result['green']},{$result['blue']}";
    $arry[]="$result";
    $arry =array_unique($arry);
    $exact=array_unique($exact);
    }
    $e=0;
    $b=count($arry);
    natsort($arry);
    natsort($exact);
    $arry=array_values($arry);
    $exact=array_values($exact);
    shuffle($arry);
    while(
    $e<=$b)
    {
    $arry[$e]=explode(',',$arry[$e]);
    imagecolorset($im,$exact[$e],$arry[$e][0],$arry[$e][1],$arry[$e][2]);
    $e++;
    }
    imagejpeg($imnull100);
    ?>
    It looks a bit psychedelic. Basically it looks like a negative of an image. The best results are when I keep the palette size small < 25 colors. I'll add this to my tiny collection of GD scripts. This latest one makes me feel like I have gotten my feet sufficiently wet with the GD library of php.

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •