现在的位置: 首页 > 综合 > 正文

renderscript-v8.jar的简单使用

2017年11月14日 ⁄ 综合 ⁄ 共 11346字 ⁄ 字号 评论关闭

这个库主要是对图形的处理,模糊,渲染

需要的操作,加入v8库,支持这个jar包的目录在\sdk\build-tools\里面

,如下两张图,因为build-tools大家的目录可能不一样,老的是上边那个目录,新的是下边的。



之后记得在project.properties添加如下选中的那行代码,否则运行的时候会报错提示找不到库的


xml代码如下:

 <ImageView
        android:id="@+id/image_normal"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:layout_margin="5dp"
        android:scaleType="center"/>
    <ImageView
        android:id="@+id/image_blurred"
        android:layout_width="match_parent"
      android:layout_height="0dp"
        android:layout_weight="1"
        android:layout_margin="5dp"
        android:scaleType="center"/>
    <ImageView
        android:id="@+id/image_colored"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:layout_margin="5dp"
        android:scaleType="center"/>

activity中使用:

mNormalImage = (ImageView) findViewById(R.id.image_normal);
        mBlurImage = (ImageView) findViewById(R.id.image_blurred);
        mColorImage = (ImageView) findViewById(R.id.image_colored);
        //mColorImageHalf = (ImageView) findViewById(R.id.image_colored_half);
 
        //Start with an image from our APK resources
        Bitmap inBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.data);
        Bitmap outBitmap = inBitmap.copy(inBitmap.getConfig(), true);
        Bitmap grayBitmap = inBitmap.copy(inBitmap.getConfig(), true);
        //Bitmap  halfBitmap=Bitmap.createBitmap(inBitmap.getWidth(), inBitmap.getHeight(), inBitmap.getConfig());
        
        //Create the context and I/O allocations
        final RenderScript rs = RenderScript.create(this);
        final Allocation input = Allocation.createFromBitmap(rs, inBitmap,
                Allocation.MipmapControl.MIPMAP_NONE,
                Allocation.USAGE_SCRIPT);
        final Allocation output = Allocation.createTyped(rs, input.getType());
 
        //Blur the image
        final ScriptIntrinsicBlur script =
                ScriptIntrinsicBlur.create(rs, Element.U8_4(rs));
        script.setRadius(6f);
        script.setInput(input);
        script.forEach(output);
        output.copyTo(outBitmap);
 
        //Make the image greyscale
        final ScriptIntrinsicColorMatrix scriptColor =
                ScriptIntrinsicColorMatrix.create(rs, Element.U8_4(rs));
        scriptColor.setGreyscale();
        scriptColor.forEach(input, output);
        output.copyTo(grayBitmap);
        mNormalImage.setImageBitmap(inBitmap);
        mBlurImage.setImageBitmap(outBitmap);
        mColorImage.setImageBitmap(grayBitmap);
        //mColorImageHalf.setImageBitmap(halfBitmap);
        //We don't need RenderScript anymore
        rs.destroy();

效果图:

以上为简单的使用,其他的用法可以参考android提供的example,目录如下:

下面为demo中的代码,复制下来方便查找:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#0099cc"
    tools:context=".MainActivity_old">

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scaleType="fitCenter"
        android:src="@drawable/data" />
<RadioGroup
        android:id="@+id/radioGroup1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_gravity="center"
        android:orientation="horizontal"
        android:layout_above="@+id/seekBar1"
        android:layout_marginBottom="8dp">

        <RadioButton
            android:id="@+id/radio0"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:checked="true"
            android:text="Blur" />

        <RadioButton
            android:id="@+id/radio1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
             android:layout_weight="1"
            android:text="Emboss" />

        <RadioButton
            android:id="@+id/radio2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
             android:layout_weight="1"
            android:text="Hue" />
    </RadioGroup>
    <SeekBar
        android:id="@+id/seekBar1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom"
        android:layout_marginBottom="16dp" />


</FrameLayout>

/*
 * Copyright (C) 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.
 */



