反转存储为字节数组的灰度图像(在 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
类型是有符号的,它只能有从-128
到127
的值。如果你想要 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()
}
我有一个字节数组,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
类型是有符号的,它只能有从-128
到127
的值。如果你想要 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()
}