http://eyehere.net/2011/android-camera-2/

在应用里,不需要把拍下来的图片存储,只需要把预览的图片数据处理一下就好,很自然的我只是用了onPreviewFrame调用,考虑处理传递进来的data数据流就是了。

网上很多帖子都说,然后用BitmapFactory的decodeByteArray()函数来解析图片就行了,我试了一下,发现这真是彻头彻尾的谎言,data字节流默认是YCbCr_420_SP(虽然可以改,但其他的格式未必兼容),decodeByteArray()压根儿不认!SDK2.2之后,似乎提供了一个YuvImage的类来转一下(那Google一开始提供这个借口是做什么的?),难道就要把老机给抛弃了么??万万不能啊(穷人最理解穷人们了)!

好在这个世界总是不缺少好人和牛人的,有人提供了这么一段转换的代码:
static public void decodeYUV420SP(int[] rgb, byte[] yuv420sp, int width, int height) {    final int frameSize = width * height;     for (int j = 0, yp = 0; j < height; j++) {        int uvp = frameSize + (j >> 1) * width, u = 0, v = 0;        for (int i = 0; i < width; i++, yp++) {            int y = (0xff & ((int) yuv420sp[yp])) - 16;            if (y < 0) y = 0;            if ((i & 1) == 0) {                v = (0xff & yuv420sp[uvp++]) - 128;                u = (0xff & yuv420sp[uvp++]) - 128;            }             int y1192 = 1192 * y;            int r = (y1192 + 1634 * v);            int g = (y1192 - 833 * v - 400 * u);            int b = (y1192 + 2066 * u);             if (r < 0) r = 0; else if (r > 262143) r = 262143;            if (g < 0) g = 0; else if (g > 262143) g = 262143;            if (b < 0) b = 0; else if (b > 262143) b = 262143;             rgb[yp] = 0xff000000 | ((r << 6) & 0xff0000) | ((g >> 2) & 0xff00) | ((b >> 10) & 0xff);        }    }}


不是很清楚这里面的原理,但是它能在我这里工作,暂时可以了……然后你才可以吧处理完的rgb[]传给decodeByteArray()。

顺便好心的把使用SDK2.2之后的也贴上
public void onPreviewFrame(byte[] data, Camera arg1) {    FileOutputStream outStream = null;    try {        YuvImage yuvimage = new YuvImage(data,ImageFormat.NV21,arg1.getParameters().getPreviewSize().width,arg1.getParameters().getPreviewSize().height,null);        ByteArrayOutputStream baos = new ByteArrayOutputStream();        yuvimage.compressToJpeg(new Rect(0,0,arg1.getParameters().getPreviewSize().width,arg1.getParameters().getPreviewSize().height), 80, baos);         outStream = new FileOutputStream(String.format("/sdcard/%d.jpg", System.currentTimeMillis()));        outStream.write(baos.toByteArray());        outStream.close();         Log.d(TAG, "onPreviewFrame - wrote bytes: " + data.length);    } catch (FileNotFoundException e) {        e.printStackTrace();    } catch (IOException e) {        e.printStackTrace();    } finally {    }    Preview.this.invalidate();}


得到的图像旋转了90°(似乎有的机型设置一下setRotation(90)可以搞定,但还是那句话,不通用啊,况且这个是2.1之后的API)。手动转一下吧……
Matrix matrix = new Matrix();matrix.postRotate(90);// 这里的rgb就是刚刚转换处理的东东Bitmap bmp = Bitmap.createBitmap(rgb, 0, w, w, h, Bitmap.Config.ARGB_4444);Bitmap nbmp = Bitmap.createBitmap(bmp,                0, 0, bmp.getWidth(),  bmp.getHeight(), matrix, true);


考虑到需要做识别,自然得先把它转成灰度图像,经典心理公式Gray = R*0.299 + G*0.587 + B*0.114出场了,但是手机的计算速度不那么快,这样的浮点运算还是尽量避免吧~ 于是考虑Gray = (R*299 + G*587 + B*114 + 500) / 1000或者Gray = (R*30 + G*59 + B*11 + 50) / 100。但是除法总是还是不够快,用移位吧……Gray = (R*19595 + G*38469 + B*7472) >> 16,稍微小一点,用Gray = (R*38 + G*75 + B*15) >> 7也足够了。

更多相关文章

  1. Android(安卓)嵌入式 linux 去掉启动时闪烁的光标 和制作启动LOG
  2. Android(安卓)腾讯面试Glide源码解析 3分钟手写最牛框架 看完成
  3. android图像绘制(六)——获取本地图片或拍照图片
  4. android 辅助工具类—— 图片缓冲池
  5. android 拍照或者图库选择 压缩后 图片 上传
  6. android 9.png 图片制作
  7. Android(安卓)图片转动效果(一)
  8. Android(安卓)中 Base64 转换成 图片
  9. ps图片黑白调整算法——Android实现及性能优化

随机推荐

  1. Android数据存取之Files
  2. 用android build system 编译自己的init
  3. unityd 公布android apk相关
  4. Android(安卓)文件绝对路径和Content开头
  5. 【Android Developers Training】 25. 保
  6. Android修改图片颜色-转成灰度图
  7. android命令gradle打包apk
  8. android pullToRefreshListView的item点
  9. Android,子类访问父类私有成员
  10. kotlin常用工具类总结,高效优雅的开发Andr