2010-03-03 3 views
5

Мне интересно, есть ли более эффективный метод замены цветов в BufferedImage. В настоящий момент я использую следующий метод:Как заменить цвета в BufferedImage в JAVA

Я заполняю массив цветами, подлежащими замене, и цветами для их замены, включая прозрачность. Затем я просматриваю каждый пиксель в изображении. Если он соответствует одному из цветов в массиве, я заменяю его новым цветом из массива. Вот код:

Graphics2D g2; 
    g2 = img.createGraphics(); 
    int x, y, i,clr,red,green,blue; 

    for (x = 0; x < img.getWidth(); x++) { 
    for (y = 0; y < img.getHeight(); y++) { 

     // For each pixel in the image 
     // get the red, green and blue value 
     clr = img.getRGB(x, y); 
     red = (clr & 0x00ff0000) >> 16; 
     green = (clr & 0x0000ff00) >> 8; 
     blue = clr & 0x000000ff; 

     for (i = 1; i <= Arraycounter; i++) { 
     // for each entry in the array 
     // if the red, green and blue values of the pixels match the values in the array 
     // replace the pixels color with the new color from the array 
     if (red == Red[i] && green == Green[i] && blue == Blue[i]) 
     { 
      g2.setComposite(Transparency[i]); 
      g2.setColor(NewColor[i]); 
      g2.fillRect(x, y, 1, 1); 
     } 
     } 
    } 

Изображения, с которыми я работаю, маленькие, 20x20 пикселей или около того. Тем не менее, похоже, должен быть более эффективный способ сделать это.

+0

Возможно, если вы объясните первоначальную проблему, мы сможем помочь больше – medopal

+0

Код создает изображения, которые будут использоваться как легенда на карте. У нас есть набор шаблонных изображений с четырьмя цветами. черный, красный, зеленый и синий. В зависимости от тематического представления на карте изображения шаблонов должны иметь правильный цвет. Черный будет преобразован в цвет фона, красный правильный цвет границы, зеленый хеш-узор и синие области станут прозрачными. – Rene

ответ

10

Вместо изменения значения пикселей изображения вы можете изменить базовый ColorModel. Гораздо быстрее этот путь и не нужно перебирать весь образ, чтобы он хорошо масштабировался.

+1

'ColorMap' не является классом в Java API. Как он должен это делать? – uckelman

+2

Thats была опечатка (которая уже была исправлена), вниз голосование кажется немного резким – objects

+0

И техника работает хорошо, использовала ее для просмотра медицинских изображений, где контраст изображения нужно было отрегулировать в реальном времени. Изменение отдельных значений пикселей слишком медленное. – objects

3

Используйте HashMap<Color,Color>. Ключ должен быть оригинальным цветом, а значение - заменой. Если get возвращает null, ничего не делайте.

3

Похоже, что идиоматический способ сделать это - реализовать LookupOp, а затем применить эту операцию для создания новой цели BufferedImage. Есть отличный ответ here.

+0

Что мне нужно сделать, так это преобразовать красный, зеленый, синий и черный пиксели в новый цвет. Можно ли это сделать с помощью LookupOp? Кажется, что каждый компонент цвета работает индивидуально. – Rene

+0

Я не использовал его, но я не уверен, что это возможно. Глядя на ответ, я ссылаюсь, похоже, что LookupTable (построенный с помощью 2D-массива) используется для сопоставления цветов источника с назначением. Посмотрите метод LookupPixel LookupTable ... Я уверен, что это то, что будет вызываться, как правило, с 4-элементным массивом src, содержащим значения RGBA (вы должны это проверить). – Adamski