如何让每一个500毫秒后摄像头preVIEW框架 [英] How to get camera preview frame after every 500ms
问题描述
我开发的示例应用程序,让我色$ C $尖锐的图像或对象了C通过摄像头的机器人。我的应用是类似这样的应用程序,我使用这申请code这一点。
使用此应用程序code,我能够不断地得到相机preVIEW框架,这让我的色彩$ C $当前previewframe℃。我想使它一些延迟。我希望每一个500毫秒后,得到的只有1个摄像头preVIEW框架。
我如何才能做到这一点,我需要做的,这个code什么修改。
code:
类preVIEW延伸SurfaceView实现SurfaceHolder.Callback,previewCallback {
公共接口previewListener {
公共无效在previewUpdated(INT []像素,诠释的宽度,高度INT);
}
previewListener监听;
SurfaceHolder mHolder;
相机mCamera = NULL;
byte []的缓冲区;
INT缓冲区大小;
私人布尔isFrontCamera = FALSE;
布尔lightOn = FALSE;
私人布尔isPaused得到= FALSE;
//这个变量是负责获取和设置的相机设置
私人参数参数;
//这个变量存储摄像机的preVIEW大小
私人大小previewSize;
//这个数组存储像素为十六进制对
私人INT []像素;
preVIEW(上下文的背景下){
超(上下文);
//安装SurfaceHolder.Callback所以我们得到通知时,该
//下垫面创建和销毁。
mHolder = getHolder();
mHolder.addCallback(本);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
尝试 {
//实例化EnterColorListener,所以我们可以将事件发送到主机
监听=(previewListener)范围内;
}赶上(ClassCastException异常E){
//活动不实现接口,抛出异常
抛出新ClassCastException异常(context.toString()
+必须实现previewListener);
}
}
公共无效surfaceCreated(SurfaceHolder持有者){
//表面经创建,获取摄像机,并告诉它在哪里
//绘制。
尝试 {
CameraInfo信息=新CameraInfo();
Camera.getCameraInfo(0,信息);
如果(info.facing == CameraInfo.CAMERA_FACING_FRONT){
this.isFrontCamera =真;
}
mCamera = Camera.open(0); //尝试获取的Camera实例。指数B / C前摄像头都OK了。
}
赶上(例外五){
//相机无法使用(使用或不存在)
Log.e(相机错误,无法打开相机);
返回;
}
尝试 {
mCamera.setDisplayOrientation(90);
mCamera.set previewDisplay(保持器);
}赶上(IOException异常除外){
mCamera.release();
mCamera = NULL;
}
}
//感谢骗codeR @ github上
公共无效闪光灯(){
如果(supportsFlash()){
如果(!lightOn){
lightOn =真;
mCamera.stop preVIEW();
mCamera.set previewCallbackWithBuffer(本); // mCamera.set previewCallback(本); //设置previewCallbackWithBuffer(本);
parameters.setFlashMode(Parameters.FLASH_MODE_TORCH);
mCamera.setParameters(参数);
mCamera.start preVIEW();
} 其他 {
lightOn = FALSE;
mCamera.stop preVIEW();
mCamera.set previewCallbackWithBuffer(本); //设置previewCallback(本); //设置previewCallbackWithBuffer(本);
parameters.setFlashMode(Parameters.FLASH_MODE_OFF);
mCamera.setParameters(参数);
mCamera.start preVIEW();
}
}
}
//感谢http://ikravchenko.blogspot.com/2013/09/nexus-7-2013-torch-issue.html
公共布尔supportsFlash(){
如果(的getContext()。getPackageManager()。hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH)){
参数= mCamera.getParameters();
如果(parameters.getFlashMode()!= NULL){
名单<字符串> supportedFlashModes = parameters.getSupportedFlashModes();
如果(supportedFlashModes ==空|| supportedFlashModes.isEmpty()|| supportedFlashModes.size()== 1&安培;&安培; supportedFlashModes.get(0).equals(Camera.Parameters.FLASH_MODE_OFF)){
返回false;
}
返回true;
}
}
返回false;
}
公共无效surfaceDestroyed(SurfaceHolder持有者){
//面,当我们返回将被销毁,所以停止了preVIEW。
//因为CameraDevice对象不是共享资源,这是非常
//重要的是要释放它当活动被暂停。
如果(mCamera!= NULL){
mCamera.stop preVIEW();
mCamera.set previewCallback(NULL); //设置previewCallbackWithBuffer(空);
mCamera.release();
mCamera = NULL;
}
}
公共布尔isFrontCamera(){
返回isFrontCamera;
}
/ * TODO:修复bug的空指针异常* /
公共无效surfaceChanged(SurfaceHolder持有人,INT格式,INT W,INT高){
//现在的尺寸是已知的,设置相机参数,并开始
//在preVIEW。
如果(mCamera!= NULL){
参数= mCamera.getParameters();
//做自动对焦,需要设置的参数(如果可用)
//http://stackoverflow.com/questions/11623266/camera-parameters-setfocusmode-is-not-working
名单<字符串> focusModes = parameters.getSupportedFocusModes();
如果(focusModes!= NULL){
如果(focusModes.contains(Parameters.FOCUS_MODE_CONTINUOUS_PICTURE))
parameters.setFocusMode(Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
否则,如果(focusModes.contains(Parameters.FOCUS_MODE_CONTINUOUS_VIDEO))
parameters.setFocusMode(Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
否则,如果(focusModes.contains(Parameters.FOCUS_MODE_AUTO))
parameters.setFocusMode(Parameters.FOCUS_MODE_AUTO);
}
//必须得到previewSizes因为不是所有的设备都支持任意的previews
//下面是堆栈溢出
INT宽度= this.getWidth();
INT高= this.getHeight();
大小最好= NULL;
名单< Camera.Size> previewSizes = parameters.getSupported previewSizes();
//你需要选择最合适的previewSize您的应用程序
的for(int i = 0; I< previewSizes.size();我++){
尺寸尺寸= previewSizes.get(我);
如果((size.width< =宽度放大器;&安培; size.height< =身高)||(size.height< =宽度放大器;&安培; size.width< =身高)){
如果(最好== NULL){
最好=大小;
} 其他 {
INT resultArea = best.width * best.height;
INT newArea = size.width * size.height;
如果(newArea> resultArea){
最好=大小;
}
}
}
}
//确保东西挑选出来的。 previewSizes保证为是至少有一件事。
如果(最好的!= NULL){
previewSize =最好;
} 其他 {
previewSize = previewSizes.get(0);
}
parameters.set previewSize(previewSize.width,previewSize.height);
像素=新INT [previewSize.width * previewSize.height]。
mCamera.setParameters(参数);
//设置在这个类进行一个定义相机回调
mCamera.set$p$pviewCallbackWithBuffer(this);//set$p$pviewCallback(this);//set$p$pviewCallbackWithBuffer(this);
BUFFERSIZE = $p$pviewSize.width*$p$pviewSize.height*ImageFormat.getBitsPerPixel(parameters.get$p$pviewFormat())/8;
缓冲区=新的字节[BUFFERSIZE]
resetBuffer();
(!isPaused得到),如果mCamera.start preVIEW();
}
}
公共无效暂停(布尔isPaused得到){
this.isPaused = isPaused得到;
如果(isPaused得到){
parameters.setFlashMode(Parameters.FLASH_MODE_OFF);
mCamera.setParameters(参数);
mCamera.stop preVIEW();
} 其他 {
如果(mCamera!= NULL){
mCamera.set$p$pviewCallbackWithBuffer(this);//set$p$pviewCallback(this);//set$p$pviewCallbackWithBuffer(this);
如果(lightOn)
parameters.setFlashMode(Parameters.FLASH_MODE_TORCH);
mCamera.setParameters(参数);
mCamera.start preVIEW();
}
}
}
公共无效resetBuffer(){
如果(mCamera!= NULL){
mCamera.addCallbackBuffer(缓冲液);
}
}
@覆盖
在previewFrame(byte []的数据,摄像头摄像头){公共无效
//变换NV21像素数据分成RGB像素
德codeYUV420SP(像素,数据,previewSize.width,previewSize.height);
listener.On previewUpdated(像素,previewSize.width,previewSize.height);
}
//从科泰项目的方法!不是我的!见下文...
虚空德codeYUV420SP(INT [] RGB,byte []的yuv420sp,诠释的宽度,高度INT){
最终诠释框架尺寸=宽*高;
为(诠释J = 0,YP = 0; J&所述;高度; J ++){INT UVP =框架尺寸+(J>→1)*宽度,U = 0,V = 0;
的for(int i = 0; I<宽度;我++,YP ++){
INT Y =(0xFF的及((int)的yuv420sp [YP])) - 16;
如果(γ℃的)
Y = 0;
如果((ⅰ&安培; 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);
如果(为r 0)R = 0;否则,如果(R> 262143)
R = 262143;
如果(克℃,)克= 0;否则,如果(G> 262143)
G = 262143;
如果(b将0)B = 0;否则,如果(B> 262143)
B = 262143;
RGB [YP] = 0xff000000 | ((为r&10 6)及为0xFF0000)| ((g取代;→2)及为0xFF00)| ((B个大于10)及0xff的);
}
}
}
}
您可以计算在previewFrame经过的时间()。例如:
布尔isFirstTime = TRUE;
长的startTime = 0;
previewCallback回调=新的previewCallback(){
@覆盖
在previewFrame(byte []的数据,摄像头摄像头){公共无效
// TODO自动生成方法存根
如果(isFirstTime){
isFirstTime = FALSE;
的startTime = SystemClock.currentThreadTimeMillis();
德codeYUV420SP(像素,数据,previewSize.width,previewSize.height);
listener.On previewUpdated(像素,previewSize.width,previewSize.height);
}
其他 {
长currentTime的= SystemClock.currentThreadTimeMillis();
长elapsedTime = currentTime的 - 的startTime;
如果(elapsedTime> = 500){//触发事件
的startTime = currentTime的;
德codeYUV420SP(像素,数据,previewSize.width,previewSize.height);
listener.On previewUpdated(像素,previewSize.width,previewSize.height);
}
}
}
};
不要忘了,当你切换preVIEW状态重置布尔值和开始时间。
I am developing sample application which gives me color code of pointed image or object via Camera in android. My application is similar to this application and I am using this application code for this.
Using this application code I am able to get camera preview frames continuously and it gives me color code of current previewframe. I want to make it some delay. I want to get only 1 camera preview frame after every 500ms.
How Can i do that, what modification I need to do in this code.
Code :
class Preview extends SurfaceView implements SurfaceHolder.Callback, PreviewCallback {
public interface PreviewListener {
public void OnPreviewUpdated(int[] pixels, int width, int height);
}
PreviewListener listener;
SurfaceHolder mHolder;
Camera mCamera = null;
byte[] buffer;
int bufferSize;
private boolean isFrontCamera = false;
boolean lightOn = false;
private boolean isPaused = false;
//This variable is responsible for getting and setting the camera settings
private Parameters parameters;
//this variable stores the camera preview size
private Size previewSize;
//this array stores the pixels as hexadecimal pairs
private int[] pixels;
Preview(Context context) {
super(context);
// Install a SurfaceHolder.Callback so we get notified when the
// underlying surface is created and destroyed.
mHolder = getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
try {
// Instantiate the EnterColorListener so we can send events to the host
listener = (PreviewListener) context;
} catch (ClassCastException e) {
// The activity doesn't implement the interface, throw exception
throw new ClassCastException(context.toString()
+ " must implement PreviewListener");
}
}
public void surfaceCreated(SurfaceHolder holder) {
// The Surface has been created, acquire the camera and tell it where
// to draw.
try {
CameraInfo info = new CameraInfo();
Camera.getCameraInfo(0, info);
if (info.facing == CameraInfo.CAMERA_FACING_FRONT) {
this.isFrontCamera = true;
}
mCamera = Camera.open(0); // attempt to get a Camera instance. index b/c front cameras are ok too.
}
catch (Exception e){
// Camera is not available (in use or does not exist)
Log.e("camera error", "could not open camera");
return;
}
try {
mCamera.setDisplayOrientation(90);
mCamera.setPreviewDisplay(holder);
} catch (IOException exception) {
mCamera.release();
mCamera = null;
}
}
// thanks cheatcoder@github
public void flash() {
if (supportsFlash()) {
if (!lightOn) {
lightOn = true;
mCamera.stopPreview();
mCamera.setPreviewCallbackWithBuffer(this);// mCamera.setPreviewCallback(this);//setPreviewCallbackWithBuffer(this);
parameters.setFlashMode(Parameters.FLASH_MODE_TORCH);
mCamera.setParameters(parameters);
mCamera.startPreview();
} else {
lightOn = false;
mCamera.stopPreview();
mCamera.setPreviewCallbackWithBuffer(this); //setPreviewCallback(this);//setPreviewCallbackWithBuffer(this);
parameters.setFlashMode(Parameters.FLASH_MODE_OFF);
mCamera.setParameters(parameters);
mCamera.startPreview();
}
}
}
// thanks http://ikravchenko.blogspot.com/2013/09/nexus-7-2013-torch-issue.html
public boolean supportsFlash() {
if (getContext().getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH)) {
parameters = mCamera.getParameters();
if (parameters.getFlashMode() != null) {
List<String> supportedFlashModes = parameters.getSupportedFlashModes();
if (supportedFlashModes == null || supportedFlashModes.isEmpty() || supportedFlashModes.size() == 1 && supportedFlashModes.get(0).equals(Camera.Parameters.FLASH_MODE_OFF)) {
return false;
}
return true;
}
}
return false;
}
public void surfaceDestroyed(SurfaceHolder holder) {
// Surface will be destroyed when we return, so stop the preview.
// Because the CameraDevice object is not a shared resource, it's very
// important to release it when the activity is paused.
if (mCamera != null) {
mCamera.stopPreview();
mCamera.setPreviewCallback(null);//setPreviewCallbackWithBuffer(null);
mCamera.release();
mCamera = null;
}
}
public boolean isFrontCamera() {
return isFrontCamera;
}
/* TODO: fix the bug with the null pointer exception */
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
// Now that the size is known, set up the camera parameters and begin
// the preview.
if (mCamera != null) {
parameters = mCamera.getParameters();
//to do autofocus, need to set the parameters if available
//http://stackoverflow.com/questions/11623266/camera-parameters-setfocusmode-is-not-working
List<String> focusModes = parameters.getSupportedFocusModes();
if (focusModes != null) {
if (focusModes.contains(Parameters.FOCUS_MODE_CONTINUOUS_PICTURE))
parameters.setFocusMode(Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
else if (focusModes.contains(Parameters.FOCUS_MODE_CONTINUOUS_VIDEO))
parameters.setFocusMode(Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
else if (focusModes.contains(Parameters.FOCUS_MODE_AUTO))
parameters.setFocusMode(Parameters.FOCUS_MODE_AUTO);
}
//have to get previewSizes because not all devices support arbitrary previews
//the following is from Stack Overflow
int width = this.getWidth();
int height = this.getHeight();
Size best = null;
List<Camera.Size> previewSizes = parameters.getSupportedPreviewSizes();
// You need to choose the most appropriate previewSize for your app
for (int i = 0; i < previewSizes.size(); i++) {
Size size = previewSizes.get(i);
if ((size.width <= width && size.height <= height) || (size.height <= width && size.width <= height)) {
if (best==null) {
best=size;
} else {
int resultArea=best.width*best.height;
int newArea=size.width*size.height;
if (newArea>resultArea) {
best=size;
}
}
}
}
// make sure something is picked. previewSizes is guarenteed to have at least one thing.
if (best != null) {
previewSize = best;
} else {
previewSize = previewSizes.get(0);
}
parameters.setPreviewSize(previewSize.width, previewSize.height);
pixels = new int[previewSize.width * previewSize.height];
mCamera.setParameters(parameters);
//sets the camera callback to be the one defined in this class
mCamera.setPreviewCallbackWithBuffer(this);//setPreviewCallback(this);//setPreviewCallbackWithBuffer(this);
bufferSize = previewSize.width*previewSize.height*ImageFormat.getBitsPerPixel(parameters.getPreviewFormat())/8;
buffer = new byte[bufferSize];
resetBuffer();
if (!isPaused) mCamera.startPreview();
}
}
public void pause(boolean isPaused) {
this.isPaused = isPaused;
if (isPaused) {
parameters.setFlashMode(Parameters.FLASH_MODE_OFF);
mCamera.setParameters(parameters);
mCamera.stopPreview();
} else {
if (mCamera != null) {
mCamera.setPreviewCallbackWithBuffer(this);//setPreviewCallback(this);//setPreviewCallbackWithBuffer(this);
if(lightOn)
parameters.setFlashMode(Parameters.FLASH_MODE_TORCH);
mCamera.setParameters(parameters);
mCamera.startPreview();
}
}
}
public void resetBuffer() {
if (mCamera != null) {
mCamera.addCallbackBuffer(buffer);
}
}
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
//transforms NV21 pixel data into RGB pixels
decodeYUV420SP(pixels, data, previewSize.width, previewSize.height);
listener.OnPreviewUpdated(pixels, previewSize.width, previewSize.height);
}
//Method from Ketai project! Not mine! See below...
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);
}
}
}
}
You can calculate the elapsed time in onPreviewFrame(). For example:
boolean isFirstTime = true;
long startTime = 0;
PreviewCallback callback = new PreviewCallback() {
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
// TODO Auto-generated method stub
if (isFirstTime) {
isFirstTime = false;
startTime = SystemClock.currentThreadTimeMillis();
decodeYUV420SP(pixels, data, previewSize.width, previewSize.height);
listener.OnPreviewUpdated(pixels, previewSize.width, previewSize.height);
}
else {
long currentTime = SystemClock.currentThreadTimeMillis();
long elapsedTime = currentTime - startTime;
if (elapsedTime >= 500) { // trigger your event
startTime = currentTime;
decodeYUV420SP(pixels, data, previewSize.width, previewSize.height);
listener.OnPreviewUpdated(pixels, previewSize.width, previewSize.height);
}
}
}
};
Do not forget to reset the boolean value and start time when you switch the preview status.
这篇关于如何让每一个500毫秒后摄像头preVIEW框架的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!