# Convert PImage to byte array

**URL:** <https://discourse.processing.org/t/convert-pimage-to-byte-array/20268>\
**Category:** Coding Questions\
**Created:** [April 29, 2020, 2:18pm UTC](https://discourse.processing.org/t/convert-pimage-to-byte-array/20268 "2020-04-29T14:18:01Z")\
**Posts on this page:** 18\
**Page:** 1

<div class="post-metadata">

**Author:** ![Marce](https://avatars.discourse-cdn.com/v4/letter/m/d9b06d/32.png) [@Marce](https://discourse.processing.org/u/Marce)\
**Post date:** [April 29, 2020, 2:18pm UTC](https://discourse.processing.org/t/convert-pimage-to-byte-array/20268/1 "2020-04-29T14:18:01Z")

</div>

Hi !

I’m looking for a way to convert a Pimage to a byte array. I feel like this should be a pretty common things to do, and I tried plenty of things found online but, not a single one seems to work.  
If anyone knows how to easily convert a Pimage to a byte array that would really help me. For the context, I need to convert it before sending thanks to the mqtt library.

Thanks you

---

<div class="post-metadata">

**Author:** ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)\
**Post date:** [April 29, 2020, 2:31pm UTC](https://discourse.processing.org/t/convert-pimage-to-byte-array/20268/2 "2020-04-29T14:31:57Z")

</div>

it is a gray scale image?

RGB has int as datay type, not byte?

Chrisir

---

<div class="post-metadata">

**Author:** ![Marce](https://avatars.discourse-cdn.com/v4/letter/m/d9b06d/32.png) [@Marce](https://discourse.processing.org/u/Marce)\
**Post date:** [April 29, 2020, 2:38pm UTC](https://discourse.processing.org/t/convert-pimage-to-byte-array/20268/3 "2020-04-29T14:38:01Z")

</div>

it’s a RGb image, i know it’s an int data type but i wanna convert it to a byte array

---

<div class="post-metadata">

**Author:** ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)\
**Post date:** [April 29, 2020, 2:44pm UTC](https://discourse.processing.org/t/convert-pimage-to-byte-array/20268/4 "2020-04-29T14:44:27Z")

</div>

obviously you will have a big loss of data, e.g. only gray or only brightness

but when you look at loadPixels() and pixels[] you can just program the function yourself

[https://www.processing.org/reference/pixels.html](https://www.processing.org/reference/pixels.html)

Chrisir

```auto

color c1 = color (#AD2A2A); 

fill(c1); 

background(c1); 

println (c1); 

byte b1 = byte (c1); 

println (b1);

```

---

<div class="post-metadata">

**Author:** ![Marce](https://avatars.discourse-cdn.com/v4/letter/m/d9b06d/32.png) [@Marce](https://discourse.processing.org/u/Marce)\
**Post date:** [April 29, 2020, 2:49pm UTC](https://discourse.processing.org/t/convert-pimage-to-byte-array/20268/5 "2020-04-29T14:49:44Z")

</div>

Ok so the only way is to convert it pixel by pixel trough a loop using byte() and adding it to a byte array ?

---

<div class="post-metadata">

**Author:** ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)\
**Post date:** [April 29, 2020, 2:55pm UTC](https://discourse.processing.org/t/convert-pimage-to-byte-array/20268/6 "2020-04-29T14:55:20Z")

</div>

I don’t know whether there are other ways

---

<div class="post-metadata">

**Author:** ![glv](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/glv/32/18785_2.png) [@glv](https://discourse.processing.org/u/glv)\
**Post date:** [April 29, 2020, 4:15pm UTC](https://discourse.processing.org/t/convert-pimage-to-byte-array/20268/7 "2020-04-29T16:15:35Z")

</div>

Hello,

> [@Marce](#):
>
> Ok so the only way is to convert it pixel by pixel trough a loop using byte() and adding it to a byte array

If you convert a 32 bit int (4 bytes) using byte() you lose all but the first byte which only represents B (blue).

> **[byte() / Reference](https://processing.org/reference/byteconvert_.html)**
>
> Converts any value of a primitive data type (boolean, byte, char, color, double, float, int, or long) to its byte representation. A byte can onl…

Read on…

color is stored as a 32 bit int (4 bytes):

> **[color / Reference](https://processing.org/reference/color_datatype.html)**
>
> Datatype for storing color values. Colors may be assigned with get() and color() or they may be specified directly using hexadecimal notation such as #FFCC00 or 0xFFFFCC00.…

You will have to extract 4 bytes and store these into a byte array; 1 pixel will have 4 elements in a 1 dimensional array. You will have to decide on the correct order for A, R, G, B for your context.

I did bit manipulation:

> **[\>\> (right shift) / Reference](https://processing.org/reference/rightshift.html)**
>
> Shifts bits to the right. The number to the left of the operator is shifted the number of places specified by the number to the right. Each shift to the right halves the number, therefore each right s…

> **[& (bitwise AND) / Reference](https://processing.org/reference/bitwiseAND.html)**
>
> Compares each corresponding bit in the binary representation of the values. For each comparison two 1's yield 1, 1 and 0 yield 0, and two 0's yield 0. This is easy to see when we look at the binary re…

An example (left some for you to think about) using bit manipulation to extract the R and G:

```auto
  byteArray[0] = ? >> 0); //B
  byteArray[1] = byte((pixels[i] & 0x0000FF00) >> 8); //G
  byteArray[2] = ? >> 16); //R
  byteArray[3] = byte((pixels[i] & 0xFF000000) >> 24); //A

```

You can also use these functions to extract color.  
[red() / Reference / Processing.org](https://processing.org/reference/red_.html) There are others!

The examples do comment on bit manipulation being faster!  
And they did it by shifting first and then masking.

It is simple enough to write a function to do this; I started with above and iterated it down to a nice clean function to do this.

I do not know what the library is expecting but you can easily adapt code for this.

`:)`

Other references:

> **[PImage / Reference](https://processing.org/reference/PImage.html)**
>
> Datatype for storing images. Processing can display .gif, .jpg, .tga, and .png images. Images may be displayed in 2D and 3D space. Before an image is used, it must be loade…

---

<div class="post-metadata">

**Author:** ![Marce](https://avatars.discourse-cdn.com/v4/letter/m/d9b06d/32.png) [@Marce](https://discourse.processing.org/u/Marce)\
**Post date:** [April 29, 2020, 4:36pm UTC](https://discourse.processing.org/t/convert-pimage-to-byte-array/20268/8 "2020-04-29T16:36:57Z")

</div>

Thanks ,I’ll try that

---

<div class="post-metadata">

**Author:** ![Marce](https://avatars.discourse-cdn.com/v4/letter/m/d9b06d/32.png) [@Marce](https://discourse.processing.org/u/Marce)\
**Post date:** [April 29, 2020, 5:02pm UTC](https://discourse.processing.org/t/convert-pimage-to-byte-array/20268/9 "2020-04-29T17:02:02Z")

</div>

Ok so I found an easier way to do that.  
I just save the image as a local file and then I open it this way :

`byte b[] = loadBytes("image.jpg");`

And I have my byte array, ready to send.

---

<div class="post-metadata">

**Author:** ![neilcsmith](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/neilcsmith/32/144_2.png) [@neilcsmith](https://discourse.processing.org/u/neilcsmith)\
**Post date:** [April 29, 2020, 5:07pm UTC](https://discourse.processing.org/t/convert-pimage-to-byte-array/20268/10 "2020-04-29T17:07:32Z")

</div>

If the bytes in the image are in the right order for you, you should be able to use something like (coding off top of my head! 😄) -

```auto
byte[] data = new byte[width * height * 4];
int[] pixels = ...
ByteBuffer.wrap(data).asIntBuffer().put(pixels);

```

> [@Marce](#):
>
> byte b = loadBytes(“image.jpg”);

Do you want encoded or raw data?

Also, it should be `byte[] b =` if you don’t want to confuse everyone.

---

<div class="post-metadata">

**Author:** ![quark](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/quark/32/26_2.png) [@quark](https://discourse.processing.org/u/quark)\
**Post date:** [April 29, 2020, 5:46pm UTC](https://discourse.processing.org/t/convert-pimage-to-byte-array/20268/11 "2020-04-29T17:46:22Z")

</div>

Saving the image to a local file is a nice idea and will work provided you don’t want to recreate the image. This is not possible because although you can load the original pixel data you don’t know the width and height of the original image.

In the code below the image width and height are stored alongside the pixel data in the byte array allowing the image to be recreated like this  
 ![warn2x](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/0/0f0484fab149aa82fdbb69cebb0b505c00a20a0d.png)

The sketch contains two handy functions to do the conversions `byte[] > PImage` and `PImage > byte[]`

```auto
import java.nio.ByteBuffer;

void setup() {
  size(400, 300);
  background(255);
  fill(0);
  textSize(16);
  PImage imgOrg = loadImage("warn.png");
  text("Original", 20, 16);
  image(imgOrg, 20, 40);
  // Not create byte array
  byte[] array = convertImageToByteArray(imgOrg);
  // Now recreate a copy of the original from the byte array
  PImage imgNew = convertByteArrayToImage(array);
  text("Byte array > image", 220, 16);
  image(imgNew, 220, 40);
  save("warn2x.png");
}

byte[] convertImageToByteArray(PImage img) {
  img.loadPixels();
  int[] px = img.pixels;
  ByteBuffer bb = ByteBuffer.allocate((2 + px.length) * 4);
  bb.putInt(img.width);
  bb.putInt(img.height);
  for (int d : px) {
    bb.putInt(d);
  }
  return bb.array();
}

PImage convertByteArrayToImage(byte[] bytes) {
  ByteBuffer bb = ByteBuffer.wrap(bytes);
  int w = bb.getInt();
  int h = bb.getInt();
  PImage img = new PImage(w, h);
  int[] px = img.pixels;
  for (int i = 0; i < px.length; i++) {
    px[i] = bb.getInt();
  }
  img.updatePixels();
  return img;
}

```

here is the image if you want to try it out  
 ![warn1](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/1X/3c6dc86d97b234334fd1e2434cd0399d859fe7ba.png)

---

<div class="post-metadata">

**Author:** ![glv](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/glv/32/18785_2.png) [@glv](https://discourse.processing.org/u/glv)\
**Post date:** [May 4, 2020, 12:09am UTC](https://discourse.processing.org/t/convert-pimage-to-byte-array/20268/12 "2020-05-04T00:09:26Z")

</div>

Hello,

> [@Marce](#):
>
> I just save the image as a local file and then I open it this way :
> 
> `byte b[] = loadBytes("image.jpg");`
> 
> And I have my byte array, ready to send.

Keep in mind that a jpg is a lossy compression algorithm and the receiving end will not reproduce the original. It all depends on what your requirements are.  
This is one article on the subject (there are many):

> **[JPG vs. PNG: Which is Better?](https://www.techsmith.com/blog/jpg-vs-png/)**
>
> Confused about which image type to use for your website or marketing project? Find out more details and see what the pros and cons of both file types are in this blog post.

`:)`

---

<div class="post-metadata">

**Author:** ![SomeOne](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/someone/32/8639_2.png) [@SomeOne](https://discourse.processing.org/u/SomeOne)\
**Post date:** [May 6, 2020, 7:01am UTC](https://discourse.processing.org/t/convert-pimage-to-byte-array/20268/13 "2020-05-06T07:01:54Z")

</div>

JPG-format does not contain pixels in arrays, so you will get garbage. If you really want to go with image-file way you should use ppm [https://en.wikipedia.org/wiki/Netpbm#File\_formats](https://en.wikipedia.org/wiki/Netpbm#File_formats). It has a few leading bits: P3, width, height and colour depth, before pixel array starts.

I have used it to create an image-file and converted that file to png for later usage.

Otherwise it is loadPixels() and going through all pixels to create byte array. It’s actually pretty fast and quite easy once you get hang of it.

---

<div class="post-metadata">

**Author:** ![gerrikoio](https://avatars.discourse-cdn.com/v4/letter/g/b2d939/32.png) [@gerrikoio](https://discourse.processing.org/u/gerrikoio)\
**Post date:** [September 2, 2021, 4:41pm UTC](https://discourse.processing.org/t/convert-pimage-to-byte-array/20268/14 "2021-09-02T16:41:58Z")

</div>

I’ve been struggling with this challenge of converting a PImage to a byte array. I cannot get it to work. I tried all of the above etc.

My intention is to send my byte array, which is a conversion of an image I created in my Processing application, to an external MCU connected to the serial port of my computer so that this image can be displayed on a e-Paper or e-Ink device.

The e-Paper display only shows black and white images, so I am not grappling with RGB or transparency.

To test my image, I have saved the image as a JPEG and then I used this utility [https://lvgl.io/tools/imageconverter](https://lvgl.io/tools/imageconverter) to convert the JPEG as a byte array using the option “Indexed 2 colors”.

This utility works well and the generated byte array is used by the MCU to display the image.

This webpage uses a PHP script and this code is opensourced on GitHub: [lv\_utils/img\_conv\_core.php at master · lvgl/lv\_utils · GitHub](https://github.com/lvgl/lv_utils/blob/master/img_conv_core.php)

The PHP code looks more complicated than it really is, as it covers all options from raw, true color and multiple alpha and indexed options. I am simply using the indexed 2 color option, which is referenced as “const CF\_INDEXED\_1\_BIT = 8;” in the PHP script. The script also includes dithering conversion options which are not needed either.

I now want to avoid saving my Processing create image as a JPEG and simply save the pixels as a byte array.

However, I cannot get my bytes to match up with the bytes generated by the webpage.

For starters, I have an image which is 128 pixels wide and 296 pixels high. The byte array generated by the PHP script is 16 x 296. So 8 pixels is converted into one byte.

Hence, I am stuck as using get(x,y) or referencing pixels[i] does not work.

So I had hoped that **pixelDensity** work here… as according to documentation " When the pixel density is set to more than 1, it changes all of the pixel operations including the way **get()** , **set()** , **blend()** , **copy()** , and **updatePixels()** all work."

But this is display or monitor dependent and I got an error message. Also you cannot use anything higher than 2.

Maybe there is a simple way to use the PHP script… it uses a class structure, which is a good start, but actually there is only one function and one private function that matters, so it is relatively straightforward for the experts out there.

I got stuck on the bit manipulation section as could not figure out the java/wiring equivalent:

```auto
    $w = $this->w >> 3;
            if($this->w & 0x07) $w++;

            $p = $w * $y + ($x >> 3) + 8; /* +8 for the palette*/
            if(!isset($this->d_out[$p])) $this->d_out[$p] = 0; /*Clear the bits first*/
            $this->d_out[$p] |= ($c & 0x1) << (7 - ($x & 0x7));

```

Any suggestions are all greatly appreciated thanks.

---

<div class="post-metadata">

**Author:** ![gerrikoio](https://avatars.discourse-cdn.com/v4/letter/g/b2d939/32.png) [@gerrikoio](https://discourse.processing.org/u/gerrikoio)\
**Post date:** [September 4, 2021, 8:26pm UTC](https://discourse.processing.org/t/convert-pimage-to-byte-array/20268/15 "2021-09-04T20:26:54Z")

</div>

I have converted what I thought was relevant and it is almost? working. It is certainly an improvement to what I tried manually by trying to convert 8 pixels into 1 byte etc.

![IMG_20210904_210929](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/4/4d122f1cfbb8097390cc5a7a86c5162eff7aba9f.jpeg)

The code I created was as follows:

```auto
void setup() {
  // Not using size as there is nothing to display (for now) and printing output to console
  PImage img = loadImage("image.jpg");
  int d_out[] = new int[4736]; // this is 16 x 296 (I'm ignoring the first 8 bytes as per PHP code)
  
  /*Convert all the pixels*/
  int $w = img.width >> 3;
  for(int $y = 0; $y < img.height; $y++) {
      for(int $x = 0; $x < img.width; ++$x){
          int $p = $w * $y + ($x >> 3); /* +8 for the palette*/
          d_out[$p] |= (img.get($x,$y) & 0x1) << (7 - ($x & 0x7));
      }
  }
  
  int $i = 0;
  for(int $y = 0; $y < img.height; $y++) {
      String $c_array = "";
      for(int $x = 0; $x < img.width; $x++) {
          if(($x & 0x7) == 0) {
              $c_array += "0x" + hex(d_out[$i], 2) + ", ";
              $i++;
          }
      }
      println($c_array);
  }
  
}

void draw() {}

```

So I am not sure where I’ve gone wrong.

One aspect I was not sure of was how the indexing process worked within the PHP script and whether this was necessary to do within my Processing code.

Here is the PHP code extract:

```auto
$img_tmp = imagecreatetruecolor($this->w, $this->h);

        imagecopy ($img_tmp, $this->img, 0 , 0 , 0 , 0, $this->w , $this->h);

        imagetruecolortopalette($this->img, false, $palette_size);

        $real_palette_size = imagecolorstotal($this->img); /*The real number of colors in the image's palette*/

        for($i = 0; $i < $palette_size; $i++) {

            if($i < $real_palette_size) {

                $c = imagecolorsforindex ($this->img , $i);

                array_push($this->d_out, $c['blue'], $c['green'], $c['red'], 0xFF);

            } else {

                array_push($this->d_out, 0xFF, 0xFF, 0xFF, 0xFF);

            }

        }

```

This “pushed” 8 extra bytes into the array, which I do not need for my purposes so I left this out.

Any suggestions greatly appreciated.

Thanks

---

<div class="post-metadata">

**Author:** ![glv](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/glv/32/18785_2.png) [@glv](https://discourse.processing.org/u/glv)\
**Post date:** [September 4, 2021, 10:35pm UTC](https://discourse.processing.org/t/convert-pimage-to-byte-array/20268/16 "2021-09-04T22:35:26Z")

</div>

Hello,

I just threw this together to work my brain:

> **Code**
>
> ```auto
> // Packing and Unpacking 8 bits
> // v1.0.0
> // GLV 2021-09-04
> 
> // https://discourse.processing.org/t/convert-pimage-to-byte-array/20268
> 
> PImage img;
> PGraphics pg;
> 
> byte bin [] = new byte [32/8*32]; //32/8*32 = 128 byte packed array
> 
> void setup() 
> {
> size(100, 100);
> 
> noSmooth(); //Otherwise it "smoothed" the output
>   
> pg = createGraphics(32, 32); //32*32 = 1024 byte unpacked array
>   
> pg.beginDraw();
> 
> pg.background(255);
> pg.noFill();
> pg.stroke(0);
> int rx = 8;
> pg.rect(rx, rx, pg.width-2*rx, pg.height-2*rx);
> pg.circle(pg.width/2, pg.height/2, 28);
> pg.line(0, 1, pg.width/2, 1);
> pg.line(0, 3, pg.width/3, 3);
> pg.endDraw();
>   
> pg.save("test.png");
> // pg.loadPixels();
>   
> image(pg, 0, 0);
>   
> println("Test:");
> test();
> println();
>   
> println("Pack:");
> pack01();
> println();
>   
> println("Unpack:");
> unpack00();
> println();  
>   
> println(bin.length);
> println(pg.pixels.length);
> println(pg.width/8f);
> }
> 
> //void draw() 
> // {
> // background(0);
> // }
> 
> void test()
> {
> int [] pixels = {0, 3, 0, 3, 0, 3, 3, 3,
> 0, 3, 0, 3, 0, 3, 0, 3};
> int b = 0;
> for (int i = 0; i<pixels.length; i++)
> {
> b |= (pixels[i] & 1) << (7-i%8);
> if ((i+1)%8 == 0)
> {
> println(binary(b, 8));
> b=0;
> }
> }
> }  
> 
> void pack01()
> {
> int bc = 0;
> for(int y = 0; y<pg.height; y++)
> {
> int b = 0;  
> for(int x = 0; x<pg.width; x++)
> {
> int pl = x+y*pg.width; //for array only!
>       
> int bit = pg.pixels[pl] & 1;
> //print(bit);
> char tbit = (bit == 0 ? 'O' : '-');
> print(tbit); 
>       
> b |= (pg.pixels[pl] & 1) << (7-x%8);
> if ((x+1)%8 == 0)
> {
> //print(binary(b, 8)); 
> print(' ');
>         
> bin[bc] = byte(b);
> bc++; 
>         
> b = 0;
> }
> } 
> println();   
> }
> }   
> 
> void unpack00()
> {
> for(int y = 0; y<pg.height; y++)
> {
> for(int x = 0; x<pg.width/8; x++)
> {
> int pl = x+y*pg.width/8;
>       
> for (int i = 7; i>=0; i--)
> //for (int i = 0; i<8; i++)
> {
> int px = (bin[pl] >>> i) & 1;
> //print(px); //ok
> char tbit = (px == 0 ? 'O' : '-');
> print(tbit); 
>         
> if (px == 0)
> stroke(0);
> else
> stroke(255);
>         
> point( (7-i) + x*8 + width/2, y);
> } 
> print(" ");  
> }
> println();  
> }     
> }
> 
> ```

I am “packing” 8 bytes (0 or 1 for color) into 8 pixels (one byte) and then “unpacking” to display.

I used a very small image so I could also print to console for debugging… it helped.

There may be something of interest in there for you.

`:)`

---

<div class="post-metadata">

**Author:** ![gerrikoio](https://avatars.discourse-cdn.com/v4/letter/g/b2d939/32.png) [@gerrikoio](https://discourse.processing.org/u/gerrikoio)\
**Post date:** [September 5, 2021, 10:15am UTC](https://discourse.processing.org/t/convert-pimage-to-byte-array/20268/17 "2021-09-05T10:15:49Z")

</div>

> [@glv](#):
>
> am “packing” 8 bytes from 8 pixels into one

Thanks so much. Your packing code worked a charm.

Instead of `print(binary(b, 8)); ` I used `print("0x" + hex(b,2)); ` instead.

and used print(", ") as my spacer.

---

<div class="post-metadata">

**Author:** ![glv](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/glv/32/18785_2.png) [@glv](https://discourse.processing.org/u/glv)\
**Post date:** [September 5, 2021, 10:23am UTC](https://discourse.processing.org/t/convert-pimage-to-byte-array/20268/18 "2021-09-05T10:23:19Z")

</div>

> [@gerrikoio](#):
>
> Your packing code worked a charm.

It was a good workout! I learned a lot along the way…

I still have to convert the unpacked back to a picture.

Another day…

All the best with your project.

`:)`
