Pointer Null
Pointer Null

Reputation: 40381

Renderscript - getting neighbor pixel

I'm starting to explore power of renderscript.

Trying with 2D image data, I can convert pixel to some other pixel. However, how is it possible to get neighbor pixels from input allocation?

I thing how is for example built-in convolve3x3 filter done, when it needs neighbor pixels to operate, and it nicely clamps pixels at edge of image.

Assuming I have function

void root(const uchar4 *v_in, uchar4 *v_out) {
   float4 f4 = rsUnpackColor8888(*v_in);
   // do something on pixel
   uchar4 u4 = rsPackColorTo8888(f4);
   *v_out = u4;
}

am I really supposed to index v_in like v_in[1] or v_in[k] to get other pixels, or is there some clever rs* function to get adjacent horizontal/vertical pixels, while providing proper clamp to image size, so that I don't index v_in array out of its size?

Upvotes: 1

Views: 1577

Answers (1)

Stephen Hines
Stephen Hines

Reputation: 2622

If you want to look at neighboring pixels (and you are using rs_allocations), you should just use a single global rs_allocation rather than passing it as *v_in. This would look like:

rs_allocation in;

// Using the new kernel syntax where v_out becomes the return value.
uchar4 __attribute__((kernel)) doSomething(uint32_t x, uint32_t y) {
  uchar4 u4 = rsGetElementAt_uchar4(in, x, y);  // You can adjust x,y here to get neighbor values too.
  float4 f4 = rsUnpackColor8888(u4);
  ...
  return rsPackColorTo8888(f4);
}

Unfortunately, there is no nice way to get automatic clamping with a regular rs_allocation, but you can adjust your code to do the edge clamp manually. Keep maxX, maxY as global variables passed to the Script, and then dynamically check whether or not you are in range before any rsGetElementAt*(). If you do want automatic clamping/wrapping behaviors, you can also check out the rs_sampler and rsSample() APIs.

Upvotes: 1

Related Questions