Сочетание 2 цветов RGB с альфа - PullRequest
3 голосов
/ 07 декабря 2011

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

PNG Image

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

JPG Image

Это функция, которую яв настоящее время использую.Фон для демонстрационных изображений был установлен на синий цвет, или значение int 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 ]

5 голосов
/ 10 апреля 2014
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);
}

Это будет то же самое, что и рисование color2 (с заданным альфа-значением) поверх color1.

2 голосов
/ 07 декабря 2011

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

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 полностью белый, он полностью непрозрачный, и видны только наложенные пиксели. Значения между ними дают промежуточную непрозрачность.

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

...