Я пытаюсь инвертировать альфа буферизованного изображения, но вместо того, чтобы инвертировать альфа, он возвращает странное желтое изображение.

Это оригинал до инверсии original

Вот что он возвращает: return

public void invertAlpha(BufferedImage lightmap){    
    int[] values = (int[])lightmap.getRaster().getDataElements(0, 0, lightmap.getWidth(), lightmap.getHeight(), null);
    for(int i = 0; i < values.length; i += 1) values[i] = (byte)(invertAlphaofPixel(values[i]));

    lightmap.getRaster().setDataElements(0, 0, lightmap.getWidth(), lightmap.getHeight(), values);
}
public int invertAlphaofPixel(int value){

    byte R = (byte) (value & 255); 
    byte G = (byte) ((value >> 8) & 255); 
    byte B = (byte) ((value >> 16) & 255); 
    byte A = (byte) ((value >> 24) & 255);
    A = (byte) (A ^ 0xff); //basically A = 255 - A I believe?

    return A | R | G |B;
}
1
Kyranstar 25 Янв 2014 в 04:05

1 ответ

Лучший ответ
return A | R | G |B;

Значения A, R, G и B - все байты, поэтому результатом их объединения является байт, который затем расширяется знаком до внутр. Вам нужно перестроить значение int ARGB, обратное тому, как вы его разобрали, с помощью сдвигов и или.

В вашем коде конечный результат, скорее всего, будет выглядеть так:

0xffffff??

Где ?? - это "или" значений. Т.е. он будет ярко-красный + зеленый (отсюда желтый) с небольшими вариациями в синем канале, но, вероятно, также будет гореть большинство битов.

Вы хотите

return ((int)A)<<24 | 
        0x00FF0000 & ((int)B)<<16 | 
        0x0000FF00 & ((int)G)<<8  | 
        0x000000FF & ((int)R);

Кроме того, судя по выходным данным, я подозреваю, что ваше изображение относится к типу TYPE_INT_ARGB, а не TYPE_4BYTE_ABGR.

3
Jim Garrison 25 Янв 2014 в 04:20