Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Parsing a "rgb (x, x, x)" String Into a Color Object

Tags:

java

colors

gwt

Is there an effecient way/existing solution for parsing the string "rgb (x, x, x)" [where x in this case is 0-255] into a color object? [I'm planning to use the color values to convert them into the hex color equivilience.

I would prefer there to be a GWT option for this. I also realize that it would be easy to use something like Scanner.nextInt. However I was looking for a more reliable manner to get this information.

like image 372
monksy Avatar asked Sep 30 '11 17:09

monksy


3 Answers

As far as I know there's nothing like this built-in to Java or GWT. You'll have to code your own method:

public static Color parse(String input) 
{
    Pattern c = Pattern.compile("rgb *\\( *([0-9]+), *([0-9]+), *([0-9]+) *\\)");
    Matcher m = c.matcher(input);

    if (m.matches()) 
    {
        return new Color(Integer.valueOf(m.group(1)),  // r
                         Integer.valueOf(m.group(2)),  // g
                         Integer.valueOf(m.group(3))); // b 
    }

    return null;  
}

You can use that like this

// java.awt.Color[r=128,g=32,b=212]
System.out.println(parse("rgb(128,32,212)"));     

// java.awt.Color[r=255,g=0,b=255]                         
System.out.println(parse("rgb (255, 0, 255)"));   

// throws IllegalArgumentException: 
// Color parameter outside of expected range: Red Blue
System.out.println(parse("rgb (256, 1, 300)"));  
like image 141
Confluence Avatar answered Oct 22 '22 04:10

Confluence


For those of use who don't understand regex:

public class Test
{
    public static void main(String args[]) throws Exception
    {
        String text = "rgb(255,0,0)";
        String[] colors = text.substring(4, text.length() - 1 ).split(",");
        Color color = new Color(
            Integer.parseInt(colors[0].trim()),
            Integer.parseInt(colors[1].trim()),
            Integer.parseInt(colors[2].trim())
            );
        System.out.println( color );
    }

}

Edit: I knew someone would comment on error checking. I was leaving that up to the poster. It is easily handled by doing:

if (text.startsWith("rgb(") && text.endsWith(")"))
   // do the parsing
   if (colors.length == 3)
      // build and return the color

return null;

The point is your don't need a complicated regex that nobody understands at first glance. Adding error conditions is a simple task.

like image 4
camickr Avatar answered Oct 22 '22 04:10

camickr


I still prefer the regex solution (and voted accordingly) but camickr does make a point that regex is a bit obscure, especially to kids today who haven't used Unix (when it was a manly-man's operating system with only a command line interface -- Booyah!!). So here is a high-level solution that I'm offering up, not because I think it's better, but because it acts as an example of how to use some the nifty Guava functions:

package com.stevej;

import com.google.common.base.CharMatcher;
import com.google.common.base.Splitter;
import com.google.common.collect.Iterables;

public class StackOverflowMain {

  public static void main(String[] args) {

    Splitter extractParams = Splitter.on("rgb").omitEmptyStrings().trimResults();

    Splitter splitParams =
        Splitter.on(CharMatcher.anyOf("(),").or(CharMatcher.WHITESPACE)).omitEmptyStrings()
            .trimResults();

    final String test1 = "rgb(11,44,88)";

    System.out.println("test1");
    for (String param : splitParams.split(Iterables.getOnlyElement(extractParams.split(test1)))) {
      System.out.println("param: [" + param + "]");
    }

    final String test2 = "rgb      ( 111,         444         , 888         )";

    System.out.println("test2");
    for (String param : splitParams.split(Iterables.getOnlyElement(extractParams.split(test2)))) {
      System.out.println("param: [" + param + "]");
    }

  }
}

Output:

test1
param: [11]
param: [44]
param: [88]
test2
param: [111]
param: [444]
param: [888]

It's regex-ee-ish without the regex.

It is left as an exercise to the reader to add checks that (a) "rgb" appears in the beginning of the string, (b) the parentheses are balanced and correctly positioned, and (c) the correct number of correctly formatted rgb integers are returned.

like image 2
Steve J Avatar answered Oct 22 '22 04:10

Steve J