热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

androidcamera(4)

先说说我的测试机器:nexuss。以下的结果都是通过nexuss上测试通过。这次先说说步骤:下载zxing2.0,里面的core有个cor

先说说我的测试机器:nexus s。以下的结果都是通过nexus s上测试通过。


这次先说说步骤:下载zxing2.0,里面的core有个core.jar这个有用,将它引用到你的工程下。接着在目录android\src\com\google\zxing\client\android\PlanarYUVLuminanceSource.java,将它复制到你的工程的src文件夹下,记得改了它的包名。准备工作就完成了。然后就上代码:

package com.TestCamera2;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.MultiFormatReader;
import com.google.zxing.Result;
import com.TestCamera2.PlanarYUVLuminanceSource;
import com.google.zxing.common.HybridBinarizer;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Timer;
import java.util.TimerTask;
import android.app.Activity;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.ImageFormat;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.YuvImage;
import android.hardware.Camera;
import android.hardware.Camera.PictureCallback;
import android.hardware.Camera.ShutterCallback;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.Display;
import android.view.KeyEvent;
import android.view.SurfaceHolder;
import android.view.View;
import android.view.SurfaceHolder.Callback;
import android.view.View.OnClickListener;
import android.view.SurfaceView;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
public class TestCamera2Activity extends Activity {private Camera camera;private SurfaceView surfaceView;private boolean preview;final static int width = 352; final static int height = 288; int dstLeft, dstTop, dstWidth, dstHeight; private Timer mTimer;private MyTimerTask mTimerTask ;private Button btn;private Camera.PreviewCallback previewCallback;@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);requestWindowFeature(Window.FEATURE_NO_TITLE);setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);Window window = getWindow();window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);setContentView(R.layout.main);surfaceView = (SurfaceView) findViewById(R.id.preview_view);surfaceView.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);surfaceView.getHolder().setFixedSize(352, 288); //设定surface的大小,必须要,除非你的surface刚好是你手机preview允许的大小 surfaceView.getHolder().addCallback(new SurfaceViewCallback());btn=(Button)findViewById(R.id.button1);btn.setOnClickListener(new OnClickListener(){public void onClick(View v) {mTimer = new Timer(); mTimerTask = new MyTimerTask(); mTimer.schedule(mTimerTask, 0, 80);}});previewCallback = new Camera.PreviewCallback() {public void onPreviewFrame(byte[] data, Camera arg1) {if(data!=null){Log.i("data", "ok");if (dstLeft == 0) {// 只赋值一次 dstLeft = surfaceView.getLeft() * width / getWindowManager().getDefaultDisplay().getWidth(); dstTop = surfaceView.getTop() * height / getWindowManager().getDefaultDisplay().getHeight(); dstWidth = (surfaceView.getRight() - surfaceView.getLeft()) * width / getWindowManager().getDefaultDisplay().getWidth(); dstHeight = (surfaceView.getBottom() - surfaceView.getTop()) * height / getWindowManager().getDefaultDisplay().getHeight(); } //PlanarYUVLuminanceSource source = new PlanarYUVLuminanceSource(data, width, height, dstLeft, dstTop, dstWidth, dstHeight,false); // 取得灰度图 Bitmap bm = source.renderCroppedGreyscaleBitmap(); // 保存灰度图 String picDirStr = Environment.getExternalStorageDirectory()+"/"; File picDir = new File(picDirStr); if(!picDir.exists()){ picDir.mkdir(); } String picName = picDirStr + System.currentTimeMillis() + ".jpg"; File myCaptureFile = new File(picName); try { BufferedOutputStream bos = new BufferedOutputStream( new FileOutputStream(myCaptureFile)); bm.compress(Bitmap.CompressFormat.JPEG, 80, bos); bos.flush(); bos.close(); camera.startPreview(); Log.i("pic","ok");} catch (Exception e) { e.printStackTrace();}// BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source)); MultiFormatReader reader = new MultiFormatReader(); try { Result result = reader.decode(bitmap); String strResult = "BarcodeFormat:"+ result.getBarcodeFormat().toString() + " text:"+ result.getText(); Log.i("result",strResult);Toast.makeText(getApplicationContext(), strResult, Toast.LENGTH_LONG+2000).show();mTimer.cancel(); } catch (Exception e) { Log.i("result","faile");} }else{Log.i("data", "null");}} };}private final class SurfaceViewCallback implements SurfaceHolder.Callback {public void surfaceCreated(SurfaceHolder holder) {camera = Camera.open(); }public void surfaceChanged(SurfaceHolder holder, int format, int width,int height) {Camera.Parameters parameters = camera.getParameters();parameters.setPreviewSize(width, height); parameters.setPreviewFrameRate(5); parameters.setPictureFormat(PixelFormat.JPEG); parameters.set("jpeg-quality", 85);camera.setParameters(parameters); try{ camera.setPreviewDisplay(holder);preview = true;Log.i("camera", "camera open!");}catch(IOException exception) { camera.release(); camera = null; } camera.startPreview();Log.i("camera","camera preview");}public void surfaceDestroyed(SurfaceHolder holder) {if (camera != null) { if(preview) {camera.stopPreview();preview = false;Log.i("destroyprevie", "ok!");} camera.release();camera = null;}} }class MyTimerTask extends TimerTask { @Override public void run() { camera.autoFocus(new Camera.AutoFocusCallback() {public void onAutoFocus(boolean success, Camera camera) {if(success){Log.i("focus","ok!");camera.setOneShotPreviewCallback(previewCallback);}}}); }}
}



