diff --git a/app/src/main/java/com/jiangdg/usbcamera/view/USBCameraActivity.java b/app/src/main/java/com/jiangdg/usbcamera/view/USBCameraActivity.java index 4c8ec11..5f2bd32 100644 --- a/app/src/main/java/com/jiangdg/usbcamera/view/USBCameraActivity.java +++ b/app/src/main/java/com/jiangdg/usbcamera/view/USBCameraActivity.java @@ -107,13 +107,15 @@ public class USBCameraActivity extends AppCompatActivity implements CameraDialog @Override public void run() { try { - Thread.sleep(1500); + Thread.sleep(2500); } catch (InterruptedException e) { e.printStackTrace(); } Looper.prepare(); - mSeekBrightness.setProgress(mCameraHelper.getModelValue(UVCCameraHelper.MODE_BRIGHTNESS)); - mSeekContrast.setProgress(mCameraHelper.getModelValue(UVCCameraHelper.MODE_CONTRAST)); + if(mCameraHelper != null && mCameraHelper.isCameraOpened()) { + mSeekBrightness.setProgress(mCameraHelper.getModelValue(UVCCameraHelper.MODE_BRIGHTNESS)); + mSeekContrast.setProgress(mCameraHelper.getModelValue(UVCCameraHelper.MODE_CONTRAST)); + } Looper.loop(); } }).start(); @@ -223,11 +225,11 @@ public class USBCameraActivity extends AppCompatActivity implements CameraDialog return super.onOptionsItemSelected(item); } String picPath = UVCCameraHelper.ROOT_PATH + System.currentTimeMillis() - + UVCCameraHelper.SUFFIX_PNG; + + UVCCameraHelper.SUFFIX_JPEG; mCameraHelper.capturePicture(picPath, new AbstractUVCCameraHandler.OnCaptureListener() { @Override public void onCaptureResult(String path) { - showShortMsg("save path:" + path); + Log.i(TAG,"save path:" + path); } }); break; @@ -332,95 +334,6 @@ public class USBCameraActivity extends AppCompatActivity implements CameraDialog return resolutions; } - // @OnClick({R.id.btn_contrast, R.id.btn_brightness, R.id.btn_capture_pic, R.id.btn_rec_video, R.id.btn_update_resolution, R.id.btn_restart_camera}) -// public void onViewClick(View view) { -// int vId = view.getId(); -// switch (vId) { -// case R.id.btn_contrast: -// if (mUSBManager == null || !mUSBManager.isCameraOpened()) -// return; -// int contrast = mUSBManager.getModelValue(UVCCameraHelper.MODE_CONTRAST); -// mUSBManager.setModelValue(UVCCameraHelper.MODE_CONTRAST, contrast++); -// break; -// case R.id.btn_brightness: -// if (mUSBManager == null || !mUSBManager.isCameraOpened()) -// return; -// int brightness = mUSBManager.getModelValue(UVCCameraHelper.MODE_BRIGHTNESS); -// mUSBManager.setModelValue(UVCCameraHelper.MODE_BRIGHTNESS, brightness++); -// break; -// case R.id.btn_update_resolution: - -// break; -// case R.id.camera_view: -// if (mUSBManager == null) -// return; -//// mUSBManager.startCameraFoucs(); -//// showShortMsg("对焦相机"); -// List list = mUSBManager.getSupportedPreviewSizes(); -// if (list == null) { -// return; -// } -// -// StringBuilder sb = new StringBuilder(); -// for (Size size : list) { -// sb.append(size.width + "x" + size.height); -// sb.append("\n"); -// } -// showShortMsg(sb.toString()); -// break; -// case R.id.btn_capture_pic: -// if (mUSBManager == null || !mUSBManager.isCameraOpened()) { -// showShortMsg("抓拍异常,摄像头未开启"); -// return; -// } -// String picPath = UVCCameraHelper.ROOT_PATH + System.currentTimeMillis() -// + UVCCameraHelper.SUFFIX_PNG; -// mUSBManager.capturePicture(picPath, new AbstractUVCCameraHandler.OnCaptureListener() { -// @Override -// public void onCaptureResult(String path) { -// showShortMsg("保存路径:" + path); -// } -// }); -// break; -// case R.id.btn_rec_video: -// if (mUSBManager == null || !mUSBManager.isCameraOpened()) { -// showShortMsg("录制异常,摄像头未开启"); -// return; -// } -// -// if (!mUSBManager.isRecording()) { -// String videoPath = UVCCameraHelper.ROOT_PATH + System.currentTimeMillis(); -// FileUtils.createfile(FileUtils.ROOT_PATH + "test666.h264"); -// RecordParams params = new RecordParams(); -// params.setRecordPath(videoPath); -// params.setRecordDuration(0); // 设置为0,不分割保存 -// params.setVoiceClose(false); // 不屏蔽声音 -// mUSBManager.startRecording(params, new AbstractUVCCameraHandler.OnEncodeResultListener() { -// @Override -// public void onEncodeResult(byte[] data, int offset, int length, long timestamp, int type) { -// // type = 0,aac格式音频流 -// // type = 1,h264格式视频流 -// if (type == 1) { -// FileUtils.putFileStream(data, offset, length); -// } -// } -// -// @Override -// public void onRecordResult(String videoPath) { -// showShortMsg(videoPath); -// } -// }); -// -// mBtnRecord.setText("正在录制"); -// } else { -// FileUtils.releaseFile(); -// mUSBManager.stopRecording(); -// mBtnRecord.setText("开始录制"); -// } -// break; -// } -// } - @Override protected void onDestroy() { super.onDestroy(); diff --git a/libusbcamera/src/main/java/com/jiangdg/usbcamera/UVCCameraHelper.java b/libusbcamera/src/main/java/com/jiangdg/usbcamera/UVCCameraHelper.java index 8ed2578..7a08bd6 100644 --- a/libusbcamera/src/main/java/com/jiangdg/usbcamera/UVCCameraHelper.java +++ b/libusbcamera/src/main/java/com/jiangdg/usbcamera/UVCCameraHelper.java @@ -27,7 +27,7 @@ import java.util.List; public class UVCCameraHelper { public static final String ROOT_PATH = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator; - public static final String SUFFIX_PNG = ".png"; + public static final String SUFFIX_JPEG = ".jpg"; public static final String SUFFIX_MP4 = ".mp4"; private static final String TAG = "UVCCameraHelper"; private int previewWidth = 640; diff --git a/libusbcamera/src/main/java/com/serenegiant/usb/common/AbstractUVCCameraHandler.java b/libusbcamera/src/main/java/com/serenegiant/usb/common/AbstractUVCCameraHandler.java index 3daef2f..602a702 100644 --- a/libusbcamera/src/main/java/com/serenegiant/usb/common/AbstractUVCCameraHandler.java +++ b/libusbcamera/src/main/java/com/serenegiant/usb/common/AbstractUVCCameraHandler.java @@ -3,7 +3,11 @@ package com.serenegiant.usb.common; import android.annotation.TargetApi; import android.app.Activity; import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.ImageFormat; +import android.graphics.Rect; import android.graphics.SurfaceTexture; +import android.graphics.YuvImage; import android.hardware.usb.UsbDevice; import android.media.MediaScannerConnection; import android.os.Build; @@ -17,6 +21,7 @@ import android.view.Surface; import android.view.SurfaceHolder; import com.jiangdg.usbcamera.task.SaveYuvImageTask; +import com.jiangdg.usbcamera.utils.FileUtils; import com.jiangdg.usbcamera.utils.YUVBean; import com.serenegiant.usb.IFrameCallback; import com.serenegiant.usb.Size; @@ -34,7 +39,9 @@ import com.serenegiant.usb.encoder.biz.Mp4MediaMuxer; import com.serenegiant.usb.widget.CameraViewInterface; import java.io.BufferedOutputStream; +import java.io.ByteArrayOutputStream; import java.io.File; +import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.lang.ref.WeakReference; @@ -99,7 +106,7 @@ public abstract class AbstractUVCCameraHandler extends Handler { private final WeakReference mWeakThread; private volatile boolean mReleased; - protected boolean isCaptureStill; + protected static boolean isCaptureStill; protected AbstractUVCCameraHandler(final CameraThread thread) { mWeakThread = new WeakReference(thread); @@ -220,6 +227,7 @@ public abstract class AbstractUVCCameraHandler extends Handler { AbstractUVCCameraHandler.mCaptureListener = listener; checkReleased(); sendMessage(obtainMessage(MSG_CAPTURE_STILL, path)); + isCaptureStill = true; } // 开始录制 @@ -761,7 +769,7 @@ public abstract class AbstractUVCCameraHandler extends Handler { // isAudioThreadStart = false; } - private String picPath; + private String picPath = null; public void handleStillPicture(String picPath) { this.picPath = picPath; @@ -779,28 +787,23 @@ public abstract class AbstractUVCCameraHandler extends Handler { // videoEncoder.encode(frame); // } int len = frame.capacity(); - byte[] yuv = new byte[len]; + final byte[] yuv = new byte[len]; frame.get(yuv); // nv21 yuv data callback if(mPreviewListener != null) { mPreviewListener.onPreviewResult(yuv); } // 捕获图片 - if(! TextUtils.isEmpty(picPath)) { - picPath = null; - YUVBean bean = new YUVBean(); - bean.setYuvData(yuv); - bean.setPicPath(picPath); - bean.setWidth(mWidth); - bean.setHeight(mHeight); - new SaveYuvImageTask(bean, new SaveYuvImageTask.OnSaveYuvResultListener() { + if(isCaptureStill && ! TextUtils.isEmpty(picPath)) { + isCaptureStill = false; + new Thread(new Runnable() { @Override - public void onSaveResult(String savePath) { - if(mCaptureListener != null) { - mCaptureListener.onCaptureResult(savePath); - } + public void run() { + saveYuv2Jpeg(picPath,yuv); } - }).execute(); + }).start(); + + isCaptureStill = false; } // 视频 if(mH264Consumer != null){ @@ -810,6 +813,40 @@ public abstract class AbstractUVCCameraHandler extends Handler { } }; + private void saveYuv2Jpeg(String path,byte[] data){ + YuvImage yuvImage = new YuvImage(data, ImageFormat.NV21, mWidth, mHeight, null); + ByteArrayOutputStream bos = new ByteArrayOutputStream(data.length); + boolean result = yuvImage.compressToJpeg(new Rect(0, 0, mWidth, mHeight), 100, bos); + if(result){ + byte[] buffer = bos.toByteArray(); + Bitmap bmp = BitmapFactory.decodeByteArray(buffer, 0, buffer.length); + + File file = new File(path); + FileOutputStream fos = null; + try { + fos = new FileOutputStream(file); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + bmp.compress(Bitmap.CompressFormat.JPEG, 100, fos); + try { + fos.flush(); + fos.close(); + bmp.recycle(); + if(mCaptureListener != null) { + mCaptureListener.onCaptureResult(path); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + try { + bos.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) public void handleUpdateMedia(final String path) { if (DEBUG) Log.v(TAG_THREAD, "handleUpdateMedia:path=" + path);