Android摄像头:只拍摄SurfaceView预览界面特定区域内容(矩形框)---完整实现(原理:底层SurfaceView+上层绘制ImageView)

2013-02-13 11:54 34368人阅读 评论(86) 收藏 举报
本文章已收录于:

 Android知识库
 分类:
Android开发(128) 

版权声明:本文为博主原创文章,未经博主允许不得转载。

目录(?)[+]

【后注:】下载代码的注意,我的手机是4.3寸的屏,华为U9200.如果不能运行的请修改参数。看前文的第四条。Y的,省的说我传的代码不能用 

最近一直在审视以前做过的东西,关于Android摄像头预览,预览界面上呈现矩形框,在前文(

Android开发 摄像头SurfaceView预览 背景带矩形框 实现(原理:双surfaceview,顶层画矩形框,底层预览视频)

)----http://blog.csdn.net/yanzi1225627/article/details/7934710已经实现。最近发现上层绘制矩形框,用surfaceview有点大材小用了。SurfaceView绘制动画更合适,只绘制个矩形框用ImageView足够了。但有些时候必须要用SurfaceView来实现。比如360手机安全卫士扫描二维码的实现应该就是通过上下两层SurfaceView实现的(见下图)。上层SurfaceView用于显示那个可以旋转的扫描示意框,底层SurfaceView预览摄像头视频。

废话不说了,稍候几天我会仿照上面360这个扫描二维码的界面做一个工程(结合PreviewCallback),公开出来。这次先谈用底层surfaceView+上层ImageView实现只拍摄矩形框中的图像。新建一个类继承ImageView,源码如下:

[java] view plaincopy print?
  1. package yan.guoqi.rectphoto;
  2. import android.content.Context;
  3. import android.graphics.Canvas;
  4. import android.graphics.Color;
  5. import android.graphics.Paint;
  6. import android.graphics.Paint.Style;
  7. import android.graphics.Rect;
  8. import android.util.AttributeSet;
  9. import android.widget.ImageView;
  10. public class DrawImageView extends ImageView{
  11. public DrawImageView(Context context, AttributeSet attrs) {
  12. super(context, attrs);
  13. // TODO Auto-generated constructor stub
  14. }
  15. Paint paint = new Paint();
  16. {
  17. paint.setAntiAlias(true);
  18. paint.setColor(Color.RED);
  19. paint.setStyle(Style.STROKE);
  20. paint.setStrokeWidth(2.5f);//设置线宽
  21. paint.setAlpha(100);
  22. };
  23. @Override
  24. protected void onDraw(Canvas canvas) {
  25. // TODO Auto-generated method stub
  26. super.onDraw(canvas);
  27. canvas.drawRect(new Rect(100, 200, 400, 500), paint);//绘制矩形
  28. }
  29. }

布局文件里与前文http://blog.csdn.net/yanzi1225627/article/details/8577756这里一样,只是在帧布局里加一个上面自定义的DrawImageView,整个布局文件示下:

[html] view plaincopy print?
  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2. xmlns:tools="http://schemas.android.com/tools"
  3. android:layout_width="fill_parent"
  4. android:layout_height="fill_parent"
  5. android:orientation="vertical" >
  6. <TextView
  7. android:layout_width="wrap_content"
  8. android:layout_height="wrap_content"
  9. android:text="@string/BestWish"
  10. tools:context=".RectPhoto" />
  11. <FrameLayout
  12. android:layout_width="wrap_content"
  13. android:layout_height="wrap_content" >
  14. <SurfaceView
  15. android:id="@+id/previewSV"
  16. android:layout_width="fill_parent"
  17. android:layout_height="800px" />
  18. <yan.guoqi.rectphoto.DrawImageView
  19. android:id="@+id/drawIV"
  20. android:layout_width="fill_parent"
  21. android:layout_height="800px"
  22. />
  23. </FrameLayout>
  24. <ImageButton
  25. android:id="@+id/photoImgBtn"
  26. android:layout_width="wrap_content"
  27. android:layout_height="wrap_content"
  28. android:background="@drawable/photo_img_btn"
  29. android:layout_gravity="center" />
  30. </LinearLayout>

在主程序文件里,onCreate()函数里设置底层SurfaceView为底层且透明(如果不设也可以,默认就是如此):

mPreviewSV.setZOrderOnTop(false);

mySurfaceHolder.setFormat(PixelFormat.TRANSPARENT);//translucent半透明 transparent透明

在主UI线程里的onCreate()函数里添加代码:

//绘制矩形的ImageView
        mDrawIV = (yan.guoqi.rectphoto.DrawImageView)findViewById(R.id.drawIV);
        mDrawIV.onDraw(new Canvas());

