0

I have an array of bytes, byte bytes[], representing a greyscale image.

I want to invert the colours of this image - so figured I would just flip the bits (bitwise not).

I have attempted this as seen below (have included an extra loop to populate a dummy byte array to allow quick and easy re-creation of my problem)

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]);
 } 

The results I am getting are:

116 -117

48 -49

70 -71

What I'm looking for is: (I have added the binary manually to fuly illustrate what my understanding of bitwise not (please correct if wrong)

116 (01110100) = (10001011) 139

48 (00110000) = (11001111) 207

70 (01000110) = (10111001) 185

Thanks in advance for any advice

1
  • Regarding your comment, Java does not treat a byte array as an int array, but it does automatically convert narrower types to int when you perform an operation on them. It's the ~ that makes it an int (and yes you can just cast back) Commented Sep 3, 2017 at 19:18

4 Answers 4

1

You can XOR the value with 255, so the particular line should be

bytes[i] = (byte) (bytes[i] ^ 0xff);
Sign up to request clarification or add additional context in comments.

3 Comments

That's exactly the same thing
I answered 5 minutes earlier than Roman, so your comment should be there ;-)
No, it's exactly the same thing as OP already has. (byte)~x is the same thing as (byte)(x ^ 0xff) for all values of x. It's easy to prove it too: ~ and ^ 0xff do (by design) the same operation on the low 8 bits. They differ in the upper bits, but the cast removes them.
0

10001011 actually represents -117 (in two's complement format: https://en.wikipedia.org/wiki/Two%27s_complement ); Java byte type is signed. You probably want unsigned byte values as output (which range from 0 to 255).

As Java byte type is signed, it can only have values from -128 to 127. If you want to have values between 0 and 255 (like 139), you have to use some other type, for example short:

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

This produces 139.

3 Comments

Many thanks for the response. This works perfectly for positive numbers, but for negative numbers produces results in the region 65000. Do you have any idea what would be causing that behaviour?
I've updated the answer to use short; it seems to work correctly for negative values as well.
You really don't have to use shorts here though.. an unsigned byte fits just fine in a signed byte, they're both 8 bits.
0

You can leave it as it is. It's already correct, just printed in a confusing way.

For example note that (byte)207 will (by default) be printed as -49. But it's still the same value, it's just printed with a different interpretation of the most significant bit.

In short, change nothing.

Comments

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 xor syntax

import kotlin.experimental.xor

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

kotlin with Byte.inv() syntax

import kotlin.experimental.inv

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

If you want to convert to BufferedImage

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.