# Pixel Processing: Grabbing the Canvas, and Where's the Alpha?

**URL:** <https://discourse.processing.org/t/pixel-processing-grabbing-the-canvas-and-wheres-the-alpha/7162>\
**Category:** Coding Questions\
**Created:** [January 4, 2019, 12:58pm UTC](https://discourse.processing.org/t/pixel-processing-grabbing-the-canvas-and-wheres-the-alpha/7162 "2019-01-04T12:58:41Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![Aleksi](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/aleksi/32/11065_2.png) [@Aleksi](https://discourse.processing.org/u/Aleksi)\
**Post date:** [January 4, 2019, 12:58pm UTC](https://discourse.processing.org/t/pixel-processing-grabbing-the-canvas-and-wheres-the-alpha/7162/1 "2019-01-04T12:58:42Z")

</div>

Hello again.

I’d like to be able to grab a small area from the canvas and process the pixels in such a way that I can alter the color of intersecting lines. Here’s an example of what I’m trying to accomplish.

```auto
void setup(){
  size(200, 200); // P3D fixes PImage alpha?
  background(255, 255);
  
  noFill();
  
  stroke(0, 100);
  strokeWeight(1);
  strokeCap(SQUARE);
  rect(59, 59, 82, 82);

  strokeWeight(20);
  line(100, 60, 100, 140);
  line(60, 100, 140, 100);
  
  // is there a way to grab only a rectangle from the canvas instead of the whole thing?
  loadPixels();
  
  PImage img = createImage(80, 80, RGB);
  int cnt = 0;
  for (int x=60; x<140; x++){
    for (int y=60; y<140; y++){
      int loc = x + y*width;
      img.pixels[cnt] = pixels[loc];
      
      float r = red(img.pixels[cnt]);
      float a = alpha(img.pixels[cnt]);
      if (cnt % 250 == 0){ println(cnt," ",r," ",a); }
      if (r == 155){ 
        img.pixels[cnt] = color(0);
        // however, using the P3D renderer, img.pixels[cnt] = color(0, 20) doesn't seem to have alpha... WTF?
      } else if (r < 155) {
        img.pixels[cnt] = color(255);
      } else {
        // where's the alpha? 
        // (fixed using P3D renderer, which seems to initialize a PImage object with color(0,0))
        img.pixels[cnt] = color(255, 0);
        // however, using the P3D renderer, img.pixels[cnt] = color(0, 0, 255, 0); doesn't seem to have alpha... WTF?
      }
      cnt++;
    }
  }
  
  image(img, 0, 0);
}

```

I have a few questions, since I find this approach a bit awkward, and it doesn’t entirely work. I figure there’s got to be a better way to do this.

1. Is there a way to grab only a part of the canvas rather than execute `loadPixels()` which grabs it all?
2. `PImage` provides a way to `get()` pixel colors, or to grab a rect of pixels. But `loadPixels()` only seems to be able to access its color data via the `pixels` array. Is there a way to use `get()` from `loadPixels()`?
3. Printing the red and alpha values shows that `loadPixels()` doesn't retrieve alpha. The doc for [`PImage.copy()`](https://processing.org/reference/PImage_copy_.html) says: "No alpha information is used in the process, however if the source image has an alpha channel set, it will be copied as well.", which implies that the canvas doesn't contain alpha. So how do I obtain alpha information from the canvas? 
4. ~~The `PImage` object I create replaces white with full transparency, yet it doesn't work. Why not? Because the source image doesn't have alpha? But since I'm defining the pixels in the object, shouldn't it be able to create its own alpha?~~ Actually, I answered my own question by trying the **`P3D`** renderer, which seems to initialize a PImage object with color(0,0). And yet, when I apply alpha to a pixel, it seems to ignore it. What's going on?

Thank you for any help.

---

<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:** [January 4, 2019, 1:08pm UTC](https://discourse.processing.org/t/pixel-processing-grabbing-the-canvas-and-wheres-the-alpha/7162/2 "2019-01-04T13:08:33Z")

</div>

AFAIK, the main canvas is 100% opaque. 🙄  
And any alpha values in its _pixels[]_ are simply ignored. 😳

---

<div class="post-metadata">

**Author:** ![Aleksi](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/aleksi/32/11065_2.png) [@Aleksi](https://discourse.processing.org/u/Aleksi)\
**Post date:** [January 4, 2019, 1:12pm UTC](https://discourse.processing.org/t/pixel-processing-grabbing-the-canvas-and-wheres-the-alpha/7162/3 "2019-01-04T13:12:55Z")

</div>

So it seems, then, that I’ll need to create a `PGraphics` object and draw into it; then grab its data once its placed on the canvas as a `PImage` object?

---

<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:** [January 4, 2019, 1:17pm UTC](https://discourse.processing.org/t/pixel-processing-grabbing-the-canvas-and-wheres-the-alpha/7162/4 "2019-01-04T13:17:11Z")

</div>

Both PImage & its subclass PGraphics objects have their alpha values respected when rendered by **image()**. 😉

---

<div class="post-metadata">

**Author:** ![Aleksi](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/aleksi/32/11065_2.png) [@Aleksi](https://discourse.processing.org/u/Aleksi)\
**Post date:** [January 4, 2019, 1:27pm UTC](https://discourse.processing.org/t/pixel-processing-grabbing-the-canvas-and-wheres-the-alpha/7162/5 "2019-01-04T13:27:27Z")

</div>

Then, citing my example above, why does alpha not work when I set it in my `PImage` object? (Eg: `img.pixels[cnt] = color(0, 0, 255, 0);` )

---

<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:** [January 4, 2019, 1:32pm UTC](https://discourse.processing.org/t/pixel-processing-grabbing-the-canvas-and-wheres-the-alpha/7162/6 "2019-01-04T13:32:11Z")

</div>

I guess a 100% transparent color renders a 100% invisible pixel AFAIK. 🤔

> [@Aleksi](#):
>
> `color(0, 0, 255, 0)`

---

<div class="post-metadata">

**Author:** ![Aleksi](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/aleksi/32/11065_2.png) [@Aleksi](https://discourse.processing.org/u/Aleksi)\
**Post date:** [January 4, 2019, 1:32pm UTC](https://discourse.processing.org/t/pixel-processing-grabbing-the-canvas-and-wheres-the-alpha/7162/7 "2019-01-04T13:32:41Z")

</div>

And yet it appears bright blue…

---

<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:** [January 4, 2019, 1:46pm UTC](https://discourse.processing.org/t/pixel-processing-grabbing-the-canvas-and-wheres-the-alpha/7162/8 "2019-01-04T13:46:25Z")

</div>

> [@Aleksi](#):
>
> And yet it appears bright blue…

I believe it’s b/c you’re using RGB instead of ARGB:

> [@Aleksi](#):
>
> `PImage img = createImage(80, 80, RGB);`

```java
noLoop();

background(0);
imageMode(CENTER);

final int w = round(width * .75), h = round(height * .75);
println(w, h);

final PImage img = createImage(w, h, ARGB); // 100% invisible
//final PImage img = createImage(w, h, RGB); // 100% visible blue

// Fill PImage w/ a 100% transparent blue color:
java.util.Arrays.fill(img.pixels, color(0, 0, 255, 0));
img.updatePixels();

image(img, width >> 1, height >> 1);

```

---

<div class="post-metadata">

**Author:** ![Aleksi](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/aleksi/32/11065_2.png) [@Aleksi](https://discourse.processing.org/u/Aleksi)\
**Post date:** [January 4, 2019, 1:48pm UTC](https://discourse.processing.org/t/pixel-processing-grabbing-the-canvas-and-wheres-the-alpha/7162/9 "2019-01-04T13:48:43Z")

</div>

(…sigh…) It seems you’re right. I must tend to the docs more carefully…

Thank you.

---

<div class="post-metadata">

**Author:** ![Aleksi](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/aleksi/32/11065_2.png) [@Aleksi](https://discourse.processing.org/u/Aleksi)\
**Post date:** [January 4, 2019, 6:26pm UTC](https://discourse.processing.org/t/pixel-processing-grabbing-the-canvas-and-wheres-the-alpha/7162/10 "2019-01-04T18:26:35Z")

</div>

Ok, so I’m using PGraphics to create my image now so that I’ll have alpha. According to the [docs](https://processing.org/reference/createGraphics_.html) “Unlike the main drawing surface which is completely opaque, surfaces created with createGraphics() can have transparency. This makes it possible to draw into a graphics and maintain the alpha channel. By using save() to write a PNG or TGA file, the transparency of the graphics object will be honored.” Great, just what I want.

But… if I set the my `PGraphics` object to use the `P3D` renderer I get a NullPointerException in my pixel loop. If I don’t set the P3D renderer I don’t get alpha from my `PGraphics` object.

Is there some other obvious thing I’m overlooking here?

```auto
void setup(){
  size(200, 200, P3D);
  background(255);
  
  noFill();
  
  stroke(0, 100);
  strokeWeight(1);
  strokeCap(SQUARE);
  rect(59, 59, 82, 82);

  //// if I set the renderer to P3D...
  //PGraphics pg = createGraphics(80, 80);
  PGraphics pg = createGraphics(80, 80, P3D); // P3D restored
  pg.beginDraw();
  pg.background(255);
  pg.stroke(0, 100);
  pg.strokeWeight(20);
  pg.strokeCap(SQUARE);
  pg.line(40, 0, 40, 80); 
  pg.line(0, 40, 80, 40);
  pg.endDraw();
  
  imageMode(CENTER);  
  image(pg, 100, 100);
  
  pg.loadPixels(); // thx TfGuy44 post 11 below!
  for (int x=0; x<pg.width; x++){
    for (int y=0; y<pg.height; y++){
      int loc = x + y*pg.width;

      // ... I used to get a NullPointerException here, but not anymore with pg.loadPixels()
      float r = red(pg.pixels[loc]);

      // ... but the P3D renderer (still) gives me no alpha
      float a = alpha(pg.pixels[loc]);

      if (loc % 250 == 0){ println(loc," ",r," ",a); }
    }
  }
}

```

---

<div class="post-metadata">

**Author:** ![TfGuy44](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/tfguy44/32/41_2.png) [@TfGuy44](https://discourse.processing.org/u/TfGuy44)\
**Post date:** [January 4, 2019, 6:45pm UTC](https://discourse.processing.org/t/pixel-processing-grabbing-the-canvas-and-wheres-the-alpha/7162/11 "2019-01-04T18:45:42Z")

</div>

Hit the Docs again. Look for `loadPixels()`. 😀

That is, switch back to using P3D, and before you start your for loops for x and y, call `pg.loadPixels();`.

---

<div class="post-metadata">

**Author:** ![Aleksi](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/aleksi/32/11065_2.png) [@Aleksi](https://discourse.processing.org/u/Aleksi)\
**Post date:** [January 4, 2019, 6:52pm UTC](https://discourse.processing.org/t/pixel-processing-grabbing-the-canvas-and-wheres-the-alpha/7162/12 "2019-01-04T18:52:52Z")

</div>

D’oh! Yes, forgot that step.

But I’m still not getting any alpha from the pixels array, even after switching the renderer back to P3D.

😭

Note: I edited the code at comment 10 to reflect the changes.

---

<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:** [January 5, 2019, 11:39am UTC](https://discourse.processing.org/t/pixel-processing-grabbing-the-canvas-and-wheres-the-alpha/7162/13 "2019-01-05T11:39:09Z")

</div>

JAVA2D is Processing’s most stable renderer.  
Unless you really need 3D capabilities, you’re better off sticking w/ JAVA2D.

> [@Aleksi](#):
>
> pg.background(255);

The gray scale value `255` is 100% opaque.  
If you need to clear the PGraphics w/ 100% transparency, use **clear()** instead:

> **[clear() / Reference](https://processing.org/reference/clear_.html)**
>
> Clears the pixels within a buffer. This function only works on PGraphics objects created with the createGraphics() function. Unlike the main graphics context (the display window), pixels…

---

<div class="post-metadata">

**Author:** ![Aleksi](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/aleksi/32/11065_2.png) [@Aleksi](https://discourse.processing.org/u/Aleksi)\
**Post date:** [January 5, 2019, 12:00pm UTC](https://discourse.processing.org/t/pixel-processing-grabbing-the-canvas-and-wheres-the-alpha/7162/14 "2019-01-05T12:00:54Z")

</div>

> [@](#):
>
> pg.background(255);

**D’OH!** 😱

Yes, that was it… of course…

I’ll just slink away now…

---

<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:** [January 5, 2019, 12:03pm UTC](https://discourse.processing.org/t/pixel-processing-grabbing-the-canvas-and-wheres-the-alpha/7162/15 "2019-01-05T12:03:19Z")

</div>

Alternatively, we can use `pg.background(0, 0);` in place of **clear()**.  
For 100% invisible white, use `pg.background(255, 0);`

[Processing.org/reference/background\_.html](http://Processing.org/reference/background_.html)
