5

Recently, I found render script is a better choice for image processing on Android. The performance is wonderful. But there are not many documents on it. I am wondering if I can merge multiple photos into a result photo by render script.

http://developer.android.com/guide/topics/renderscript/compute.html says:

A kernel may have an input Allocation, an output Allocation, or both. A kernel may not have more than one input or one output Allocation. If more than one input or output is required, those objects should be bound to rs_allocation script globals and accessed from a kernel or invokable function via rsGetElementAt_type() or rsSetElementAt_type().

Is there any code example for this issue?

Sagar Zala
  • 4,854
  • 9
  • 34
  • 62
James Zhao
  • 418
  • 5
  • 13

3 Answers3

5

For the kernel with multiple inputs you would have to manually handle additional inputs.

Let's say you want 2 inputs.

example.rs:

rs_allocation extra_alloc;

uchar4 __attribute__((kernel)) kernel(uchar4 i1, uint32_t x, uint32_t y)
{
    // Manually getting current element from the extra input
    uchar4 i2 = rsGetElementAt_uchar4(extra_alloc, x, y);
    // Now process i1 and i2 and generate out
    uchar4 out = ...;
    return out;
}

Java:

Bitmap bitmapIn = ...;
Bitmap bitmapInExtra = ...;
Bitmap bitmapOut = Bitmap.createBitmap(bitmapIn.getWidth(),
                    bitmapIn.getHeight(), bitmapIn.getConfig());

RenderScript rs = RenderScript.create(this);
ScriptC_example script = new ScriptC_example(rs);

Allocation inAllocation = Allocation.createFromBitmap(rs, bitmapIn);
Allocation inAllocationExtra = Allocation.createFromBitmap(rs, bitmapInExtra);
Allocation outAllocation = Allocation.createFromBitmap(rs, bitmapOut);

// Execute this kernel on two inputs
script.set_extra_alloc(inAllocationExtra);
script.forEach_kernel(inAllocation, outAllocation);

// Get the data back into bitmap
outAllocation.copyTo(bitmapOut);
Stanislav Vitvitskyy
  • 2,297
  • 20
  • 17
3

you want to do something like

rs_allocation input1;
rs_allocation input2;

uchar4 __attribute__((kernel)) kernel() {
  ... // body of kernel goes here
  uchar4 out = ...;
  return out;
}

Call set_input1 and set_input2 from your Java code to set those to the appropriate Allocations, then call forEach_kernel with your output Allocation.

Tim Murray
  • 2,205
  • 13
  • 13
  • Thanks, I will make a try. – James Zhao Dec 28 '13 at 00:54
  • Actually, I cannot find a method called set_input1 and set_input2 in the class ScriptC from Java layer. Instead, there is a method named ScriptC.bindAllocation(Allocation va, int slot). Also, ScriptC.forEach_kernel is not exist. – James Zhao Dec 30 '13 at 08:54
  • the class is autogenerated by the RS toolchain--it will be ScriptC_(RS filename). – Tim Murray Dec 30 '13 at 21:25
  • There is a class ScriptC_aaa, but no such method called set_input1. – James Zhao Dec 31 '13 at 13:38
  • the method will be named set_(name of variable in your RS file), so it won't necessarily be input1 or anything like that. – Tim Murray Jan 02 '14 at 19:18
  • 1
    For illustrative purpose the kernel function should have input arguments such as `kernel(uint32_t x, uint32_t y) {...}`. – rwong Jun 21 '14 at 10:09
0

This is how you do it :

in the .rs file :

uchar4 RS_KERNEL myKernel(float4 in1, int in2, uint32_t x, uint32_t y)
{
    //My code
}

in java :

myScript.forEach_myKernel(allocationInput1, allocationInput2, allocationOutput);

uchar4, float4, and int are used as example. It works for me, you can add more than 2 inputs.

Leo
  • 91
  • 3