最近在做的几个项目都和摄像头有关,其中不乏图像识别的,但是拍照识别有时候感觉还是有些low,直接把画面一对准自己就识别了多好,就像zxing扫描二维码一样,于是上网查了很多资料,找到了
需要给camera对象设置一个 Camera.PreviewCallback,在这个回调中实现一个方法onPreviewFrame(byte[] data, Camera camera)
当然如果我们设置camera.setPreviewCallback(callback);在设置后onPreviewFrame这个方法会被一直调用,我们可以在摄像头对焦成功够设置
camera.setOneShotPreviewCallback(previewCallback);如果这样设置onPreviewFrame这个方法就会被调用一次,我们只要将其中的data取回做成bitmap来做相应的处理就行了
那么有人问了,为什么不在对焦成功后拍照呢,因为拍照后画面会顿一下,无论你再怎么设置那几个参数时间(具体名字忘了),也会有相当短暂的停顿,所以要借助onPreviewFrame这个方法来获取图像,那么直接上onPreviewFrame这个方法的代码吧
Bitmap bitmap;
public void runInPreviewFrame(byte[] data, Camera camera) {
bitmap = BitmapFactory.decodeByteArray(rawImage, 0, rawImage.length, options);
}
我靠,就这个简单的几行代码楼主跟这墨迹这么半天?别急,如果不出意外的话,一部分人如果只是直接用BitmapFactory.decodeByteArray这个方法的话,应该有一部分会报错:
SkImageDecoder::Factory returned null;(偷笑)
原因不多说了,就是因为格式问题引起的,需要对data进行一下预处理,不废话,贴代码
ByteArrayOutputStream baos;
byte[] rawImage;
Bitmap bitmap;
public void runInPreviewFrame(byte[] data, Camera camera) {
camera.setOneShotPreviewCallback(null);
//处理data
Camera.Size previewSize = camera.getParameters().getPreviewSize();//获取尺寸,格式转换的时候要用到
BitmapFactory.Options newOpts = new BitmapFactory.Options();
newOpts.inJustDecodeBounds = true;
YuvImage yuvimage = new YuvImage(
data,
ImageFormat.NV21,
previewSize.width,
previewSize.height,
null);
baos = new ByteArrayOutputStream();
yuvimage.compressToJpeg(new Rect(0, 0, previewSize.width, previewSize.height), 100, baos);// 80--JPG图片的质量[0-100],100最高
rawImage = baos.toByteArray();
//将rawImage转换成bitmap
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.RGB_565;
bitmap = BitmapFactory.decodeByteArray(rawImage, 0, rawImage.length, options);
//下面对bitmap进行处理
}
最后啊,好习惯,记得bitmap要及时回收哈