接着解说一下这个过程:你按button,手机就开始自动对焦(由Timer不断触发),当对焦成功时,调用函数onPreviewFrame来取得那一帧的图片data然后生成对象PlanarYUVLuminanceSource,由这个对象返回一张灰度图,我将它保存下来以便观察。接下来的工作就是交给解码器完成工作了,若解码成功则直接输出解码结果,然后。如果解码不成功,会不断对焦,不断进行尝试。大家可能觉得这个过程十分简单,但是对于这只菜鸟要用一个星期的时间,花时间搞懂照相机,花时间上网找资料,表示看了很多资料http://www.cnblogs.com/liuan/category/347622.html(我从这个博客学到很多,要感谢一下这个博客的博主),花时间看看zxing,然后慢慢学习。这个过程也学习到很多东西。


最后我说说我这个demo的问题。首先看看我的布局文件



android:screenOrientation="landscape" />



这样的布局导致不能知道surfaceview的大小,但是surfaceview比较大,所以必须要设定
surfaceView.getHolder().setFixedSize(352, 288);我还操蛋的发现parameters.setPreviewSize(width, height); 根本不起作用的,所以还是不设定好,直接设定surfaceview。然后我将surfaceview设定成352*288,这个surfaceview就太小了而且所得到的灰度图大概只能surfaceview的一半大,所以解码永远不成功的,于是我去看了类
PlanarYUVLuminanceSource的构造函数,但是不知所云。我猜想,因为源程序是满屏幕只取中间那个很小的view的灰度图,所以我的小surfaceview被活生生的截图了(本来就刚刚好找到条形码),所以解码不成功。更多发现留给大家了。所以我直接将surfaceview放得大大好了。


接下来我的android camera系列就结束了(我留给自己的工作是实现跟源程序一样的界面)。这次让我感慨良多。这个是我第一次写这样的文章,发觉是超级难写。因为你要尽量保证你的准确性还要描述清楚(我知道我的表达能力十分有限),那么就不得不做大量的尝试,查看大量的资料(我花了一个多星期吧,才开始接触android两个星期左右)。


附上demo:android camera(4)



警告:android camera系列的文章是由一个刚接触android不到一个月的菜鸟所写,所以必然存在很多错误,请大家指出






