请参考:“Android preview YUV转换 RenderScript 优化”

https://blog.csdn.net/zhjali123/article/details/80086987

计算:RenderScript Runtime API参考:简介

https://blog.csdn.net/Explorer_day/article/details/71641333

基于以上文章,进行实际操作。

1. 创建了一个 5.0.1的 Android项目“hellorenderscript”

2. 创建界面

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:id="@+id/LinearLayout1"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"android:paddingBottom="@dimen/activity_vertical_margin"android:paddingLeft="@dimen/activity_horizontal_margin"android:paddingRight="@dimen/activity_horizontal_margin"android:paddingTop="@dimen/activity_vertical_margin"tools:context="com.example.hellorenderscript.MainActivity" ><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content" ><Buttonandroid:id="@+id/Camera1"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_weight="1"android:text="Camera" /><Buttonandroid:id="@+id/PauseButton"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_weight="1"android:text="Pause/Start" /></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_weight="1"android:orientation="vertical" ><ImageViewandroid:id="@+id/imageView1"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_weight="6.82"android:src="@drawable/ic_launcher" /></LinearLayout></LinearLayout>

3. 在project.properties 文件中加入:renderscript.target=18

4. 创建“hello.rs”

内容如下,如果eclipse报红色警告,并修改代码后,记得clean一下(eclipse菜单 Project ==> Clean)。

#pragma version(1)
#pragma rs java_package_name(com.hc.renderscript)rs_allocation inputAllocation;
uchar4 out;
int wIn, hIn;
int numTotalPixels;
static float scaleInv;
static int inputWidth, inputHeight, outputWidth, outputHeight;uchar4 __attribute__((kernel)) invert(uchar4 in)
{uchar4 out = in;out.r =255- in.r;out.g = 255-in.g;out.b = 255-in.b;return out;}const static float3 gMonoMult1 = {0.299f, 0.587f, 0.114f};void RGBA2Gray(const uchar4 *v_in, uchar4 *v_out) {float4 f4 = rsUnpackColor8888(*v_in);//将输入的颜色值转化为r g b afloat3 mono = dot(f4.rgb, gMonoMult1);//计算向量的点积*v_out = rsPackColorTo8888(mono);//return 20;  根据返回值(ms)作刷新。相当于每20毫秒刷新一次。
}// Function to invoke before applying conversion
void setInputImageSize(int _w, int _h)
{wIn = _w;hIn = _h;numTotalPixels = wIn * hIn;
}void setInformation(int _inputWidth, int _inputHeight,int _outputWidth, int _outputHeight){inputWidth = _inputWidth;inputHeight = _inputHeight;outputWidth = _outputWidth;outputHeight = _outputHeight;// Calculates inverse scale factor, by which// to round coordinates.//// Ex:// Input size is 100// Output desired size is 25//// Scale factor is 25 / 100 = 0.25// Inverse scale factor is 1 / 0.25 = 4//// When iterating directly on the output// allocation, to get input element it is needed// to use the inverse scale factor.//// Current output element index is 20// Respective input element index is 20 * 4 = 80//scaleInv = (float)inputWidth/(float)outputWidth;
}const static uchar Myclamp(short x, uchar Mymin, uchar Mymax){if (x > Mymax)return Mymax;if (x < Mymin)return Mymin;return (uchar)x;
}// Kernel that converts a YUV element to a RGBA one
uchar4 __attribute__((kernel)) convert(uint32_t x, uint32_t y)
{// YUV 4:2:0 planar image, with 8 bit Y samples, followed by// interleaved V/U plane with 8bit 2x2 subsampled chroma samples//两行Y,两列X共用一对V&U.int baseIdx = x + y * wIn;int baseVYIndex = numTotalPixels + (y>>1) * wIn + (x & 0xfffffe);int baseUYIndex=baseVYIndex+1;uchar _y = rsGetElementAt_uchar(inputAllocation, baseIdx);uchar _u = rsGetElementAt_uchar(inputAllocation, baseUYIndex);uchar _v = rsGetElementAt_uchar(inputAllocation, baseVYIndex);_y = _y < 16 ? 16 : _y;short Y = ((short)_y) - 16;short U = ((short)_u) - 128;short V = ((short)_v) - 128;uchar4 out;out.r =  (uchar)Myclamp(((Y * 298 + V * 408 + 128) >> 8), 0, 255);out.g =  (uchar)Myclamp(((Y * 298 - U * 100 - V * 208 + 128) >> 8), 0, 255);out.b =  (uchar)Myclamp(((Y * 298 + U * 516 + 128) >> 8), 0, 255);out.a = 255;//以下为黑白图像
//  out.r =Y;
//  out.g=Y;
//  out.b =Y;return out;
}uchar4 __attribute__ ((kernel)) rotate_90_clockwise ( uint32_t x, uint32_t y) {uint32_t inX  = wIn - 1 - y;uint32_t inY = x;uchar4 out;out = rsGetElementAt_uchar4(inputAllocation,inX, inY);return out;
}uchar4 __attribute__ ((kernel)) rotate_270_clockwise (uint32_t x, uint32_t y) {uint32_t inX = y;uint32_t inY = hIn - 1 - x;uchar4 out;out = rsGetElementAt_uchar4(inputAllocation,inX, inY);return out;
}const static float Limit(float x, float Mymin, float Mymax){if (x > Mymax)return Mymax;if (x < Mymin)return Mymin;return x;
}uchar4 __attribute__((kernel)) resizeNearest(uint32_t x, uint32_t y) {float fX = clamp(x*scaleInv, 0.0f, (float)inputWidth);float fY = clamp(y*scaleInv, 0.0f, (float)inputHeight);return rsGetElementAt_uchar4(inputAllocation, fX, fY);
}

