android4.0 USB Camera实例(三)UVC

android4.0 USB Camera实例(三)UVC

https://blog.****.net/hclydao/article/details/30258241

下面顺便把通用的USB也写上 前面的ZC301获取到的格式是JPEG的所以不用进行什么处理就可以用来显示,但是标准的UVC获取到的是YUV422格式的需要转换成RGB后才能进行显示 这里我们在前面两篇的代码稍作修改就可以了

HAL层 代码如下

 

 
  1. /*

  2. * Android USB Camera zc3xx Library

  3. *

  4. * Copyright (c) 2014 Store information technology guangzhou ltd<http://www.storeinf.com>

  5. * Copyright (c) 2014 hclydao <[email protected]>

  6. *

  7. * This program is free software; you can redistribute it and/or modify

  8. * it under the terms of the GNU General Public License as published by

  9. * the Free Software Foundation; either version 2 of the License.

  10. */

  11. #include <errno.h>

  12. #include <sys/types.h>

  13. #include <sys/stat.h>

  14. #include <fcntl.h>

  15. #include <sys/ioctl.h>

  16. #include <unistd.h>

  17. #include <stdint.h>

  18. #include <stdio.h>

  19. #include <stdlib.h>

  20. #include <asm/types.h>

  21. #include <linux/videodev2.h>

  22. #include <sys/mman.h>

  23. #include <string.h>

  24. #include <malloc.h>

  25. #include <linux/fb.h>

  26. #include <jni.h>

  27. #include <string.h>

  28. #include <android/log.h>

  29. #include <syslog.h>

  30. #include <android/log.h>

  31. #include <android/bitmap.h>

  32.  
  33. #define LOG_TAG "FimcGzsd"

  34. #define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__)

  35. #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG , LOG_TAG, __VA_ARGS__)

  36. #define LOGI(...) __android_log_print(ANDROID_LOG_INFO , LOG_TAG, __VA_ARGS__)

  37. #define LOGW(...) __android_log_print(ANDROID_LOG_WARN , LOG_TAG, __VA_ARGS__)

  38. #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR , LOG_TAG, __VA_ARGS__)

  39.  
  40. struct fimc_buffer {

  41. unsigned char *start;

  42. size_t length;

  43. };

  44.  
  45. static int fd = -1;

  46. struct fimc_buffer *buffers=NULL;

  47. struct v4l2_buffer v4l2_buf;

  48. static int bufnum = 1;

  49. static int mwidth,mheight;

  50. static int c_type = 0;

  51.  
  52. int *rgb = NULL;

  53. int *ybuf = NULL;

  54.  
  55. int yuv_tbl_ready=0;

  56. int y1192_tbl[256];

  57. int v1634_tbl[256];

  58. int v833_tbl[256];

  59. int u400_tbl[256];

  60. int u2066_tbl[256];

  61. /*

  62. *open usb camera device

  63. */

  64. JNIEXPORT jint JNICALL Java_com_dao_usbcam_Fimcgzsd_open(JNIEnv * env, jclass obj, const jbyteArray devname)

  65. {

  66. jbyte *dev = (jbyte*)(*env)->GetByteArrayElements(env, devname, 0);

  67. fd = open(dev, O_RDWR, 0);

  68. if (fd<0)

  69. {

  70. LOGE("%s ++++ open error\n",dev);

  71. return -1;

  72. }

  73. (*env)->ReleaseByteArrayElements(env, devname, dev, 0);

  74. return fd;

  75. }

  76. /*

  77. * init device

  78. */

  79. JNIEXPORT jint JNICALL Java_com_dao_usbcam_Fimcgzsd_init(JNIEnv * env, jclass obj, jint width, jint height,jint numbuf,jint ctype)

  80. {

  81. int ret;

  82. int i;

  83. bufnum = numbuf;

  84. mwidth = width;

  85. mheight = height;

  86. c_type = ctype;

  87. struct v4l2_format fmt;

  88. struct v4l2_capability cap;

  89.  
  90. ret = ioctl(fd, VIDIOC_QUERYCAP, &cap);

  91. if (ret < 0) {

  92. LOGE("%d :VIDIOC_QUERYCAP failed\n",__LINE__);

  93. return -1;

  94. }

  95. if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {

  96. LOGE("%d : no capture devices\n",__LINE__);

  97. return -1;

  98. }

  99.  
  100. memset( &fmt, 0, sizeof(fmt));

  101. fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

  102. if(c_type == 1)

  103. fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;

  104. else

  105. fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_RGB565;

  106. fmt.fmt.pix.width = width;

  107. fmt.fmt.pix.height = height;

  108. if (ioctl(fd, VIDIOC_S_FMT, &fmt) < 0)

  109. {

  110. LOGE("++++%d : set format failed\n",__LINE__);

  111. return -1;

  112. }

  113.  
  114. struct v4l2_requestbuffers req;

  115. req.count = numbuf;

  116. req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

  117. req.memory = V4L2_MEMORY_MMAP;

  118.  
  119. ret = ioctl(fd, VIDIOC_REQBUFS, &req);

  120. if (ret < 0) {

  121. LOGE("++++%d : VIDIOC_REQBUFS failed\n",__LINE__);

  122. return -1;

  123. }

  124.  
  125. buffers = calloc(req.count, sizeof(*buffers));

  126. if (!buffers) {

  127. LOGE ("++++%d Out of memory\n",__LINE__);

  128. return -1;

  129. }

  130.  
  131. for(i = 0; i< bufnum; ++i) {

  132. memset(&v4l2_buf, 0, sizeof(v4l2_buf));

  133. v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

  134. v4l2_buf.memory = V4L2_MEMORY_MMAP;

  135. v4l2_buf.index = i;

  136. ret = ioctl(fd , VIDIOC_QUERYBUF, &v4l2_buf);

  137. if(ret < 0) {

  138. LOGE("+++%d : VIDIOC_QUERYBUF failed\n",__LINE__);

  139. return -1;

  140. }

  141. buffers[i].length = v4l2_buf.length;

  142. if ((buffers[i].start = (char *)mmap(0, v4l2_buf.length,

  143. PROT_READ | PROT_WRITE, MAP_SHARED,

  144. fd, v4l2_buf.m.offset)) < 0) {

  145. LOGE("%d : mmap() failed",__LINE__);

  146. return -1;

  147. }

  148. }

  149. rgb = (int *)malloc(sizeof(int) * (mwidth*mheight));

  150. ybuf = (int *)malloc(sizeof(int) * (mwidth*mheight));

  151. return 0;

  152. }

  153. /*

  154. *open usb camera device

  155. */

  156. JNIEXPORT jint JNICALL Java_com_dao_usbcam_Fimcgzsd_streamon(JNIEnv * env, jclass obj)

  157. {

  158. int i;

  159. int ret;

  160. enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

  161. for(i = 0; i< bufnum; ++i) {

  162. memset(&v4l2_buf, 0, sizeof(v4l2_buf));

  163. v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

  164. v4l2_buf.memory = V4L2_MEMORY_MMAP;

  165. v4l2_buf.index = i;

  166. ret = ioctl(fd, VIDIOC_QBUF, &v4l2_buf);

  167. if (ret < 0) {

  168. LOGE("%d : VIDIOC_QBUF failed\n",__LINE__);

  169. return ret;

  170. }

  171. }

  172. ret = ioctl(fd, VIDIOC_STREAMON, &type);

  173. if (ret < 0) {

  174. LOGE("%d : VIDIOC_STREAMON failed\n",__LINE__);

  175. return ret;

  176. }

  177. return 0;

  178. }

  179.  
  180. void yuyv422toABGRY(unsigned char *src)

  181. {

  182.  
  183. int width=0;

  184. int height=0;

  185.  
  186. width = mwidth;

  187. height = mheight;

  188.  
  189. int frameSize =width*height*2;

  190.  
  191. int i;

  192.  
  193. if((!rgb || !ybuf)){

  194. return;

  195. }

  196. int *lrgb = NULL;

  197. int *lybuf = NULL;

  198.  
  199. lrgb = &rgb[0];

  200. lybuf = &ybuf[0];

  201.  
  202. if(yuv_tbl_ready==0){

  203. for(i=0 ; i<256 ; i++){

  204. y1192_tbl[i] = 1192*(i-16);

  205. if(y1192_tbl[i]<0){

  206. y1192_tbl[i]=0;

  207. }

  208.  
  209. v1634_tbl[i] = 1634*(i-128);

  210. v833_tbl[i] = 833*(i-128);

  211. u400_tbl[i] = 400*(i-128);

  212. u2066_tbl[i] = 2066*(i-128);

  213. }

  214. yuv_tbl_ready=1;

  215. }

  216.  
  217. for(i=0 ; i<frameSize ; i+=4){

  218. unsigned char y1, y2, u, v;

  219. y1 = src[i];

  220. u = src[i+1];

  221. y2 = src[i+2];

  222. v = src[i+3];

  223.  
  224. int y1192_1=y1192_tbl[y1];

  225. int r1 = (y1192_1 + v1634_tbl[v])>>10;

  226. int g1 = (y1192_1 - v833_tbl[v] - u400_tbl[u])>>10;

  227. int b1 = (y1192_1 + u2066_tbl[u])>>10;

  228.  
  229. int y1192_2=y1192_tbl[y2];

  230. int r2 = (y1192_2 + v1634_tbl[v])>>10;

  231. int g2 = (y1192_2 - v833_tbl[v] - u400_tbl[u])>>10;

  232. int b2 = (y1192_2 + u2066_tbl[u])>>10;

  233.  
  234. r1 = r1>255 ? 255 : r1<0 ? 0 : r1;

  235. g1 = g1>255 ? 255 : g1<0 ? 0 : g1;

  236. b1 = b1>255 ? 255 : b1<0 ? 0 : b1;

  237. r2 = r2>255 ? 255 : r2<0 ? 0 : r2;

  238. g2 = g2>255 ? 255 : g2<0 ? 0 : g2;

  239. b2 = b2>255 ? 255 : b2<0 ? 0 : b2;

  240.  
  241. *lrgb++ = 0xff000000 | b1<<16 | g1<<8 | r1;

  242. *lrgb++ = 0xff000000 | b2<<16 | g2<<8 | r2;

  243.  
  244. if(lybuf!=NULL){

  245. *lybuf++ = y1;

  246. *lybuf++ = y2;

  247. }

  248. }

  249.  
  250. }

  251.  
  252. void

  253. Java_com_dao_usbcam_Fimcgzsd_pixeltobmp( JNIEnv* env,jobject thiz,jobject bitmap){

  254.  
  255. jboolean bo;

  256.  
  257.  
  258. AndroidBitmapInfo info;

  259. void* pixels;

  260. int ret;

  261. int i;

  262. int *colors;

  263.  
  264. int width=0;

  265. int height=0;

  266.  
  267. if ((ret = AndroidBitmap_getInfo(env, bitmap, &info)) < 0) {

  268. LOGE("AndroidBitmap_getInfo() failed ! error=%d", ret);

  269. return;

  270. }

  271.  
  272. width = info.width;

  273. height = info.height;

  274.  
  275. if(!rgb || !ybuf) return;

  276.  
  277. if (info.format != ANDROID_BITMAP_FORMAT_RGBA_8888) {

  278. LOGE("Bitmap format is not RGBA_8888 !");

  279. return;

  280. }

  281.  
  282. if ((ret = AndroidBitmap_lockPixels(env, bitmap, &pixels)) < 0) {

  283. LOGE("AndroidBitmap_lockPixels() failed ! error=%d", ret);

  284. }

  285.  
  286. colors = (int*)pixels;

  287. int *lrgb =NULL;

  288. lrgb = &rgb[0];

  289.  
  290. for(i=0 ; i<width*height ; i++){

  291. *colors++ = *lrgb++;

  292. }

  293.  
  294. AndroidBitmap_unlockPixels(env, bitmap);

  295.  
  296. }

  297.  
  298. void yuyv422torgb(unsigned char *src,unsigned int *mrgb)

  299. {

  300.  
  301. int width=0;

  302. int height=0;

  303.  
  304. width = mwidth;

  305. height = mheight;

  306.  
  307. int frameSize =width*height*2;

  308.  
  309. int i;

  310.  
  311. if((!rgb || !ybuf)){

  312. return;

  313. }

  314. int *lrgb = NULL;

  315. int *lybuf = NULL;

  316.  
  317. lrgb = mrgb;

  318. lybuf = &ybuf[0];

  319.  
  320. if(yuv_tbl_ready==0){

  321. for(i=0 ; i<256 ; i++){

  322. y1192_tbl[i] = 1192*(i-16);

  323. if(y1192_tbl[i]<0){

  324. y1192_tbl[i]=0;

  325. }

  326.  
  327. v1634_tbl[i] = 1634*(i-128);

  328. v833_tbl[i] = 833*(i-128);

  329. u400_tbl[i] = 400*(i-128);

  330. u2066_tbl[i] = 2066*(i-128);

  331. }

  332. yuv_tbl_ready=1;

  333. }

  334.  
  335. for(i=0 ; i<frameSize ; i+=4){

  336. unsigned char y1, y2, u, v;

  337. y1 = src[i];

  338. u = src[i+1];

  339. y2 = src[i+2];

  340. v = src[i+3];

  341.  
  342. int y1192_1=y1192_tbl[y1];

  343. int r1 = (y1192_1 + v1634_tbl[v])>>10;

  344. int g1 = (y1192_1 - v833_tbl[v] - u400_tbl[u])>>10;

  345. int b1 = (y1192_1 + u2066_tbl[u])>>10;

  346.  
  347. int y1192_2=y1192_tbl[y2];

  348. int r2 = (y1192_2 + v1634_tbl[v])>>10;

  349. int g2 = (y1192_2 - v833_tbl[v] - u400_tbl[u])>>10;

  350. int b2 = (y1192_2 + u2066_tbl[u])>>10;

  351.  
  352. r1 = r1>255 ? 255 : r1<0 ? 0 : r1;

  353. g1 = g1>255 ? 255 : g1<0 ? 0 : g1;

  354. b1 = b1>255 ? 255 : b1<0 ? 0 : b1;

  355. r2 = r2>255 ? 255 : r2<0 ? 0 : r2;

  356. g2 = g2>255 ? 255 : g2<0 ? 0 : g2;

  357. b2 = b2>255 ? 255 : b2<0 ? 0 : b2;

  358.  
  359. *lrgb++ = 0xff000000 | b1<<16 | g1<<8 | r1;

  360. *lrgb++ = 0xff000000 | b2<<16 | g2<<8 | r2;

  361.  
  362. if(lybuf!=NULL){

  363. *lybuf++ = y1;

  364. *lybuf++ = y2;

  365. }

  366. }

  367.  
  368. }

  369.  
  370. JNIEXPORT jint JNICALL Java_com_dao_usbcam_Fimcgzsd_yuvtorgb(JNIEnv * env, jclass obj,const jbyteArray yuvdata, jintArray rgbdata)

  371. {

  372. jbyte *ydata = (jbyte*)(*env)->GetByteArrayElements(env, yuvdata, 0);

  373. jint *rdata = (jint*)(*env)->GetIntArrayElements(env, rgbdata, 0);

  374. yuyv422torgb(ydata,rdata);

  375. (*env)->ReleaseByteArrayElements(env, yuvdata, ydata, 0);

  376. (*env)->ReleaseIntArrayElements(env, rgbdata, rdata, 0);

  377. return 0;

  378. }

  379. /*

  380. *get one frame data

  381. */

  382. JNIEXPORT jint JNICALL Java_com_dao_usbcam_Fimcgzsd_dqbuf(JNIEnv * env, jclass obj,const jbyteArray videodata)

  383. {

  384. int ret;

  385.  
  386. jbyte *data = (jbyte*)(*env)->GetByteArrayElements(env, videodata, 0);

  387. v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

  388. v4l2_buf.memory = V4L2_MEMORY_MMAP;

  389.  
  390. ret = ioctl(fd, VIDIOC_DQBUF, &v4l2_buf);

  391. if (ret < 0) {

  392. LOGE("%s : VIDIOC_DQBUF failed, dropped frame\n",__func__);

  393. return ret;

  394. }

  395. if(c_type == 1)

  396. yuyv422toABGRY((unsigned char *)buffers[v4l2_buf.index].start);

  397. memcpy(data,buffers[v4l2_buf.index].start,buffers[v4l2_buf.index].length);

  398. (*env)->ReleaseByteArrayElements(env, videodata, data, 0);

  399. return v4l2_buf.index;

  400. }

  401. /*

  402. *put in frame buffer to queue

  403. */

  404. JNIEXPORT jint JNICALL Java_com_dao_usbcam_Fimcgzsd_qbuf(JNIEnv * env, jclass obj,jint index)

  405. {

  406. int ret;

  407.  
  408. v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

  409. v4l2_buf.memory = V4L2_MEMORY_MMAP;

  410. v4l2_buf.index = index;

  411.  
  412. ret = ioctl(fd, VIDIOC_QBUF, &v4l2_buf);

  413. if (ret < 0) {

  414. LOGE("%s : VIDIOC_QBUF failed\n",__func__);

  415. return ret;

  416. }

  417.  
  418. return 0;

  419. }

  420. /*

  421. *streamoff

  422. */

  423. JNIEXPORT jint JNICALL Java_com_dao_usbcam_Fimcgzsd_streamoff(JNIEnv * env, jclass obj,jint index)

  424. {

  425. enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

  426. int ret;

  427.  
  428. ret = ioctl(fd, VIDIOC_STREAMOFF, &type);

  429. if (ret < 0) {

  430. LOGE("%s : VIDIOC_STREAMOFF failed\n",__func__);

  431. return ret;

  432. }

  433.  
  434. return 0;

  435. }

  436. /*

  437. *release

  438. */

  439. JNIEXPORT jint JNICALL Java_com_dao_usbcam_Fimcgzsd_release(JNIEnv * env, jclass obj)

  440. {

  441. enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

  442. int ret;

  443. int i;

  444.  
  445. ret = ioctl(fd, VIDIOC_STREAMOFF, &type);

  446. if (ret < 0) {

  447. LOGE("%s : VIDIOC_STREAMOFF failed\n",__func__);

  448. return ret;

  449. }

  450.  
  451. for (i = 0; i < bufnum; i++) {

  452. ret = munmap(buffers[i].start, buffers[i].length);

  453. if (ret < 0) {

  454. LOGE("%s : munmap failed\n",__func__);

  455. return ret;

  456. }

  457. }

  458. free (buffers);

  459. if(rgb) free(rgb);

  460. if(ybuf) free(ybuf);

  461. close(fd);

  462. return 0;

  463. }