看上面的DrawImageView的函数里的onDraw,画的矩形是Rect(100, 200, 400, 500)。在onPictureTaken(byte[] data, Camera camera)函数里,先将图片旋转90度,大小成为宽×高(960×1280)。由于预览surfaceview的大小是宽×高(540×800),所以在onPictureTaken函数里将960×1280的图片缩放到540×800, 缩放相同大小后就可以用矩阵的坐标直接截取子图了。核心函数就是这两句:

//将960×1280缩放到540×800
            Bitmap sizeBitmap = Bitmap.createScaledBitmap(rotaBitmap, 540, 800, true);
            Bitmap rectBitmap = Bitmap.createBitmap(sizeBitmap, 100, 200, 300, 300);//截取

注意这个截取的函数参数和矩阵的坐标关系,分别是x轴 y轴起始坐标及 x轴宽度 y轴宽度。截取出来的图片大小应该是300×300. onPictureTaken()函数的源码如下:

[java] view plaincopy print?
  1. public void onPictureTaken(byte[] data, Camera camera) {
  2. // TODO Auto-generated method stub
  3. Log.i(tag, "myJpegCallback:onPictureTaken...");
  4. if(null != data){
  5. mBitmap = BitmapFactory.decodeByteArray(data, 0, data.length);//data是字节数据,将其解析成位图
  6. myCamera.stopPreview();
  7. isPreview = false;
  8. }
  9. //设置FOCUS_MODE_CONTINUOUS_VIDEO)之后,myParam.set("rotation", 90)失效。图片竟然不能旋转了,故这里要旋转下
  10. Matrix matrix = new Matrix();
  11. matrix.postRotate((float)90.0);
  12. Bitmap rotaBitmap = Bitmap.createBitmap(mBitmap, 0, 0, mBitmap.getWidth(), mBitmap.getHeight(), matrix, false);
  13. //旋转后rotaBitmap是960×1280.预览surfaview的大小是540×800
  14. //将960×1280缩放到540×800
  15. Bitmap sizeBitmap = Bitmap.createScaledBitmap(rotaBitmap, 540, 800, true);
  16. Bitmap rectBitmap = Bitmap.createBitmap(sizeBitmap, 100, 200, 300, 300);//截取
  17. //保存图片到sdcard
  18. if(null != rectBitmap)
  19. {
  20. saveJpeg(rectBitmap);
  21. }
  22. //再次进入预览
  23. myCamera.startPreview();
  24. isPreview = true;
  25. }

涉及到的其他函数如saveJpeg()参见前文:

2013新春奉送:Android摄像头开发完美demo---(循环聚焦,缩放大小,旋转picture,查询支持的picturesize, ImageButton按键效果)------------

http://blog.csdn.net/yanzi1225627/article/details/8577756   重复的东西我就不发了。

效果图如下所示:

点击拍照,查看保存后的图片如下:

   反思:

1,SurfaceView为啥 无论translucent半透明还是 transparent透明基本没啥区别?而且surfaceview的setAlpha函数不能用。

2,在这里surfaceview一定要在底层(默认如此),如果设成顶层会看不到红色矩形框。可以自己测试下。

3,最纠结的一点,第一副图片里的360扫描二维码的界面,底层的预览surfaceview是半透明的,底色是灰色的,只有中间的扫描矩形框是透明的,亮色。这一块究竟是怎么实现的??下午实验了n种方法愣是无济于事。我擦。。。如果有高人,希望能不吝指点下。 不过说实话,人家已经设计出来的产品界面看着就是好,不得不服阿。以后要多多模仿钻研这些成型产品的设计。

源码下载:http://download.csdn.net/detail/yanzi1225627/5063105

欢迎android爱好者加群248217350,备注:yanzi

转者另注:如果只是实现矩形框的参照,可以直接在布局文件上叠加ImageView(可以定义自己的类,继承ImageView,参照上面),然后把上面的绘制 矩形改为绘制矩形框,再在onCreate中bringToFont()就可以了。

