RenderScript使用教程(三)

Java层与 RenderScript 层参数传递

在开发中时常需要将Java层数据传递到RenderScript层来实现参数的传递,例如:高斯模糊中需要我们传递模板(算子)到RenderScript层来实现模糊的功能。下面演示何传递。
RenderScript层首先定义一个变量,如下

rs_allocation inAllocation;
uint32_t nTempMX, nTempMY;
uint32_t nTempW, nTempH;
float fCoef;
float template[256];

在Java层我们就可以通过IDE自动编译生成的代码来传递参数,如下

processScript.set_inAllocation(inAllocation);
System.arraycopy(ntemplate, 0, template, 0, ntemplate.length);
processScript.set_template(template);
processScript.set_nTempH(nTempH);
processScript.set_nTempW(nTempW);
processScript.set_nTempMY(nTempMY);
processScript.set_nTempMX(nTempMX);
processScript.set_fCoef(fCoef);

备注:这里需要注意的是在传递数组类型的时候需要制定Java层和RenderScript层数组的大小,如果他们数组大小不一致会导致异常。如果RenderScript层不显式制定大小,例如float template[],那么它默认的大小为一。

完整示例

下面我用一个高斯模糊的例子来演示参数的传递
Java层代码

// Gauss平滑  1/16
private static final float TEMPLATE_SMOOTH_GAUSS[] =
                    {1, 2, 1,
                     2, 4, 2,
                     1, 2, 1};
private static float template[] = new float[256];

public static Bitmap imTemplate(Context context, Bitmap inBitmap,
                                    float ntemplate[], int nTempH,
                                    int nTempW, int nTempMY,
                                    int nTempMX) {

        float weight = 0f;
        for (float t : ntemplate) {
            weight += t;
        }
        float fCoef = 1.0f / weight;

        // Creates a RS context.
        RenderScript mRS = RenderScript.create(context);

        // Creates the input Allocation and copies all Bitmap contents into it.
        Allocation inAllocation = Allocation.createFromBitmap(mRS, inBitmap);

        // Defines the output Type, which will be a RGBA pixel.
        // The Allocation will be composed by four unsigned chars (0-255) for each pixel,
        // so that R-G-B-A values can be stored.
        // It is necessary to use a Type-based approach whenever there is a multi-dimensional sizing (X,Y).
        int bitmapWidth = inBitmap.getWidth();
        int bitmapHeight = inBitmap.getHeight();

        Type.Builder outType = new Type.Builder(mRS, Element.RGBA_8888(mRS)).setX(bitmapWidth).setY(bitmapHeight);

        // Creates the output Allocation wherein to store the conversion result.
        Allocation outAllocation = Allocation.createTyped(mRS, outType.create(), Allocation.USAGE_SCRIPT);

        // Creates the conversion script wrapper.
        ScriptC_ImgProcess processScript = new ScriptC_ImgProcess(mRS);

        // Binds the inAllocation variable with the actual Allocation.
        processScript.set_inAllocation(inAllocation);
        System.arraycopy(ntemplate, 0, template, 0, ntemplate.length);
        processScript.set_template(template);
        processScript.set_nTempH(nTempH);
        processScript.set_nTempW(nTempW);
        processScript.set_nTempMY(nTempMY);
        processScript.set_nTempMX(nTempMX);
        processScript.set_fCoef(fCoef);

        // Performs the conversion. RS kernel will use outAllocation size for its iterations.
        processScript.forEach_imTemplate(outAllocation);

        // Creates output Bitmap, matching input one size.
        Bitmap outBitmap = Bitmap.createBitmap(bitmapWidth, bitmapHeight, inBitmap.getConfig());

        // Copy calculation result to the output Bitmap.
        outAllocation.copyTo(outBitmap);

        mRS.destroy();
        return outBitmap;

    }

    /**
     * 高斯模糊
     * @param context
     * @param inBitmap
     * @return
     */
    public static Bitmap gaussSmooth(Context context, Bitmap inBitmap) {
        return imTemplate(context, inBitmap, TEMPLATE_SMOOTH_GAUSS, 3, 3, 1, 1);
    }

RenderScript代码

// Needed directive for RS to work
#pragma version(1)
// Change java_package_name directive to match your Activity's package path
#pragma rs java_package_name(demo.rs.dong.cn.java_rs_demo)

rs_allocation inAllocation;
uint32_t nTempMX, nTempMY;
uint32_t nTempW, nTempH;
float fCoef;
float template[256];


uchar4 __attribute__((kernel)) imTemplate(uint32_t x, uint32_t y) {
            const uint32_t imageWidth = rsAllocationGetDimX(inAllocation);
            const uint32_t imageHeight = rsAllocationGetDimY(inAllocation);

             uchar4 in = rsGetElementAt_uchar4(inAllocation, x, y);
             uchar4 out = in;
             //process border
             if(x < nTempMX || y < nTempMY || x >= (imageWidth - nTempMX) || y >= (imageHeight - nTempMY)) {
                    return out;
              }

             float r = 0 ,g = 0, b = 0;
             uint32_t index;
             for (uint32_t k = 0; k < nTempH; k++) {
                   for (uint32_t l = 0; l < nTempW; l++) {
                       uchar4 value = rsGetElementAt_uchar4(inAllocation, (x + l - nTempMX), (y + k - nTempMY));
                       //计算加权和
                       index = k * nTempW + l;
                       r = r + (float) (value.r * template[index]);
                       g = g + (float) (value.g * template[index]);
                       b = b + (float) (value.b * template[index]);
                   }
             }

              // 乘以系数
              out.r = (uchar) r * fCoef;
              out.g = (uchar) g * fCoef;
              out.b = (uchar) b * fCoef;

             if (out.r > 255) {out.r = 255;};
             if (out.g > 255) {out.g = 255;};
             if (out.b > 255) {out.b = 255;};
             out.a = in.a;
             return out;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值