import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.ImageView;
import android.widget.RadioButton;
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 ScriptIntrinsicBlur mScriptBlur;
    private ScriptIntrinsicConvolve5x5 mScriptConvolve;
    private ScriptIntrinsicColorMatrix mScriptMatrix;

    private final int MODE_BLUR = 0;
    private final int MODE_CONVOLVE = 1;
    private final int MODE_COLORMATRIX = 2;

    private int mFilterMode = MODE_BLUR;

    private RenderScriptTask mLatestTask = null;

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

        setContentView(R.layout.main_layout);

        /*
         * Initialize UI
         */

        //Set up main image view
        mBitmapIn = loadBitmap(R.drawable.data);
        mBitmapsOut = new Bitmap[NUM_BITMAPS];
        for (int i = 0; i < NUM_BITMAPS; ++i) {
            mBitmapsOut[i] = Bitmap.createBitmap(mBitmapIn.getWidth(),
                    mBitmapIn.getHeight(), mBitmapIn.getConfig());
        }
        mImageView = (ImageView) findViewById(R.id.imageView);
        mImageView.setImageBitmap(mBitmapsOut[mCurrentBitmap]);
        mCurrentBitmap += (mCurrentBitmap + 1) % NUM_BITMAPS;

        //Set up seekbar
        final SeekBar seekbar = (SeekBar) findViewById(R.id.seekBar1);
        seekbar.setProgress(50);
        seekbar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
            public void onProgressChanged(SeekBar seekBar, int progress,
                                          boolean fromUser) {
                updateImage(progress);
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
            }

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

        //Setup effect selector
        RadioButton radio0 = (RadioButton) findViewById(R.id.radio0);
        radio0.setOnCheckedChangeListener(new OnCheckedChangeListener() {

            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                if (isChecked) {
                    mFilterMode = MODE_BLUR;
                    updateImage(seekbar.getProgress());
                }
            }
        });
        RadioButton radio1 = (RadioButton) findViewById(R.id.radio1);
        radio1.setOnCheckedChangeListener(new OnCheckedChangeListener() {

            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                if (isChecked) {
                    mFilterMode = MODE_CONVOLVE;
                    updateImage(seekbar.getProgress());
                }
            }
        });
        RadioButton radio2 = (RadioButton) findViewById(R.id.radio2);
        radio2.setOnCheckedChangeListener(new OnCheckedChangeListener() {

            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                if (isChecked) {
                    mFilterMode = MODE_COLORMATRIX;
                    updateImage(seekbar.getProgress());
                }
            }
        });

        /*
         * Create renderScript
         */
        createScript();

        /*
         * Create thumbnails
         */
       // createThumbnail();


        /*
         * Invoke renderScript kernel and update imageView
         */
        mFilterMode = MODE_BLUR;
        updateImage(50);
    }

    private void createScript() {
        mRS = RenderScript.create(this);

        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]);
        }

        /*
        Create intrinsics.
        RenderScript has built-in features such as blur, convolve filter etc.
        These intrinsics are handy for specific operations without writing RenderScript kernel.
        In the sample, it's creating blur, convolve and matrix intrinsics.
         */

        mScriptBlur = ScriptIntrinsicBlur.create(mRS, Element.U8_4(mRS));
        mScriptConvolve = ScriptIntrinsicConvolve5x5.create(mRS,
                Element.U8_4(mRS));
        mScriptMatrix = ScriptIntrinsicColorMatrix.create(mRS,
                Element.U8_4(mRS));
    }

    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);
    }

    /*
    Convert seekBar progress parameter (0-100 in range) to parameter for each intrinsic filter.
    (e.g. 1.0-25.0 in Blur filter)
     */
    private float getFilterParameter(int i) {
        float f = 0.f;
        switch (mFilterMode) {
            case MODE_BLUR: {
                final float max = 25.0f;
                final float min = 1.f;
                f = (float) ((max - min) * (i / 100.0) + min);
            }
            break;
            case MODE_CONVOLVE: {
                final float max = 2.f;
                final float min = 0.f;
                f = (float) ((max - min) * (i / 100.0) + min);
            }
            break;
            case MODE_COLORMATRIX: {
                final float max = (float) Math.PI;
                final float min = (float) -Math.PI;
                f = (float) ((max - min) * (i / 100.0) + min);
            }
            break;
        }
        return f;

    }

    /*
     * 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;

                performFilter(mInAllocation, mOutAllocations[index], mBitmapsOut[index], values[0]);
                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);
            }
        }
    }

    /*
    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(int progress) {
        float f = getFilterParameter(progress);

        if (mLatestTask != null)
            mLatestTask.cancel(false);
        mLatestTask = new RenderScriptTask();

        mLatestTask.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);
    }

 
}

效果图:

参考:http://possiblemobile.com/2013/10/renderscript-for-all/

抱歉!评论已关闭.