5. 保存hello.rs,若报错的情况下,eclipse会自动生成一个带“Script_”的类“Script_hello”。

6. 创建一个类“RSImgProcess”

package com.example.hellorenderscript;import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.ImageFormat;
import android.renderscript.Allocation;
import android.renderscript.Element;
import android.renderscript.RenderScript;
import android.renderscript.ScriptIntrinsicBlur;
import android.renderscript.ScriptIntrinsicYuvToRGB;
import android.renderscript.Type;
import android.util.Log;import com.hc.renderscript.ScriptC_hello;public class RSImgProcess {private static RenderScript mRS;final float per = 1.0f;private int outwidth, outheight;private static ScriptIntrinsicYuvToRGB yuvToRgbIntrinsic;private static Type.Builder yuvType;private static Type.Builder rgbaType;private static Allocation in;private static Allocation out;private ScriptC_hello customYUVToRGBAScript;private ScriptC_hello resizeScript;private ScriptIntrinsicBlur blurScript;private boolean isInit = false;ThreadPoolExecutor GlobalThreadPool;public RSImgProcess(final Context context) {GlobalThreadPool = new ThreadPoolExecutor(4, 4, 2, TimeUnit.MILLISECONDS,new ArrayBlockingQueue<Runnable>(200));GlobalThreadPool.execute(new Runnable() {@Overridepublic void run() {init(context);isInit = true;Log.i("RSImgProcess","Init");}});}private void init(Context context) {// Creates a RS context.mRS = RenderScript.create(context);customYUVToRGBAScript = new ScriptC_hello(mRS);// Instantiates the blur scriptresizeScript = new ScriptC_hello(mRS);}private Allocation resize(Allocation inputAllocation, int width, int height) {// Creates an output Allocation where to store the blur resultType.Builder tbOutput = new Type.Builder(mRS, Element.RGBA_8888(mRS));tbOutput.setX(outwidth);tbOutput.setY(outheight);Allocation outputAllocation = Allocation.createTyped(mRS, tbOutput.create());resizeScript.set_inputAllocation(inputAllocation);resizeScript.invoke_setInformation(width, height, outwidth, outheight);resizeScript.forEach_resizeNearest(outputAllocation);return outputAllocation;}private Allocation Rotate90(Allocation inputAllocation, int width, int height) {// Creates an output Allocation where to store the blur resultType.Builder tbOutput = new Type.Builder(mRS, Element.RGBA_8888(mRS));tbOutput.setX(height);tbOutput.setY(width);Allocation outputAllocation = Allocation.createTyped(mRS, tbOutput.create());resizeScript.set_inputAllocation(inputAllocation);resizeScript.invoke_setInputImageSize(width, height);resizeScript.forEach_rotate_90_clockwise(outputAllocation);return outputAllocation;}   private Allocation Rotate270(Allocation inputAllocation, int width, int height) {// Creates an output Allocation where to store the blur resultType.Builder tbOutput = new Type.Builder(mRS, Element.RGBA_8888(mRS));tbOutput.setX(height);tbOutput.setY(width);Allocation outputAllocation = Allocation.createTyped(mRS, tbOutput.create());resizeScript.set_inputAllocation(inputAllocation);resizeScript.invoke_setInputImageSize(width, height);resizeScript.forEach_rotate_270_clockwise(outputAllocation);return outputAllocation;} private Allocation YUVToRGBA(byte[] dataIn, int width, int height) {// Calculates expected YUV bytes count as YUV is not a human friendly way of storing data:// https://en.wikipedia.org/wiki/YUV#Y.27UV420p_.28and_Y.27V12_or_YV12.29_to_RGB888_conversionint expectedBytes = (int) (width * height * ImageFormat.getBitsPerPixel(ImageFormat.NV21) / 8f);Type.Builder yuvTypeBuilder = new Type.Builder(mRS, Element.U8(mRS)).setX(expectedBytes);Type yuvType = yuvTypeBuilder.create();Allocation inputAllocation = Allocation.createTyped(mRS, yuvType, Allocation.USAGE_SCRIPT);inputAllocation.copyFrom(dataIn);customYUVToRGBAScript.invoke_setInputImageSize(width, height);customYUVToRGBAScript.set_inputAllocation(inputAllocation);// Creates temporary allocation that will match camera preview sizeType.Builder rgbaType = new Type.Builder(mRS, Element.RGBA_8888(mRS)).setX(width).setY(height);Allocation midAllocation = Allocation.createTyped(mRS, rgbaType.create(), Allocation.USAGE_SCRIPT);customYUVToRGBAScript.forEach_convert(midAllocation);return midAllocation;}private static Allocation YUVToBMPByRS(byte[] YUVData,int OriginWidth,int OriginHeight){Bitmap BMPOut;Log.i("YUVToBMPByRS","RenderScript create again");yuvToRgbIntrinsic = ScriptIntrinsicYuvToRGB.create(mRS, Element.RGBA_8888(mRS));rgbaType = new Type.Builder(mRS, Element.RGBA_8888(mRS)).setX(OriginWidth).setY(OriginHeight);out = Allocation.createTyped(mRS, rgbaType.create(), Allocation.USAGE_SCRIPT);yuvType = new Type.Builder(mRS, Element.U8(mRS)).setX(YUVData.length);in = Allocation.createTyped(mRS, yuvType.create(), Allocation.USAGE_SCRIPT);in.copyFrom(YUVData);yuvToRgbIntrinsic.setInput(in);yuvToRgbIntrinsic.forEach(out);//      BMPOut = Bitmap.createBitmap(OriginWidth, OriginHeight, Bitmap.Config.ARGB_8888);//    out.copyTo(BMPOut);
//      return BMPOut;return out;}public Bitmap processImg(byte[] dataIn, int width, int height,int outWidth,int outHeight,int screen_orientation) {Allocation  outputallocation;long startTime = System.currentTimeMillis();//Allocation allocation = YUVToBMPByRS(dataIn, width, height);Allocation allocation = YUVToRGBA(dataIn, width, height);// Allocation resizeAllocation = resize(allocation, width, height);if(screen_orientation==1  || screen_orientation==3){//   Log.i("processImg","screen_orientation"+screen_orientation);outputallocation=Rotate270(allocation, width, height);outwidth=height;outheight=width;}else{outwidth=width;outheight=height;outputallocation=allocation;}Bitmap outBitmap;// Creates output Bitmap, matching input one size.// Bitmap outBitmap = Bitmap.createBitmap(outWidth, outHeight, Bitmap.Config.ARGB_8888);// Copy calculation result to the output Bitmap.// resizeAllocation.copyTo(outBitmap);//    Log.i("processImg","outwidth"+outwidth);outBitmap = Bitmap.createBitmap(outwidth, outheight, Bitmap.Config.ARGB_8888);outputallocation.copyTo(outBitmap);return outBitmap;}}

7. Java 调用 这些类。

7.1 MainActivity中的变量

 Allocation aIn;Allocation aOut;static Bitmap mOutBitmap,bitmap;boolean isScreenShot=false,isPreview=false;static boolean oldPreviewStatus=false;Camera mCameraDevice=null;  Camera.Parameters mParameters;ImageView iv_capture_view;Handler mHandler=new  Handler();RSImgProcess imgProcess;ThreadPoolExecutor GlobalThreadPool;OnClickListener CameraClickListener=null;Button CameraButton,PauseButton;ImageView mSrcImageView,mDstImageView;int Camera_w,Camera_h;byte [] PreviewBuff=null;byte [] OneFrameBuff=null;int FrameCount=0;long Time1,Time2;int screen_orientation;MainActivity mMainActivity;

7.2 MainActivity中的函数 prepareCamera

private void prepareCamera() {mCameraDevice=Camera.open();mParameters=mCameraDevice.getParameters();Camera_w=640;Camera_h=480;mParameters.setPreviewSize(Camera_w,Camera_h);//w,hCamera_w=mParameters.getPreviewSize().width ;Camera_h=mParameters.getPreviewSize().height; mParameters.setPictureSize(Camera_w,Camera_h);float perPixel = ImageFormat.getBitsPerPixel(mParameters.getPreviewFormat()) / 8f;final int OneFrameSize=(int)(Camera_w*Camera_h* perPixel);final int previewBufferSize = (int) (Camera_w * Camera_h *2* perPixel);Log.i("prepareCamera","w*h:"+Camera_w+"*"+Camera_h);Log.i("prepareCamera","perPixel:"+perPixel);Log.i("prepareCamera","previewBufferSize:"+previewBufferSize);OneFrameBuff=new byte[(int)(Camera_w*Camera_h* perPixel)];PreviewBuff=new byte[previewBufferSize];mCameraDevice.addCallbackBuffer(PreviewBuff);mParameters.setPictureFormat(ImageFormat.YV12);mCameraDevice.setParameters(mParameters);isScreenShot=true;isPreview=true;mCameraDevice.setPreviewCallbackWithBuffer(new Camera.PreviewCallback() {@Overridepublic void onPreviewFrame(byte[] data, Camera camera) {if (isScreenShot && isPreview) {isScreenShot = false;//    System.arraycopy(data,0,OneFrameBuff,0,OneFrameSize);//   Log.i("onPreviewFrame","data.length"+data.length);//  Log.i("onPreviewFrame","screen_orientation"+screen_orientation); screen_orientation = iv_capture_view.getResources().getConfiguration().orientation;//   Log.i("onPreviewFrame","screen_orientation"+screen_orientation); screenShot(data,screen_orientation);//   screenShot(OneFrameBuff,screen_orientation);}// camera.addCallbackBuffer(data);//    Log.i("onPreviewFrame","FrameCount"+FrameCount+isScreenShot+isPreview); camera.addCallbackBuffer(PreviewBuff);}});mCameraDevice.startPreview(); mCameraDevice.autoFocus(null);Time1= System.currentTimeMillis();FrameCount=0;Log.i("prepareCamera","mCameraDevice"+mCameraDevice);}

7.3 MainActivity中的函数 onresume/onPause

protected void onResume() {// TODO Auto-generated method stubsuper.onResume();   screen_orientation = iv_capture_view.getResources().getConfiguration().orientation;iv_capture_view.setImageBitmap(mOutBitmap);isScreenShot=true;isPreview=oldPreviewStatus;Log.i("onResume","screen_orientation"+screen_orientation+" "+isScreenShot+isPreview);imgProcess=new RSImgProcess(mMainActivity);GlobalThreadPool = new ThreadPoolExecutor(8, 8, 80, TimeUnit.MILLISECONDS,new ArrayBlockingQueue<Runnable>(200));if(isPreview && mCameraDevice==null){    //暂停后,Camera被注销为空了。prepareCamera();Log.i("onResume","Resume Camera");    }}@Overrideprotected void onPause() {// TODO Auto-generated method stuboldPreviewStatus=isPreview;mOutBitmap=bitmap;isPreview=false;if(mCameraDevice!=null){mCameraDevice.stopPreview(); mCameraDevice.release();mCameraDevice=null;}GlobalThreadPool.shutdown();try {Thread.sleep(30);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}//        GlobalThreadPool.shutdownNow();     super.onPause();Log.i("onPause","mCameraDevice"+mCameraDevice);}

7.4 MainActivity中的函数: 图像处理

private void screenShot(final byte[] pixel,final int screenorientation) {GlobalThreadPool.execute(new Runnable() {@Overridepublic void run() {bitmap = imgProcess.processImg(pixel, Camera_w, Camera_h,iv_capture_view.getWidth(),iv_capture_view.getHeight(),screenorientation);mHandler.post(new Runnable() {@Overridepublic void run() {iv_capture_view.setImageBitmap(bitmap);//          Log.i("post","setImageBitmap width"+bitmap.getWidth());//          Log.i("post","setImageBitmap");//               iv_capture_view.setVisibility(View.VISIBLE);//                AlphaAnimation inAnimation = new AlphaAnimation(0f, 1.0f);//                inAnimation.setDuration(250);//                iv_capture_view.startAnimation(inAnimation);FrameCount++;if(FrameCount>=100){Time2= System.currentTimeMillis();Log.i("screenShot","Time:"+(Time2-Time1));FrameCount=0;}if(FrameCount==0){Time1= System.currentTimeMillis();}}});mHandler.postDelayed(new Runnable() {@Overridepublic void run() {//  iv_capture_view.setVisibility(View.INVISIBLE);isScreenShot=true;}}, 20);}});}

8. 效果图:

9. 可以自己修改代码,变成黑白图。

Android eclipse RenderScript 初探(快速处理图片)相关推荐

  1. Android使用RenderScript实现图片的高斯模糊效果

    Android使用RenderScript实现图片的高斯模糊效果 首先来看一下什么是高斯模糊效果呢? 高斯模糊(英语:Gaussian Blur),也叫高斯平滑,是在Adobe Photoshop.G ...

  2. android设备局域网中快速搜索之cling方式

    cling方式就像pc端windows局域网工作组刷新显示一样,原来用过扫描ip地址的方式,可以使用就是有点慢,还有一种自己加入组广播,通过发送组广播的方式. android设备局域网中快速搜索之cl ...

  3. Android百分比布局初探

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/u010046908/article/details/48802909 标题:Android百分比布局 ...

  4. Mac OS X下配置Cocos2d-x for Android(Eclipse)IOS(Xcode)开发环境

    前面一段时间只用Cocos2d-x在IOS平台下开发, 学习Cocos2d-x不就是为了他的跨平台特性么? 所以必须也要掌握在Android下的开发, 才能引爆Cocos2d-x的跨平台特性, 发挥其 ...

  5. Android组件化初探

    Android组件化初探 1. 现状 随着业务增加,代码量急剧增加,大大延长了编译时间,短则3min,长则7.8min:很多同学为节省开发时间,自己新建新的app,完成开发后,再合并到project中 ...

  6. android eclipse中导入framework.jar以及使用其隐藏类的方法

    想使用开关3G的网络数据 ConnectivityManager cm =(ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERV ...

  7. android eclipse的环境配置

    前几天,公司让我把代码与别的公司的代码合并,我用的是android studio开发,而那个公司是用的eclipse开发,所以自己只好搭建eclipse的环境后,把修改的内容添加到eclipse工程, ...

  8. Android Eclipse ADT使用Tips

    以下为本人使用Android Eclipse ADT开发应用积累的较为常用的使用技巧:                                                    开启Ecl ...

  9. 安装eclipse及android,Eclipse Android 安装

    8种机械键盘轴体对比 本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选? 摘要:Eclipse & Android 安装 我参考这个网址去安装Eclipse及Android http:/ ...

最新文章

  1. linux:scp命令
  2. 面向工业场景,如何实现绿色智能?
  3. Spring--Quartz 任务调度的配置详解
  4. Python引用任意位置模块方法总结
  5. Java计算两个经纬度间的距离
  6. 老实人一般容易吃亏,但是老实人遇到的机会比别人多一点点!
  7. 下一代面向知识的 BI 到底有何不同,从 nextionBI 数据解读能力中一探究竟
  8. java私聊_【转帖】实现了视频私聊功能
  9. C#:判断数组中有没有某个值的方法
  10. 那些年,我们踩过的 Java 坑 | 凌云时刻
  11. Maven工程pom.xml文件秒变gradle工程的命令
  12. 【Linux】Linux的信号量集
  13. GreenPlum数据库介绍
  14. C++输出谢尔宾斯基三角形
  15. 数据结构 —— 队列
  16. 永恒之蓝--Windows7
  17. Office2019 VOL版本 自定义安装组件
  18. stream 计算一个List对象中某个字段总和
  19. 微信小程序开发:调用百度文字识别API实现图文识别
  20. 报错:java.net.bindexception: address already in use: jvm_bind:8082

热门文章

  1. [好累的游戏]传球游戏
  2. 一站式终端解决方案 —— MobaXterm使用宝典
  3. MATLAB求解非线性方程
  4. 前端面试超全整理0(html css)
  5. 基于Python+SQLite实现校园信息化统计平台【100010095】
  6. JAVA实验1.7-5 以英里计的平均速度 (7 分)
  7. java 给定一个N阶矩阵A,输出A的M次幂(M是非负整数)
  8. 【华为AI比赛】广告信息流跨域CTR预估(持续更新)
  9. ADC转换汇总(STM32、取平均、精度等)
  10. Linux $ROOT 用户无权限操作文件/目录问题