2011-12-07 5 views
1

Я пытаюсь (на Java) получить полученный цвет, когда я совмещаю 2 цвета, один сверху имеет альфа-прозрачность. В принципе, я пытаюсь назначить фоновый цвет изображения, но я разбил его на каждый пиксель, который менялся индивидуально. Я просмотрел несколько статей, в том числе this one, но безрезультатно. Кто-нибудь знает, как выполнить такое смешивание цветов RGBA/RGB? Мой текущий код использует этот формат PNG:Сочетание 2 цветов RGB с альфой

PNG Image

И производит этот JPG:

JPG Image

Это функция, которую я сейчас использую. Фон для демонстрационных изображений был установлен полный синий, или межд 255.

public static void PNGToJPEGConvert(String PNGPath, String NewJPEGPath, int BackColor) throws IOException { 
    try { 
     BufferedImage bufferedImage = ImageIO.read(new File(PNGPath)); 
     BufferedImage newImage; 
     int R1, G1, B1, R2 = (BackColor & 0xFF0000) >> 16, G2 = (BackColor & 0xFF00) >> 8, B2 = (BackColor & 0xFF), W1, W2, W3, M1, M2, R3, G3, B3; 
     float br; 
     newImage = new BufferedImage(bufferedImage.getWidth(), bufferedImage.getHeight(), BufferedImage.TYPE_4BYTE_ABGR); 
     for(int x=0; x < bufferedImage.getWidth(); x++) { 
      for(int y=0; y < bufferedImage.getHeight(); y++) { 
       R1 = BufferedImageGetPixelARGB(bufferedImage, "R", x, y); 
       G1 = BufferedImageGetPixelARGB(bufferedImage, "G", x, y); 
       B1 = BufferedImageGetPixelARGB(bufferedImage, "B", x, y); 
       W1 = Math.min(R1, Math.min(G1, B1)); 
       W2 = Math.min(R2, Math.min(G2, B2)); 
       R1 -= W1; 
       G1 -= W1; 
       B1 -= W1; 
       R2 -= W2; 
       G2 -= W2; 
       M1 = Math.max(R1, Math.max(G1, B1)); 
       M2 = Math.max(R2, Math.max(G2, B2)); 
       br = (M1 + M2)/(2*BufferedImageGetPixelARGB(bufferedImage, "A", x, y)); 
       R3 = (int) ((R1 + R2) * br); 
       G3 = (int) ((G1 + G2) * br); 
       B3 = (int) ((B1 + B2) * br); 
       W3 = (W1 + W2)/2; 
       R3 += W3; 
       G3 += W3; 
       B3 += W3; 
       newImage.setRGB(x, y, RGBValuesToInt(R3, G3, B3)); 
      } 
     } 
     try { 
      ImageIO.write(newImage, "jpg", new File(NewJPEGPath)); 
     } catch(Exception e) { 

     } 
    } catch(Exception e) { 

    } 
} 

Спасибо за помощь, -Neil

ответ

2

В основном это

float masking_factor = mask_value/255.0; 
composed_value = int(
    source_pixel_value * (1 - masking_factor) + 
    overlay_pixel_value * masking_factor 
); 

Мы полагаем, что все значения являются 8-битными, то есть от 0 до 255, а mask является монохромным. Где mask полностью черный, он полностью прозрачный, и видны только пиксели источника. Где mask полностью белый, он полностью непрозрачен и видны только перекрывающиеся пиксели. Значения между ними дают промежуточную непрозрачность.

Но если альфа-смешение является только вещь, которую вы хотите реализовать, есть более эффективные способы сделать это, чем работать с отдельными пикселями. См. Graphics2D и его метод .setComposite().

3
public static Color mixColorsWithAlpha(Color color1, Color color2, int alpha) 
{ 
    float factor = alpha/255f; 
    int red = (int) (color1.getRed() * (1 - factor) + color2.getRed() * factor); 
    int green = (int) (color1.getGreen() * (1 - factor) + color2.getGreen() * factor); 
    int blue = (int) (color1.getBlue() * (1 - factor) + color2.getBlue() * factor); 
    return new Color(red, green, blue); 
} 

Это будет то же самое, что и цвет картины2 (с заданным значением альфа) над цветом1.

+0

Это помогло мне смешать цвет с черным, чтобы получить более темную версию. Благодаря! – speedynomads

Смежные вопросы