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

时间:2017-09-03 18:48:20

标签: java arrays image binary bitwise-operators

我有一个字节数组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

提前感谢任何建议

4 个答案:

答案 0 :(得分:0)

您可以使用255对值进行异或,因此特定行应为

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

答案 1 :(得分:0)

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。

答案 2 :(得分:0)

你可以保持原样。它已经是正确的,只是以一种令人困惑的方式打印出来。

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

简而言之,什么都不做。

答案 3 :(得分:0)

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()
}

If you want to convert to BufferedImage