# 16bit grayscale images

**URL:** <https://discourse.processing.org/t/16bit-grayscale-images/10795>\
**Category:** Coding Questions\
**Created:** [April 30, 2019, 7:51pm UTC](https://discourse.processing.org/t/16bit-grayscale-images/10795 "2019-04-30T19:51:25Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Cerald](https://avatars.discourse-cdn.com/v4/letter/c/cc9497/32.png) [@Cerald](https://discourse.processing.org/u/Cerald)\
**Post date:** [April 30, 2019, 7:51pm UTC](https://discourse.processing.org/t/16bit-grayscale-images/10795/1 "2019-04-30T19:51:25Z")

</div>

As I understand it right now Processing uses a 32bit value for each pixel in an image, devided into 8bits for each color plus an alpha channel.  
However I would like load, modify and save grayscale images with a single 16bit channel. This type of image is often used as a heightmap. I attatched an image of the grand canyon as an example.  
As of now I can load this image in processing, however I end up with the 3 collor channels containing identical 8bit values and so loose half of the 16bits I want to work with.

![example](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/6/62446b69342a9a38f651707b34ee263777abd6e8.png)

---

<div class="post-metadata">

**Author:** ![clankill3r](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/clankill3r/32/1098_2.png) [@clankill3r](https://discourse.processing.org/u/clankill3r)\
**Post date:** [April 30, 2019, 8:29pm UTC](https://discourse.processing.org/t/16bit-grayscale-images/10795/2 "2019-04-30T20:29:46Z")

</div>

How many images are we talking about?

---

<div class="post-metadata">

**Author:** ![Cerald](https://avatars.discourse-cdn.com/v4/letter/c/cc9497/32.png) [@Cerald](https://discourse.processing.org/u/Cerald)\
**Post date:** [April 30, 2019, 8:45pm UTC](https://discourse.processing.org/t/16bit-grayscale-images/10795/3 "2019-04-30T20:45:09Z")

</div>

I want to load 2 of those images and output one. However the size of my example picture is not representative, I want to work with images up to 4100x4100 pixels. Speed is not an issue by the way.

---

<div class="post-metadata">

**Author:** ![Cerald](https://avatars.discourse-cdn.com/v4/letter/c/cc9497/32.png) [@Cerald](https://discourse.processing.org/u/Cerald)\
**Post date:** [May 1, 2019, 7:34pm UTC](https://discourse.processing.org/t/16bit-grayscale-images/10795/4 "2019-05-01T19:34:43Z")

</div>

I had a poke at it and here is what I got so far.  
I’m using a .raw format now which I actually have easier acess to.  
What I display in the green channel is already quite promissing. I still need to figure out what to do with the stuff I display in red though.

```auto
int HeightmapWidth = 100; //Width of the heightmap in pixels
byte[] Bytes; //Where I read my file to
short[] Shorts; //Hopeing to fill this with useful height data
color[] Colors; //Using this for easier debuging

void setup() {
  size(100, 100);
  Bytes = loadBytes("heightmap.raw"); //loading file into my Bytes array
  Shorts = new short[Bytes.length / 2]; //initialising to the correct size
  Colors = new color[Bytes.length / 2]; //initialising to the correct size

  for ( int i = 0; i < Bytes.length; i=i+2) {
    Shorts[i/2] = (short)(Bytes[i] << 8 | Bytes[i+1]); //not sure how the endianness works out yet
    Colors[i/2] = color(Bytes[i], Bytes[i+1], 0); //just to visualise better
  }

  background(0);
  for ( int j = 0; j < Colors.length; j++) {
    set(j%HeightmapWidth, j/HeightmapWidth, Colors[j]); //just to visualise better
  }
}

void draw() {
  //nothing to do here
}

```

Apparently I can’t attatch my heightmap.raw so I uploaded it somewhere else. Please let me know if there is a better way to do this: [https://www.file-upload.net/download-13590186/heightmap.raw.html](https://www.file-upload.net/download-13590186/heightmap.raw.html)

And here is the result of my code:  
 ![result](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/a/a2a2fd54c585c455bad4da9fceb86a9573d09c18.png)

---

<div class="post-metadata">

**Author:** ![Cerald](https://avatars.discourse-cdn.com/v4/letter/c/cc9497/32.png) [@Cerald](https://discourse.processing.org/u/Cerald)\
**Post date:** [May 2, 2019, 4:25pm UTC](https://discourse.processing.org/t/16bit-grayscale-images/10795/5 "2019-05-02T16:25:15Z")

</div>

I think I actually got done what I wanted. Signed and unsigned datatypes had me tripped up.  
So here is my code in case anyone searches for this.  
For this example I just invert the height values of my heightmap.raw and save it as output.raw

```auto
int HeightmapWidth = 100; //Width of the heightmap in pixels
char[] input; //Where I read my file to
char[] chars; //Hopeing to fill this with useful height data
byte[] output; //I put my output in here

void setup() {
  size(100, 100);
  input = char(loadBytes("heightmap.raw")); //loading file into my Bytes array
  chars = new char[input.length / 2]; //initialising to the correct size
    output = new byte[input.length]; //initialising to the correct size

  for ( int i = 0; i < input.length; i=i+2) {
    chars[i/2] = (char)(input[i+1] << 8 | input[i]); //This endianess is the right for my application
  }

  background(0);

  for ( int j = 0; j < chars.length; j++) {
    chars[j] = char(65535-chars[j]); //Inverting the height values just to try it out

    int gray8bit = int(map(chars[j], 0, 65535, 0, 255)); //turning it back into a regular color, just for display purposes
    color gray = color(gray8bit, gray8bit, gray8bit);
    set(j%HeightmapWidth, j/HeightmapWidth, gray); //displaying my result (yes would be faster with the pixels[] array)
  }

  for ( int k = 0; k < input.length; k++) {
    if (k%2 == 1) { //getting it back in the correct byte order
      output[k] = byte(chars[k/2]>>8);
    } else {
      output[k] = byte(chars[k/2]);
    }
  }
  saveBytes("output.raw", output); //saving my output
}

void draw() {
  //nothing to do here
}

```

And here is the result. I turned into a .png for ease of posting:  
 ![output](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/d/d7517a40fcbea64973d22dd76b101f919a6c4133.png)

---

<div class="post-metadata">

**Author:** ![jb4x](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/jb4x/32/789_2.png) [@jb4x](https://discourse.processing.org/u/jb4x)\
**Post date:** [May 2, 2019, 5:12pm UTC](https://discourse.processing.org/t/16bit-grayscale-images/10795/6 "2019-05-02T17:12:43Z")

</div>

Thanks for sharing your results!

---

<div class="post-metadata">

**Author:** ![clankill3r](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/clankill3r/32/1098_2.png) [@clankill3r](https://discourse.processing.org/u/clankill3r)\
**Post date:** [May 5, 2019, 9:27am UTC](https://discourse.processing.org/t/16bit-grayscale-images/10795/7 "2019-05-05T09:27:44Z")

</div>

One small note, variable names should be with lowercase.  
I’m not to keen on java conventions, but this one is important.  
So `int HeightmapWidth = 100;` should be `int heightmapWidth = 100;`.  
This makes it more readable for other programmers, specially if you have classes.  
Cause if you have the instance of a class with a uppercase you can have thins like this:

Wrong:

```auto
class Foo {
  int x = 10;
}

Foo Foo = new Foo();

println(Foo.x);

```

Now the `println(Foo.x);` makes it look like we are printing a static variable from the class Foo while we actually print a variable local to the instance.
