反转存储为字节数组的灰度图像(在 java 中)的颜色

Inverting colours of a greyscale image (in java) stored as a byte array

我有一个字节数组,byte bytes[],表示灰度图像。

我想反转此图像的颜色 - 所以我想我会翻转位(不是按位)。

我已尝试这样做,如下所示(包括一个额外的循环来填充虚拟字节数组,以便快速轻松地重新创建我的问题)

Random rand = new Random();  
byte bytes[] = new byte[500];

// populate a dummy byte array
for (int i = 0; i < bytes.length; ++i)
{
    new Random().nextBytes(bytes);
    System.out.println(bytes[i]);
}

for (int i = 0; i < bytes.length; ++i)
{
    System.out.print(bytes[i] + "     ");
    //bytes[i] = ~bytes[i]; This throws an error as apparantly java treats a byte array as an integer array?!
    bytes[i] = (byte)~bytes[i]; // This compiles but output not a bitwise not, results displayed below

    System.out.println(bytes[i]);
 } 

我得到的结果是:

116 -117

48 -49

70 -71

我要找的是:(我已经手动添加了二进制来充分说明我对按位不的理解(如果错误请更正)

116 (01110100) = (10001011) 139

48 (00110000) = (11001111) 207

70 (01000110) = (10111001) 185

提前感谢您的任何建议

您可以将值与 255 进行异或运算,因此特定行应该是

bytes[i] = (byte) (bytes[i] ^ 0xff);

10001011 实际上表示 -117 (二进制补码格式: https://en.wikipedia.org/wiki/Two%27s_complement ); Java byte 类型已签名。您可能希望将无符号字节值作为输出(范围从 0 到 255)。

由于Java byte类型是有符号的,它只能有从-128127的值。如果你想要 0 到 255 之间的值(比如 139),你必须使用其他类型,例如 short:

byte b = 116;
short sh = (short) (((short) b) ^ 0xff);
System.out.println(sh);

这会产生 139。

您可以保持原样。已经正确了,只是打印的有点乱。

例如,请注意 (byte)207 将(默认情况下)打印 为 -49。但它仍然是相同的值,只是打印时对最高有效位进行了不同的解释。

简而言之,什么都不改变。

java

public static byte[] bitwiseNot(byte[] array) {
    byte[] bytes = new byte[array.length];
    for (int i = 0; i < array.length; i++) {
        bytes[i] = (byte) (array[i] ^ 0xff);
    }
    return bytes;
}

kotlin 异或语法

import kotlin.experimental.xor

fun bitwiseNot(array: ByteArray) : ByteArray {
    return array.map{ b -> b xor 0xFF.toByte() }.toByteArray()
}

具有 Byte.inv() 语法的 kotlin

import kotlin.experimental.inv

fun bitwiseNot(array: ByteArray) : ByteArray {
    return array.map{ b -> b.inv() }.toByteArray()
}