主要增加了两个函数

 

yuyv422toABGRY 这个是yuv转rgb

Java_com_dao_usbcam_Fimcgzsd_pixeltobmp 这个是rgb转bitmap

这两个函数是我在网上找到例子simplewebcam里拷出来的

同时Android.mk修改如下

 

 
  1. LOCAL_PATH := $(call my-dir)

  2.  
  3. include $(CLEAR_VARS)

  4. LOCAL_MODULE := fimcgzsd

  5. LOCAL_SRC_FILES := fimcgzsd.c

  6. LOCAL_LDLIBS := -llog -ljnigraphics

  7. include $(BUILD_SHARED_LIBRARY)

增加了一个Application.mk

 

 

 
  1. # The ARMv7 is significanly faster due to the use of the hardware FPU

  2. APP_ABI := armeabi armeabi-v7a

  3. APP_PLATFORM := android-8

这样在终端进入工程所有目录直接执行ndk-build(环境变量已经设置)即可生成动态库

 

应用层

增加一个c_type指定是zc301还是uvc 我还是把代码贴上来吧

 

 
  1. package com.dao.usbcam;

  2.  
  3. import java.io.ByteArrayOutputStream;

  4. import java.io.File;

  5. import java.io.FileNotFoundException;

  6. import java.io.FileOutputStream;

  7. import java.io.IOException;

  8.  
  9. import android.app.Activity;

  10. import android.graphics.Bitmap;

  11. import android.graphics.BitmapFactory;

  12. import android.graphics.ImageFormat;

  13. import android.graphics.Rect;

  14. import android.graphics.YuvImage;

  15. import android.os.Bundle;

  16. import android.os.Environment;

  17. import android.os.Handler;

  18. import android.text.format.Time;

  19. import android.view.Menu;

  20. import android.view.View;

  21. import android.view.View.OnClickListener;

  22. import android.view.Window;

  23. import android.view.WindowManager;

  24. import android.widget.Button;

  25. import android.widget.ImageView;

  26. import android.widget.Toast;

  27.  
  28. public class MainActivity extends Activity {

  29. private ImageView mImag;

  30. private int width = 320;

  31. private int height = 240;

  32. private String devname = "/dev/video3";

  33. private byte[] mdata;

  34. private Handler mHandler;

  35. private int numbuf = 0;

  36. private int index = 0;

  37. private int ret = 0;

  38. private int ctype = 1;//0 is zc301 1 is uvc camera

  39. public Button mcap;

  40. private Bitmap bitmap;

  41. private Bitmap bmp;

  42. private int[] rgb;

  43. @Override

  44. protected void onCreate(Bundle savedInstanceState) {

  45. super.onCreate(savedInstanceState);

  46. requestWindowFeature(Window.FEATURE_NO_TITLE);

  47. getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,

  48. WindowManager.LayoutParams.FLAG_FULLSCREEN);

  49. setContentView(R.layout.activity_main);

  50. mImag = (ImageView)findViewById(R.id.mimg);

  51. mcap = (Button)findViewById(R.id.mcap);

  52. bmp = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);

  53. numbuf = 4;

  54. mdata = new byte[width * height * numbuf];

  55. rgb = new int[width * height * numbuf];

  56. ret = Fimcgzsd.open(devname.getBytes());

  57. if(ret < 0)

  58. finish();

  59. ret = Fimcgzsd.init(width, height, numbuf,ctype);

  60. if(ret < 0)

  61. finish();

  62. ret = Fimcgzsd.streamon();

  63. if(ret < 0)

  64. finish();

  65. mHandler = new Handler();

  66. new StartThread().start();

  67. mcap.setOnClickListener(new CaptureListener());

  68. }

  69.  
  70. final Runnable mUpdateUI = new Runnable() {

  71.  
  72. @Override

  73. public void run() {

  74. // TODO Auto-generated method stub

  75. mImag.setImageBitmap(bitmap);

  76.  
  77. }

  78. };

  79.  
  80. class StartThread extends Thread {

  81.  
  82. @Override

  83. public void run() {

  84. // TODO Auto-generated method stub

  85. //super.run();

  86. while(true) {

  87. if(ctype == 1){

  88. index = Fimcgzsd.dqbuf(mdata);

  89. if((index < 0) || (mdata == null)) {

  90. onDestroy();

  91. break;

  92. }

  93. Fimcgzsd.pixeltobmp(bmp);

  94. mHandler.post(mUpdateUI);

  95. bitmap = bmp;

  96. Fimcgzsd.qbuf(index);

  97. //Fimcgzsd.yuvtorgb(mdata, rgb);

  98. //mHandler.post(mUpdateUI);

  99. //bitmap = Bitmap.createBitmap(rgb,width,height,Bitmap.Config.ARGB_8888);

  100. //Fimcgzsd.qbuf(index);

  101. } else {

  102. index = Fimcgzsd.dqbuf(mdata);

  103. if(index < 0) {

  104. onDestroy();

  105. break;

  106. }

  107. mHandler.post(mUpdateUI);

  108. bitmap = BitmapFactory.decodeByteArray(mdata, 0, width * height);

  109. Fimcgzsd.qbuf(index);

  110. }

  111. }

  112. }

  113. }

  114.  
  115. public static void saveMyBitmap(Bitmap mBitmap) {

  116. Time mtime = new Time();

  117. mtime.setToNow();

  118. File fdir = new File(Environment.getExternalStorageDirectory().getPath() + "/DCIM/" + "/gzsd/");

  119. if(!fdir.exists()) {

  120. fdir.mkdir();

  121. }

  122. File f = new File(Environment.getExternalStorageDirectory().getPath() + "/DCIM/" + "/gzsd/" + mtime.year + mtime.month + mtime.monthDay + mtime.hour + mtime.minute +mtime.second+".png");

  123. try {

  124. f.createNewFile();

  125. } catch (IOException e) {

  126. e.printStackTrace();

  127. }

  128. FileOutputStream fOut = null;

  129. try {

  130. fOut = new FileOutputStream(f);

  131. mBitmap.compress(Bitmap.CompressFormat.PNG, 100, fOut);

  132. fOut.flush();

  133. fOut.close();

  134. } catch (FileNotFoundException e) {

  135. e.printStackTrace();

  136. } catch (IOException e) {

  137. e.printStackTrace();

  138. }

  139.  
  140. }

  141.  
  142. class CaptureListener implements OnClickListener{

  143.  
  144. @Override

  145. public void onClick(View v) {

  146. // TODO Auto-generated method stub

  147. //new CapThread().start();

  148. //Fimcgzsd.streamoff();

  149. saveMyBitmap(bitmap);

  150. //Fimcgzsd.streamon();

  151. Toast.makeText(MainActivity.this, "Capture Successfully", Toast.LENGTH_SHORT).show();

  152. }

  153. }

  154.  
  155. class CapThread extends Thread {

  156.  
  157. @Override

  158. public void run() {

  159. // TODO Auto-generated method stub

  160. //super.run();

  161. saveMyBitmap(bitmap);

  162. Toast.makeText(MainActivity.this, "Capture Successfully", Toast.LENGTH_LONG).show();

  163. }

  164.  
  165. }

  166.  
  167. @Override

  168. protected void onStop() {

  169. // TODO Auto-generated method stub

  170. super.onStop();

  171. Fimcgzsd.release();

  172. finish();

  173. }

  174.  
  175. @Override

  176. protected void onPause() {

  177. // TODO Auto-generated method stub

  178. super.onPause();

  179. Fimcgzsd.release();

  180. finish();

  181. }

  182.  
  183. @Override

  184. protected void onDestroy() {

  185. // TODO Auto-generated method stub

  186. super.onDestroy();

  187. Fimcgzsd.release();

  188. }

  189.  
  190. @Override

  191. public boolean onCreateOptionsMenu(Menu menu) {

  192. // Inflate the menu; this adds items to the action bar if it is present.

  193. getMenuInflater().inflate(R.menu.main, menu);

  194. finish();

  195. return true;

  196. }

  197.  
  198. }

原理什么的我前面已经简单的进行了说明这里 我就不说了 具体效果如下

 

android4.0 USB Camera实例(三)UVC