网上很多关于UVCcamera集成的Demo,也封装的非常简单,参考:github地址:https://github.com/Liuguihong/AndroidUVCCamera
public class UvcCameraReader implements ICameraReader
{
int width = 1280;
int height = 720;
private int imageRotation = 0;
private boolean opened = false;
private int imageFormat = 0;
private String TAG = "USBcamera";
private String _saveFullPath = null;
private TextureView mTextureView;
private SurfaceView mSurfaceView;
private UVCCameraProxy mUVCCamera = null;
private boolean isFirst = true;
private String path1;
private Activity mHost;
private byte[] lastImg;
private int debugReadCount = 0;
private long debugReadDiffTime = 0;
private long lastReadOkTime = 0;
private byte[][] planeData = new byte[1][];
private int[] planeRowStride = new int[1];
private int[] planePixelStride = new int[1];
HandlerThread mThreadHandler;
public UvcCameraReader() {
// manager = (CameraManager) MapApplication.getApplication().getSystemService(Context.CAMERA_SERVICE);
// Log.e("camera", "ARCameraEngine manager: " + manager);
// mThreadHandler = new HandlerThread("CameraHandler");
// mThreadHandler.start();
// handler = new Handler(mThreadHandler.getLooper());
mTextureView = new TextureView();
init_private();
}
private Size previewSize;
@Override
public boolean open(int id, int mwidth, int mheight, int imageFormat) {
Log.e(TAG, "open");
// mUVCCamera.startPreview();
List<Size> sizeList = new ArrayList<>();
if (mUVCCamera != null)
{
List<Size> list = mUVCCamera.getSupportedPreviewSizes();
for (Size size : list)
{
if (mwidth > mheight)
{
if (size.width >= mwidth && size.height >= mheight)
{
sizeList.add(size);
}
}else {
if (size.width >= mheight && size.height >= mwidth)
{
sizeList.add(size);
}
}
}
}
if (sizeList.isEmpty()) {
Log.e("camera", "USBCameraReader getSupportedPreviewSizes empty! ");
return false;
}
previewSize = Collections.min(sizeList, new Comparator<Size>() {
@Override
public int compare(Size lhs, Size rhs) {
return Long.signum(lhs.width * lhs.height - rhs.width * rhs.height);
}
});
Log.d("camera", "USBCameraReader open previewSize: " + previewSize.width + "*"+previewSize.height);
width = previewSize.width;
height = previewSize.height;
Log.d("camera", "USBCameraReader open previewSize: " + previewSize.width + "*"+previewSize.height);
mUVCCamera.stopPreview();
mUVCCamera.setPreviewSize(width, height);
mUVCCamera.startPreview();
opened = true;
return true;
}
@Override
public boolean close(int id) {
Log.e(TAG, "close");
// mUVCCamera.stopPreview();
return true;
}
@Override
public boolean isOpened() {
return isFirst;
}
@Override
public void release() {
mUVCCamera.unregisterReceiver();
mUVCCamera.closeDevice();
}
int i = 0;
@Override
public boolean read() {
Log.e(TAG, "read");
//
byte[] curImg;
Log.e(TAG, String.format("usbReader read begin"));
long startTime = System.currentTimeMillis();
{
synchronized (this) {
if (lastImg == null) {
Log.e(TAG, "lastImg = " + lastImg);
return false;
}
curImg = lastImg;
lastImg = null;
}
}
planeData[0] = curImg;
planePixelStride[0] = 1;
planeRowStride[0] = width;
Log.e(TAG, "width = " + width);
String savePath;
{
savePath = _saveFullPath;
_saveFullPath = null;
}
final int format = ImageFormat.NV21;
Log.e(TAG, "parseImage = " + height);
boolean value = this.engine.parseImage(0, format, width, height, height, 0, 0, width
, planeData, planePixelStride, planeRowStride, savePath, GLMapStaticValue.CAMERA_PREVIEW_MULTI_UI);
debugReadCount++;
long endTime = System.currentTimeMillis();
debugReadDiffTime += endTime - startTime;
// Log.e(TAG, String.format("usbCameraReader read w:%d,h:%d,f:%d count:%d, diffTime:%d, avgTime:%d, readOkInterval:%d"
// , previewSize.width, previewSize.height, format, debugReadCount, (endTime - startTime), debugReadDiffTime / debugReadCount, (endTime - lastReadOkTime)));
lastReadOkTime = endTime;
return true;
}
public void saveyuv2jpg(byte[] yuv, String path)
{
YuvImage yuvImage = new YuvImage(yuv, ImageFormat.NV21, width, height, null);
ByteArrayOutputStream bos = new ByteArrayOutputStream(yuv.length);
boolean result = yuvImage.compressToJpeg(new Rect(0, 0, width, height), 100, bos);
if (!result) {
return;
}
byte[] buffer = bos.toByteArray();
Bitmap bmp = BitmapFactory.decodeByteArray(buffer, 0, buffer.length);
// File file = new File("/mnt/sdcard/ae8test/1.jpg");
File file = new File(path);
if (file.exists()) {
file.delete();
}
try {
FileOutputStream fileOutputStream = new FileOutputStream(file);
bmp.compress(Bitmap.CompressFormat.PNG, 100, ((OutputStream) fileOutputStream));//设置PNG的话,透明区域不会变成黑色
fileOutputStream.close();
System.out.println("----------save success-------------------");
} catch (Exception v0) {
v0.printStackTrace();
}
}
protected void init_private() {
mTextureView = ARCameraEngine.mView;
// previewSize.width = 640;
// previewSize.height = 480;
Log.e(TAG, "mTextureView begin mTextureView: " + mTextureView);
//init usb
Log.e(TAG, "init usb begin");
mHost = ARCameraEngine.mActivity;
if (mHost == null)
{
Log.e(TAG, "mHost = null;");
// return false;
}
if (mUVCCamera == null) {
mUVCCamera = new UVCCameraProxy(ARCameraEngine.mContext);
}
Log.e(TAG, "mTextureView begin mUVCCamera: " + mUVCCamera);
mUVCCamera.getConfig()
.isDebug(true) // 是否调试
.setPicturePath(PicturePath.SDCARD) // 图片保存路径,保存在app缓存还是sd卡
.setDirName("uvccamera") // 图片保存目录名称
.setProductId(0) // 产品id,用于过滤设备,不需要可不设置
.setVendorId(0); // 供应商id,用于过滤设备,不需要可不设置
mUVCCamera.setConnectCallback(new ConnectCallback() {
@Override
public void onAttached(UsbDevice usbDevice) {
Log.e(TAG, " onAttached");
mUVCCamera.requestPermission(usbDevice);
}
@Override
public void onGranted(UsbDevice usbDevice, boolean granted) {
//if (granted)
{
Log.e(TAG, " onGranted");
mUVCCamera.connectDevice(usbDevice);
}
}
@Override
public void onConnected(UsbDevice usbDevice)
{
Log.e(TAG, " onConnected");
mUVCCamera.openCamera();
}
@Override
public void onCameraOpened() {
showAllPreviewSizes();
mUVCCamera.setPreviewSize(width, height);
mUVCCamera.startPreview();
GLMapStaticValue.SUPPORT_USB_CAMERA = true;
try {
int viewWidth = mTextureView.getWidth();
int viewHeight = mTextureView.getHeight();
//
// Log.e(TAG, " change viewWidth = " + viewWidth);
// Log.e(TAG, " change viewHeight = " + viewHeight);
android.util.Size previewSize = new android.util.Size(width, height);
// Log.e(TAG, " change imgaeWidth = " + width);
// Log.e(TAG, " change imgaeHeght = " + height);
Matrix matrix = new Matrix();
RectF viewRect = new RectF(0, 0, viewWidth, viewHeight);
RectF bufferRect = new RectF(0, 0, previewSize.getWidth(), previewSize.getHeight());
float centerX = viewRect.centerX();
float centerY = viewRect.centerY();
if (true) {
bufferRect.offset(centerX - bufferRect.centerX(), centerY - bufferRect.centerY());
matrix.setRectToRect(viewRect, bufferRect, Matrix.ScaleToFit.FILL);
float scale = Math.max(
(float) viewHeight / previewSize.getHeight(),
(float) viewWidth / previewSize.getWidth());
// Log.e(TAG, " change scale = " + scale);
// Log.e(TAG, " change centerX = " + centerX);
// Log.e(TAG, " change centerY = " + centerY);
matrix.postScale(scale, scale, centerX, centerY);
}
// matrix.postRotate(360, centerX, centerY);
mTextureView.setTransform(matrix);
} catch (Throwable e) {
e.printStackTrace();
}
}
@Override
public void onDetached(UsbDevice usbDevice) {
mUVCCamera.closeCamera();
}
});
mUVCCamera.setPreviewTexture(mTextureView);
// mUVCCamera.setPreviewSurface(mSurfaceView);
// mUVCCamera.registerReceiver();
// List<Size> list = mUVCCamera.getSupportedPreviewSizes();
// if (!list.isEmpty()) {
// mUVCCamera.setPreviewSize(640, 480);
// mUVCCamera.startPreview();
// }
Log.e(TAG, " mUVCCamera.setPreviewTexture(mTextureView)");
mUVCCamera.setPhotographCallback(new PhotographCallback() {
@Override
public void onPhotographClick() {
mUVCCamera.takePicture();
// mUVCCamera.takePicture("test.jpg");
}
});
mUVCCamera.setPreviewCallback(new PreviewCallback() {
@Override
public void onPreviewFrame(byte[] yuv) {
Log.e(TAG, " onPreviewFrame");
synchronized (this) {
lastImg = yuv;
// saveyuv2jpg(yuv, "/mnt/sdcard/ae8test/1.jpg");
}
}
});
mUVCCamera.setPictureTakenCallback(new PictureCallback() {
@Override
public void onPictureTaken(String path) {
path1 = path;
}
});
mUVCCamera.startPreview();
}
@Override
public boolean init(ARCameraEngine engine) {
Log.e(TAG, "init begin");
this.engine = engine;
//init view
return true;
}
private void showAllPreviewSizes() {
isFirst = true;
// List<Size> previewList = mUVCCamera.getSupportedPreviewSizes();
// List<String> previewStrs = new ArrayList<>();
// for (Size size : previewList) {
// previewStrs.add(size.width + " * " + size.height);
// }
// ArrayAdapter adapter = new ArrayAdapter(mHost, android.R.layout.simple_spinner_item, previewStrs);
// adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
// mSpinner.setAdapter(adapter);
}
@Override
public void savaTo(String path) {
synchronized (this) {
_saveFullPath = path;
}
}
CameraPreviewClient mPreviewClient;
@Override
public void addPreviewClient(CameraPreviewClient previewClient) {
mPreviewClient = previewClient;
Log.e(TAG, "addPreviewClient begin");
}
}