推荐阅读
  • 个人学习使用:谨慎参考1Client类importcom.thoughtworks.gauge.Step;importcom.thoughtworks.gauge.T ... [详细]
  • Go GUIlxn/walk 学习3.菜单栏和工具栏的具体实现
    本文介绍了使用Go语言的GUI库lxn/walk实现菜单栏和工具栏的具体方法,包括消息窗口的产生、文件放置动作响应和提示框的应用。部分代码来自上一篇博客和lxn/walk官方示例。文章提供了学习GUI开发的实际案例和代码示例。 ... [详细]
  • 本文介绍了机器学习手册中关于日期和时区操作的重要性以及其在实际应用中的作用。文章以一个故事为背景,描述了学童们面对老先生的教导时的反应,以及上官如在这个过程中的表现。同时,文章也提到了顾慎为对上官如的恨意以及他们之间的矛盾源于早年的结局。最后,文章强调了日期和时区操作在机器学习中的重要性,并指出了其在实际应用中的作用和意义。 ... [详细]
  • WhenIusepythontoapplythepymysqlmoduletoaddafieldtoatableinthemysqldatabase,itdo ... [详细]
  • IOS开发之短信发送与拨打电话的方法详解
    本文详细介绍了在IOS开发中实现短信发送和拨打电话的两种方式,一种是使用系统底层发送,虽然无法自定义短信内容和返回原应用,但是简单方便;另一种是使用第三方框架发送,需要导入MessageUI头文件,并遵守MFMessageComposeViewControllerDelegate协议,可以实现自定义短信内容和返回原应用的功能。 ... [详细]
  • Android工程师面试准备及设计模式使用场景
    本文介绍了Android工程师面试准备的经验,包括面试流程和重点准备内容。同时,还介绍了建造者模式的使用场景,以及在Android开发中的具体应用。 ... [详细]
  • 本文讨论了如何使用GStreamer来删除H264格式视频文件中的中间部分,而不需要进行重编码。作者提出了使用gst_element_seek(...)函数来实现这个目标的思路,并提到遇到了一个解决不了的BUG。文章还列举了8个解决方案,希望能够得到更好的思路。 ... [详细]
  • 使用freemaker生成Java代码的步骤及示例代码
    本文介绍了使用freemaker这个jar包生成Java代码的步骤,通过提前编辑好的模板,可以避免写重复代码。首先需要在springboot的pom.xml文件中加入freemaker的依赖包。然后编写模板,定义要生成的Java类的属性和方法。最后编写生成代码的类,通过加载模板文件和数据模型,生成Java代码文件。本文提供了示例代码,并展示了文件目录结构。 ... [详细]
  • 1、Ipv4只能用于内网,外网只能用2、DNS:把域名解析成ip地址3、MAC地址就是物理地址(网卡序列号)   IP地址:电脑序列号4、不同电脑,微信之间互相通信,靠的是端口;  ... [详细]
  • 本文介绍了解决Netty拆包粘包问题的一种方法——使用特殊结束符。在通讯过程中,客户端和服务器协商定义一个特殊的分隔符号,只要没有发送分隔符号,就代表一条数据没有结束。文章还提供了服务端的示例代码。 ... [详细]
  • 本文介绍了在MFC下利用C++和MFC的特性动态创建窗口的方法,包括继承现有的MFC类并加以改造、插入工具栏和状态栏对象的声明等。同时还提到了窗口销毁的处理方法。本文详细介绍了实现方法并给出了相关注意事项。 ... [详细]
  • Postgresql备份和恢复的方法及命令行操作步骤
    本文介绍了使用Postgresql进行备份和恢复的方法及命令行操作步骤。通过使用pg_dump命令进行备份,pg_restore命令进行恢复,并设置-h localhost选项,可以完成数据的备份和恢复操作。此外,本文还提供了参考链接以获取更多详细信息。 ... [详细]
  • 本文介绍了Java后台Jsonp处理方法及其应用场景。首先解释了Jsonp是一个非官方的协议,它允许在服务器端通过Script tags返回至客户端,并通过javascript callback的形式实现跨域访问。然后介绍了JSON系统开发方法,它是一种面向数据结构的分析和设计方法,以活动为中心,将一连串的活动顺序组合成一个完整的工作进程。接着给出了一个客户端示例代码,使用了jQuery的ajax方法请求一个Jsonp数据。 ... [详细]
  • 本文介绍了关于Java异常的八大常见问题,包括异常管理的最佳做法、在try块中定义的变量不能用于catch或finally的原因以及为什么Double.parseDouble(null)和Integer.parseInt(null)会抛出不同的异常。同时指出这些问题是由于不同的开发人员开发所导致的,不值得过多思考。 ... [详细]
  • Question该提问来源于开源项目:react-native-device-info/react-native-device-info ... [详细]
author-avatar
排骨冬菇面
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有