# Get just one channel of RGB photos?

**URL:** <https://discourse.processing.org/t/get-just-one-channel-of-rgb-photos/10732>\
**Category:** Coding Questions\
**Created:** [April 29, 2019, 3:25am UTC](https://discourse.processing.org/t/get-just-one-channel-of-rgb-photos/10732 "2019-04-29T03:25:32Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![darinb](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/darinb/32/3792_2.png) [@darinb](https://discourse.processing.org/u/darinb)\
**Post date:** [April 29, 2019, 3:25am UTC](https://discourse.processing.org/t/get-just-one-channel-of-rgb-photos/10732/1 "2019-04-29T03:25:32Z")

</div>

Hello,

I’m stuck…

If I have an RGB image how to I display just the red channel (or just the blue, or green)?

If I wanted to show a combination of two channels is there a faster way (faster as in computer speed) to show that combination?

Thanks,

–Darin

---

<div class="post-metadata">

**Author:** ![kll](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/kll/32/964_2.png) [@kll](https://discourse.processing.org/u/kll)\
**Post date:** [April 29, 2019, 3:47am UTC](https://discourse.processing.org/t/get-just-one-channel-of-rgb-photos/10732/2 "2019-04-29T03:47:35Z")

</div>

you mean like this?

 ![SNAG-0095](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/e/eef070b20e12bfa6c4420c5129bea86755ff1b90.jpeg)

hm, try

```auto
   img.pixels[i] = color(green(c),0,red(c));

```

---

<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:** [April 29, 2019, 6:20am UTC](https://discourse.processing.org/t/get-just-one-channel-of-rgb-photos/10732/3 "2019-04-29T06:20:24Z")

</div>

Hi,

If speed is really one of your concern, you can also use bit shifting to get the RGB values:

For red: `float r2 = c >> 16 & 0xFF;`  
For green: `float r2 = c >> 8 & 0xFF;`  
For blue: `float b2 = c & 0xFF;`

Of course you can find that on the reference page:  
[https://processing.org/reference/](https://processing.org/reference/)

---

<div class="post-metadata">

**Author:** ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)\
**Post date:** [April 29, 2019, 6:53am UTC](https://discourse.processing.org/t/get-just-one-channel-of-rgb-photos/10732/4 "2019-04-29T06:53:29Z")

</div>

> [@jb4x](#):
>
> For green: `float r2 = c >> 8 & 0xFF;`

I guess you meant: `int g = c >> 8 & 0xff;` 🤔

---

<div class="post-metadata">

**Author:** ![darinb](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/darinb/32/3792_2.png) [@darinb](https://discourse.processing.org/u/darinb)\
**Post date:** [April 29, 2019, 8:01am UTC](https://discourse.processing.org/t/get-just-one-channel-of-rgb-photos/10732/5 "2019-04-29T08:01:13Z")

</div>

Thanks jb4x and thank GoToLoop for the correction.

O.K., fast is good.

Can you expand on exactly what is happening here? I’m a photographer not a programmer so much. 🙂

I understand that I have a color (in c) that is twenty-four bits long. I understand that each of the three primaries is represented by eight of those bits, thus twenty-four total.

I also get the basic idea that I can use 0xFF (which I know is hexadecimal, which I understand is base 16, but I don’t use it enough to really be comfortable using it other than cutting and pasting). And so I also see (but don’t really full understand) that we are using 0xFF in some way to look at just the last eight bits of c, and so with blue we just look at them, with the other colors we shift the bits rightward the so the last eight bits are then green, then red, looking at each in turn.

So I can use what you are saying no problem at all but I don’t really feel I’m 100% understanding it. Can anyone step me through it?

Thanks,

–Darin

---

<div class="post-metadata">

**Author:** ![darinb](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/darinb/32/3792_2.png) [@darinb](https://discourse.processing.org/u/darinb)\
**Post date:** [April 29, 2019, 8:11am UTC](https://discourse.processing.org/t/get-just-one-channel-of-rgb-photos/10732/6 "2019-04-29T08:11:29Z")

</div>

Oh! I’ve never used the pixels method before–now I get it, seems super useful. Thanks.

–Darin

---

<div class="post-metadata">

**Author:** ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)\
**Post date:** [April 29, 2019, 8:25am UTC](https://discourse.processing.org/t/get-just-one-channel-of-rgb-photos/10732/7 "2019-04-29T08:25:16Z")

</div>

> [@darinb](#):
>
> … that we are using `0xFF` in some way to look at just the last eight bits of _c_,

> **[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.…

> **[\>\> (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…

> **[Mask (computing) | Masking bits to 0](https://en.wikipedia.org/wiki/Mask_(computing)#Masking_bits_to_0)**
>
> More often in practice, bits are "masked off" (or masked to 0) than "masked on" (or masked to 1). When a bit is ANDed with a 0, the result is always 0, i.e. Y AND 0 = 0. To leave the other bits as they were originally, they can be ANDed with 1 as Y AND 1 = Y 
> Example: Masking off the higher nibble (bits 4, 5, 6, 7) while leaving the lower nibble (bits 0, 1, 2, 3) unchanged.

---

<div class="post-metadata">

**Author:** ![kll](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/kll/32/964_2.png) [@kll](https://discourse.processing.org/u/kll)\
**Post date:** [April 29, 2019, 8:57am UTC](https://discourse.processing.org/t/get-just-one-channel-of-rgb-photos/10732/8 "2019-04-29T08:57:15Z")

</div>

> [@jb4x](#):
>
> If speed is really one of your concern, you can also use bit shifting to get the RGB values:

hi, sorry, but i have a hard time to test that speed up,  
any measurements with millis produce “16” or “32”  
so i changed and do that job inside draw()  
and show FPS  
and try frameRate(120)  
and still reach 105 fps in both ways,  
( with a very old win7 PC )

* * *

or do i need a bigger picture ?

test a too big picture for my computer: 2500x1250.jpg // 8 fps / 8 fps

possibly the byte coding speed improvement is just an often-copied myth

* * *

pls confirm that you have tested that.

my code using

> **[pixels\[\] / Reference](https://processing.org/reference/pixels.html)**
>
> The pixels\[\] array contains the values for all the pixels in the display window. These values are of the color datatype. This array is defined by the size of the display window. For example, if…

```auto
// https://discourse.processing.org/t/get-just-one-channel-of-rgb-photos/10732
// show red channel only
// compare red(c) with r2 = c >> 16 & 0xFF
// speed test measuring millis only show 16 or 32 nothing else, so switch to FPS show

String infile = "data/sunflower.jpg";
PImage img;
int r2, g2, b2;

void setup() {
  size(510, 340);
  img = loadImage(infile);
  println("picture "+infile+" w * h "+img.width+" * "+img.height);
  frameRate(120);
}

void show() {
  img.loadPixels();
  for (int i=0; i< img.pixels.length; i++) {
    img.pixels[i] = color(red(img.pixels[i]), 0, 0); // 105
// img.pixels[i] = color(img.pixels[i] >> 16 & 0xFF, 0, 0); // 105

/*
    // img.pixels[i] = color(0,green(c),0);
    // img.pixels[i] = color(0,0,blue(c));
    // img.pixels[i] = color(green(c),0,red(c)); // re-mix
 
    // r2 = c >> 16 & 0xFF;
    // g2 = c >> 8 & 0xFF;
    // b2 = c & 0xFF;
*/

  }
  img.updatePixels();
  image(img, 0, 0);
}

// move to draw and measure FPS
void draw() {
  surface.setTitle("my colors, FPS "+(int)frameRate+" for "+img.pixels.length+" pix");
  show();
}

```

* * *

but i did verify that this is slower ( 95 fps ) ( but snappy )

> **[set() / Reference](https://processing.org/reference/set_.html)**
>
> Changes the color of any pixel or writes an image directly into the display window. The x and y parameters specify the pixel to change and the color parameter specifies…

```auto
  for (int i=0; i< img.width; i++) for (int j=0; j< img.height; j++) img.set(color(red(img.get(i,j)),0,0),i,j); //95

```

---

<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:** [April 29, 2019, 1:41pm UTC](https://discourse.processing.org/t/get-just-one-channel-of-rgb-photos/10732/9 "2019-04-29T13:41:46Z")

</div>

> [@kll](#):
>
> pls confirm that you have tested that.

Hi @kll, this is from the [reference](https://processing.org/reference/red_.html):

> The **red()** function is easy to use and understand, but it is slower than a technique called bit shifting.

* * *

> [@GoToLoop](#):
>
> I guess you meant: `int g = c >> 8 & 0xff;` 🤔

Yep, although I did not bother to write it down I just copy-pasted the text from the [green() reference](https://processing.org/reference/green_.html).

I opened a new ticket for that.

---

<div class="post-metadata">

**Author:** ![kll](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/kll/32/964_2.png) [@kll](https://discourse.processing.org/u/kll)\
**Post date:** [April 29, 2019, 1:51pm UTC](https://discourse.processing.org/t/get-just-one-channel-of-rgb-photos/10732/10 "2019-04-29T13:51:51Z")

</div>

thanks for the link,  
sorry, but i can not reproduce that,  
you see a mistake in my code?  
but yes, i have low end hardware, but usually, that is perfect for speed tests.

actually, i am also not sure if the declaration & usage of variables costs time?  
so my idea is

```auto
img.pixels[i] = color(img.pixels[i] >> 16 & 0xFF, 0, 0);

```

should be fastest??

but nice to read:

```auto
color c = img.pixels[i];
float r1 = red(c);
int r2 = c >> 16 & 0xFF;
img.pixels[i] = color(r2, 0, 0);

```

can you suggest me a way to verify that speed difference?

---

<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:** [April 29, 2019, 2:59pm UTC](https://discourse.processing.org/t/get-just-one-channel-of-rgb-photos/10732/11 "2019-04-29T14:59:43Z")

</div>

Funny enough with the following test code I’m getting the bitshift technic 3% slower:

```auto
final int pixSize = 1000 * 1000;

void setup() {
  size(1000, 1000);
  background(20);

  int start, end;
  float r = 0;
  color c = 0;

  for (int k = 0; k < 100; k++) {
    loadPixels();
    start = millis();
    for (int i = 0; i < 10000; i++) {
      for (int j = 0; j < pixSize; j++) {
        c = pixels[j];
        // r = c >> 16 & 0xFF;
        r = red(c);
      }
    }
    end = millis();
    println(end - start);
  }

  rect(r, r, r, r);
}

```

And putting my variables global is making it 8 times slower oO:

```auto
final int pixSize = 1000 * 1000;
int start, end;
float r = 0;
color c = 0;

void setup() {
  size(1000, 1000);
  background(20);

  for (int k = 0; k < 100; k++) {
    loadPixels();
    start = millis();
    for (int i = 0; i < 10000; i++) {
      for (int j = 0; j < pixSize; j++) {
        c = pixels[j];
        // r = c >> 16 & 0xFF;
        r = red(c);
      }
    }
    end = millis();
    println(end - start);
  }

  rect(r, r, r, r);
}

```

For detail resulta I’m getting (in average):  
312ms for red() functions and local variables  
321ms for bitshifting and local variables  
2626ms for red() function and global variables

I did not know that global variables could impact tht much the performance…

---

<div class="post-metadata">

**Author:** ![kll](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/kll/32/964_2.png) [@kll](https://discourse.processing.org/u/kll)\
**Post date:** [April 29, 2019, 10:37pm UTC](https://discourse.processing.org/t/get-just-one-channel-of-rgb-photos/10732/12 "2019-04-29T22:37:30Z")

</div>

and to confuse you more:

- the color is a integer?  
so the result of a bitshift should goto integer, not real
- the result of red is float ( need to, as you might use like colorMode(RGB,1.0); )

i changed the test little bit and make many of them,  
and see the problem is actually with

```auto
c=pixels[j]

```

esp. if c is global color.  
find my data in the respective line  
and note my win7 PC is about double as slow as your hardware.  
not to mention the RPI

```auto

final int pixSize = 1000 * 1000;
final int manyruns = 10000, repeat = 10;
// global vars

  long start, end, dtime, avg = 0;
  int r1 = 0;
  float r2 = 0;
  color c = 0;

void setup() {
  size(1000, 1000);
  background(20);
/*
  // local vars
  long start, end, dtime, avg = 0;
  int r1 = 0;
  float r2 = 0;
  color c = 0;
*/
  for (int k = 0; k < repeat; k++) {
    loadPixels();
    start = millis();
    for (int i = 0; i < manyruns; i++) {
      for (int j = 0; j < pixSize; j++) { // only loop avg 4 ||global vars avg 5
        //c = pixels[j]; // only c avg 3 ||global vars avg 6848
        //r1 = c >> 16 & 0xFF; // int shift avg 629 || NO c=pixels[j] 3 ||global vars avg 7176 ||globalvars NO c=pixels[j] 656
        //r2 = c >> 16 & 0xFF; // float shift avg 632 || NO c=pixels[j] 3 ||global vars acg 7775 ||globalvars NO c=pixels[j] 640
        //r2 = red(c); // red avg 626 || NO c=pixels[j] 6 ||global vars avg 8039 ||globalvars NO c=pixels[j] 643
      }
    }
    end = millis();
    dtime = end - start;
    avg += dtime;
    println("k "+k+" dtime "+dtime);
  }
  //rect(r, r, r, r);
  println("avg "+avg/repeat);
  exit();
}

```

* * *

update  
now check again with all that features inside of draw ( and show FPS )

```auto
// https://discourse.processing.org/t/get-just-one-channel-of-rgb-photos/10732
// show red channel only
// compare red(c) with int r2 = c >> 16 & 0xFF
// check @jb4x https://discourse.processing.org/t/get-just-one-channel-of-rgb-photos/10732/11

// add test data from run on Raspberry Pi ( RPI )

String infile = "data/sunflower.jpg"; // format 1000 * 1000 with paint
PImage img;
//color c;

void setup() {
  size(1000, 1000);
  img = loadImage(infile);
  println("picture: "+infile+" w * h "+img.width+" * "+img.height);
  frameRate(120);
}

void make_red_pixels() {
  img.loadPixels(); // FPS: 67
  for (int i=0; i< img.pixels.length; i++) { // FPS: 67
    img.pixels[i] = color(red(img.pixels[i]), 0, 0); // FPS: 21 // RPI FPS 4
// img.pixels[i] = color(img.pixels[i] >> 16 & 0xFF, 0, 0); // FPS: 21
// c = img.pixels[i]; // FPS: 63 // recheck on the global variable problem? NOT here
// img.pixels[i] = color(red(c), 0, 0); // FPS: 21
// img.pixels[i] = color(c >> 16 & 0xFF, 0, 0); // FPS: 21 
    ;
  }  
  img.updatePixels();
}

void make_red_setget() {
    for (int i=0; i< img.width; i++) for (int j=0; j< img.height; j++) img.set(i,j,color(red(img.get(i,j)),0,0)); // FPS: 15 //RPI FPS 2
}

void draw() { // move to draw and measure FPS
  surface.setTitle("my colors, FPS "+(int)frameRate+" for "+img.pixels.length+" pix");
  make_red_pixels();
// make_red_setget();
  image(img, 0, 0); // FPS: 80
}

/*
       img.pixels[i] = color(0,green(c),0);
       img.pixels[i] = color(0,0,blue(c));
       img.pixels[i] = color(green(c),0,red(c)); // re-mix

  int r2, g2, b2;
 
       r2 = c >> 16 & 0xFF;
       g2 = c >> 8 & 0xFF;
       b2 = c & 0xFF;
*/

```

test with a 1000 \* 1000 picture ( old win 7 PC and RPI )

- a- the global variable color c problem i not see there again
- b- the bit shift speedup v.s. red() is a myth ( or in the whole context can be neglected )
- c- the pixels[] v.s. set ( get ) is faster like 21/80 to 15/80
