Sample之Renderscript

RenderScript对图像处理,计算摄影学,计算机视觉方面的应用非常有用。

Google sample:https://developer.android.com/samples/BasicRenderScript/index.html

google API :https://developer.android.com/guide/topics/renderscript/compute.html

先找个软柿子,有个base的项目,查看文档有个很简单的小代码,先试试那个,在原有项目里新建一个sample1.rs文件,rebuild一下

就自动生成了.java文件


自动生成的代码:

/*
 * Copyright (C) 2011-2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * This file is auto-generated. DO NOT MODIFY!
 * The source Renderscript file: D:\\slack\\android\\RenderScript\\BasicRenderScript\\Application\\src\\main\\rs\\sample1.rs
 */

package com.example.android.basicrenderscript;

import android.support.v8.renderscript.*;
import android.content.res.Resources;

/**
 * @hide
 */
public class ScriptC_sample1 extends ScriptC {
    private static final String __rs_resource_name = "sample1";
    // Constructor
    public  ScriptC_sample1(RenderScript rs) {
        this(rs,
             rs.getApplicationContext().getResources(),
             rs.getApplicationContext().getResources().getIdentifier(
                 __rs_resource_name, "raw",
                 rs.getApplicationContext().getPackageName()));
    }

    public  ScriptC_sample1(RenderScript rs, Resources resources, int id) {
        super(rs, resources, id);
        __U8_4 = Element.U8_4(rs);
    }

    private Element __U8_4;
    //private final static int mExportForEachIdx_root = 0;
    private final static int mExportForEachIdx_invert = 1;
    public Script.KernelID getKernelID_invert() {
        return createKernelID(mExportForEachIdx_invert, 59, null, null);
    }

    public void forEach_invert(Allocation ain, Allocation aout) {
        forEach_invert(ain, aout, null);
    }

    public void forEach_invert(Allocation ain, Allocation aout, Script.LaunchOptions sc) {
        // check ain
        if (!ain.getType().getElement().isCompatible(__U8_4)) {
            throw new RSRuntimeException("Type mismatch with U8_4!");
        }
        // check aout
        if (!aout.getType().getElement().isCompatible(__U8_4)) {
            throw new RSRuntimeException("Type mismatch with U8_4!");
        }
        Type t0, t1;        // Verify dimensions
        t0 = ain.getType();
        t1 = aout.getType();
        if ((t0.getCount() != t1.getCount()) ||
            (t0.getX() != t1.getX()) ||
            (t0.getY() != t1.getY()) ||
            (t0.getZ() != t1.getZ()) ||
            (t0.hasFaces()   != t1.hasFaces()) ||
            (t0.hasMipmaps() != t1.hasMipmaps())) {
            throw new RSRuntimeException("Dimension mismatch between parameters ain and aout!");
        }

        forEach(mExportForEachIdx_invert, ain, aout, null, sc);
    }

}


在base项目的基础上新增测试代码,我新增的很简单,基本上都在createScriptRGB函数里

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.support.v8.renderscript.*;

public class MainActivity extends Activity {
    /* Number of bitmaps that is used for renderScript thread and UI thread synchronization.
       Ideally, this can be reduced to 2, however in some devices, 2 buffers still showing tierings on UI.
       Investigating a root cause.
     */
    private final int NUM_BITMAPS = 3;
    private int mCurrentBitmap = 0;
    private Bitmap mBitmapIn;
    private Bitmap[] mBitmapsOut;
    private ImageView mImageView;

    private RenderScript mRS;
    private Allocation mInAllocation;
    private Allocation[] mOutAllocations;
    private ScriptC_saturation mScript;

