【问题标题】:Inverting colours of a greyscale image (in java) stored as a byte array反转存储为字节数组的灰度图像(在 java 中)的颜色
【发布时间】:2018-02-12 02:03:21
【问题描述】:

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

提前感谢您的任何建议

【问题讨论】:

  • 关于您的评论,Java 不会将字节数组视为 int 数组,但是当您对它们执行操作时,它会自动将更窄的类型转换为 int。是 ~ 使它成为 int (是的,您可以直接回退)

标签: java arrays image binary bitwise-operators


【解决方案1】:

你可以用 255 异或这个值,所以特定的行应该是

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

【讨论】:

  • 完全一样
  • 我比 Roman 早了 5 分钟回答,所以你的评论应该在那里 ;-)
  • 不,它与 OP 已经拥有的完全一样。对于x 的所有值,(byte)~x(byte)(x ^ 0xff) 相同。这也很容易证明:~^ 0xff(通过设计)对低 8 位执行相同的操作。它们在高位上有所不同,但演员将它们移除。
【解决方案2】:

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。

【讨论】:

  • 非常感谢您的回复。这对于正数非常有效,但对于负数会在 65000 区域产生结果。您知道是什么导致了这种行为吗?
  • 我已将答案更新为使用short;它似乎也适用于负值。
  • 你真的不必在这里使用短裤.. 无符号字节正好适合有符号字节,它们都是 8 位。
【解决方案3】:

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

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

简而言之,什么都不做。

【讨论】:

    【解决方案4】:

    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 xor 语法

    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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-02-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-08
      • 1970-01-01
      • 2023-02-22
      相关资源
      最近更新 更多