android SurfaceView 拍照时显示参照矩形框相关推荐

  1. ppt图片在word中不能正常显示,只显示为矩形框的解决方法

    ppt图片在word中不能正常显示,只显示为矩形框的解决方法 参考文章: (1)ppt图片在word中不能正常显示,只显示为矩形框的解决方法 (2)https://www.cnblogs.com/ga ...

  2. Android Camera2拍照时照片拍出来特别暗

    最近在开发相机的过程中遇到这样一个问题,相机打开闪光灯后拍照后照片特别的暗,刚开始打算修改一些拍照时的参数,提高曝光率啊,延长曝光时长来改善照片问题 如一下思路 1.通过设置曝光时间范围(Captur ...

  3. 鼠标悬停在li标签上时显示一个弹框_HTML标签——列表标签

    列表使用场景: 内容相关.结构相似.样式相近的内容,根据内容的不同分为:无序列表.有序列表.定义列表 无序列表:两个标签<ul>和<li>,是嵌套关系,快捷键ul>li ...

  4. iOS 调用系统相册拍照时显示英文问题

    在调用系统相册拍照的时候,在选择照片的时候,发现用的都是英文,效果如下: 我们想把那个Retake 和Use Photo 改为对应的汉字,先来一种最笨的方法,最后在来个高级的方法,最笨的办法当然是我们 ...

  5. php ppt生成图片不显示,ppt图片在word中不能正常显示,只显示为矩形框的解决方法...

    记录下 QT Linux 静态编译遇到的坑 Qt下静态编译Qt,根据我的经验,如果按照Windows下那种直接拿官方sdk安装之后的文件来编译是行不通的,需要直接下载Qt的source包,目前诺基亚的 ...

  6. Android摄像头:只拍摄SurfaceView预览界面特定区域内容(矩形框)---完整实现(原理:底层SurfaceView+上层绘制ImageView)

    [后注:]下载代码的注意,我的手机是4.3寸的屏,华为U9200.如果不能运行的请修改参数.看前文的第四条.Y的,省的说我传的代码不能用  最近一直在审视以前做过的东西,关于android摄像头预览, ...

  7. Android摄像头 只拍摄SurfaceView预览界面特定区域内容(矩形框)---完整实现(原理 底层Surface

    [后注:]下载代码的注意,我的手机是4.3寸的屏,华为U9200.如果不能运行的请修改参数.看前文的第四条.Y的,省的说我传的代码不能用  最近一直在审视以前做过的东西,关于android摄像头预览, ...

  8. Android摄像头:只拍摄SurfaceView预览界面特定区域内容(矩形框)---完整(原理:底层SurfaceView+上层绘制ImageView)...

    Android摄像头:只拍摄SurfaceView预览界面特定区域内容(矩形框)---完整实现(原理:底层SurfaceView+上层绘制ImageView) 分类: Android开发 Androi ...

  9. matlab中给图像加几个矩形框_在图像中画矩形框(matlab)

    参考代码:https://github.com/cuijiaxun/FaceRecognitionByMatlab 中的LabelDetectWindow.m 在目标检测的时候,一般都需要用矩形框圈出 ...

最新文章

  1. css设置元素继承父元素宽度_CSS设置超链接A标签宽度和高度
  2. 进程间通信之消息队列
  3. Apache2.2整合PHP5.2
  4. 腾讯的KDD competition
  5. 【瑕疵检测】基于matlab GUI灰度共生矩阵痕迹检测【含Matlab源码 863期】
  6. 伍德里奇计量经济学第四章计算机答案,计量经济学中文答案 伍德里奇
  7. 4大MQ消息队列的比较
  8. vbox虚拟机安装ssh工具远程连接安装docker
  9. 提高医疗信息化或是解决看病难看病贵的有效助剂
  10. 2019网红带货电商新趋势,与传统电商说再见-云秀传媒
  11. 中国科学技术大学计算机研究生在哪个校区,中国科学技术大学有几个校区及校区地址 哪个校区最好...
  12. C语音是什么类型的语言?
  13. 诛仙手游服务器购买无限制,全新福利提升 摆摊amp;购买增加次数限制_18183诛仙手游专区...
  14. ArcGIS 9.2 开发学习笔记(转自Mars的自语)
  15. EMA—项目 需求设计文档
  16. 神策数据埋点简单使用
  17. Webpack基础应用篇 -[9]管理资源(下)
  18. 简述计算机主机硬件安装流程,怎么看电脑配置信息 看电脑配置的方法【图文步骤】...
  19. 计算机科学硕士学位的英文,中国计算机专业研究生英文学术论文摘要中元话语的使用与特征研究...
  20. 深度学习之 人脸生成 BEGAN TensorFlow 实现

热门文章

  1. RFID读写器的组成
  2. 程序化广告欺诈流量过滤方法
  3. python 制作动画片_分享7个好用的动画制作软件,学会它,人人可以成为动画大师...
  4. 锐捷交换机系统安装与升级
  5. IC卡,ID卡,M1卡,射频卡
  6. Javascript读书笔记(六)函数作用域,声明提前,作用域链,闭包
  7. JavaScript最简单的方法实现简易的计算器
  8. Windows 8应用商店应用如何与Android和iPad对抗?
  9. 怎么判断冠词用a还是an_不定冠词a和an有哪些用法
  10. 什么是HTTP?为什么是不安全的?