    // add test
    private ScriptC_sample1 test_rgb;
    private ImageView mImageRGB;
    private Allocation test_aOut;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.main_layout);

        /*
         * Initialize UI
         */
        mBitmapIn = loadBitmap(R.drawable.data);
        mBitmapsOut = new Bitmap[NUM_BITMAPS + 1];
        for (int i = 0; i < NUM_BITMAPS + 1; ++i) {
            mBitmapsOut[i] = Bitmap.createBitmap(mBitmapIn.getWidth(),
                    mBitmapIn.getHeight(), mBitmapIn.getConfig());
        }

        mImageRGB = (ImageView) findViewById(R.id.imageView2);
        mImageView = (ImageView) findViewById(R.id.imageView);
        mImageView.setImageBitmap(mBitmapsOut[mCurrentBitmap]);
        mCurrentBitmap += (mCurrentBitmap + 1) % NUM_BITMAPS;

        SeekBar seekbar = (SeekBar) findViewById(R.id.seekBar1);
        seekbar.setProgress(50);
        seekbar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
            public void onProgressChanged(SeekBar seekBar, int progress,
                                          boolean fromUser) {
                float max = 2.0f;
                float min = 0.0f;
                float f = (float) ((max - min) * (progress / 100.0) + min);
                updateImage(f);
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
            }
        });

        /*
         * Create renderScript
         */
        createScript();
        createScriptRGB();

        /*
         * Invoke renderScript kernel and update imageView
         */
        updateImage(1.0f);
    }

    /*
     * Initialize RenderScript
     * In the sample, it creates RenderScript kernel that performs saturation manipulation.
     */
    private void createScript() {
        //Initialize RS
        mRS = RenderScript.create(this);

        //Allocate buffers
        mInAllocation = Allocation.createFromBitmap(mRS, mBitmapIn);
        mOutAllocations = new Allocation[NUM_BITMAPS];
        for (int i = 0; i < NUM_BITMAPS; ++i) {
            mOutAllocations[i] = Allocation.createFromBitmap(mRS, mBitmapsOut[i]);
        }

        //Load script
        mScript = new ScriptC_saturation(mRS);
    }

    private void createScriptRGB() {

        //Load script
        test_rgb = new ScriptC_sample1(mRS);
        // Allocation 根据Bitmap分配内存
        test_aOut = Allocation.createFromBitmap(mRS, mBitmapIn);
        // forEach_invert 一个用于输入,一个用于输出计算结果
        test_rgb.forEach_invert(mInAllocation,test_aOut);
        // copy出 bitmap 结果
        test_aOut.copyTo(mBitmapsOut[NUM_BITMAPS]);
        mImageRGB.setImageBitmap(mBitmapsOut[NUM_BITMAPS]);
        mImageRGB.invalidate();

    }

    /*
     * In the AsyncTask, it invokes RenderScript intrinsics to do a filtering.
     * After the filtering is done, an operation blocks at Allication.copyTo() in AsyncTask thread.
     * Once all operation is finished at onPostExecute() in UI thread, it can invalidate and update ImageView UI.
     */
    private class RenderScriptTask extends AsyncTask<Float, Integer, Integer> {
        Boolean issued = false;

        protected Integer doInBackground(Float... values) {
            int index = -1;
            if (isCancelled() == false) {
                issued = true;
                index = mCurrentBitmap;

                /*
                 * Set global variable in RS
                 */
                mScript.set_saturationValue(values[0]);

                /*
                 * Invoke saturation filter kernel
                 */
                mScript.forEach_saturation(mInAllocation, mOutAllocations[index]);

                /*
                 * Copy to bitmap and invalidate image view
                 */
                mOutAllocations[index].copyTo(mBitmapsOut[index]);
                mCurrentBitmap = (mCurrentBitmap + 1) % NUM_BITMAPS;
            }
            return index;
        }

        void updateView(Integer result) {
            if (result != -1) {
                // Request UI update
                mImageView.setImageBitmap(mBitmapsOut[result]);
                mImageView.invalidate();
            }
        }

        protected void onPostExecute(Integer result) {
            updateView(result);
        }

        protected void onCancelled(Integer result) {
            if (issued) {
                updateView(result);
            }
        }
    }

    RenderScriptTask currentTask = null;

    /*
    Invoke AsynchTask and cancel previous task.
    When AsyncTasks are piled up (typically in slow device with heavy kernel),
    Only the latest (and already started) task invokes RenderScript operation.
     */
    private void updateImage(final float f) {
        if (currentTask != null)
            currentTask.cancel(false);
        currentTask = new RenderScriptTask();
        currentTask.execute(f);
    }

    /*
    Helper to load Bitmap from resource
     */
    private Bitmap loadBitmap(int resource) {
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inPreferredConfig = Bitmap.Config.ARGB_8888;
        return BitmapFactory.decodeResource(getResources(), resource, options);
    }

}

看看效果,确实是颜色取反



接着看看 RenderScriptIntrinsic 这个项目https://developer.android.com/samples/RenderScriptIntrinsic/project.html

这个直接给封装了一些


官方就给了三个使用案例,剩下的还需我们自己去使用,不过基本思路都差不多,毕竟都封装好了

private void performFilter(Allocation inAllocation,
                               Allocation outAllocation, Bitmap bitmapOut, float value) {
        switch (mFilterMode) {
            case MODE_BLUR:
                
            /*
             * Set blur kernel size
             */
                mScriptBlur.setRadius(value);

            /*
             * Invoke filter kernel
             */
                mScriptBlur.setInput(inAllocation);
                mScriptBlur.forEach(outAllocation);
                break;
            case MODE_CONVOLVE: {
                float f1 = value;
                float f2 = 1.0f - f1;

                // Emboss filter kernel
                float coefficients[] = {-f1 * 2, 0, -f1, 0, 0, 0, -f2 * 2, -f2, 0,
                        0, -f1, -f2, 1, f2, f1, 0, 0, f2, f2 * 2, 0, 0, 0, f1, 0,
                        f1 * 2,};
            /*
             * Set kernel parameter
             */
                mScriptConvolve.setCoefficients(coefficients);

            /*
             * Invoke filter kernel
             */
                mScriptConvolve.setInput(inAllocation);
                mScriptConvolve.forEach(outAllocation);
                break;
            }
            case MODE_COLORMATRIX: {
            /*
             * Set HUE rotation matrix
             * The matrix below performs a combined operation of,
             * RGB->HSV transform * HUE rotation * HSV->RGB transform
             */
                float cos = (float) Math.cos((double) value);
                float sin = (float) Math.sin((double) value);
                Matrix3f mat = new Matrix3f();
                mat.set(0, 0, (float) (.299 + .701 * cos + .168 * sin));
                mat.set(1, 0, (float) (.587 - .587 * cos + .330 * sin));
                mat.set(2, 0, (float) (.114 - .114 * cos - .497 * sin));
                mat.set(0, 1, (float) (.299 - .299 * cos - .328 * sin));
                mat.set(1, 1, (float) (.587 + .413 * cos + .035 * sin));
                mat.set(2, 1, (float) (.114 - .114 * cos + .292 * sin));
                mat.set(0, 2, (float) (.299 - .3 * cos + 1.25 * sin));
                mat.set(1, 2, (float) (.587 - .588 * cos - 1.05 * sin));
                mat.set(2, 2, (float) (.114 + .886 * cos - .203 * sin));
                mScriptMatrix.setColorMatrix(mat);

            /*
             * Invoke filter kernel
             */
                mScriptMatrix.forEach(inAllocation, outAllocation);
            }
            break;
        }

        /*
         * Copy to bitmap and invalidate image view
         */
        outAllocation.copyTo(bitmapOut);
    }






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值