camera2扫描获取高清图

先看下google提供的demo https://github.com/googlesamples/android-Camera2Basic
扫描获取高清图也是基于这个demo做了一些修改,遇到一些问题,这边讲述下自己的想法,大佬勿喷。

  1. demo中自定义的AutoFitTextureView 我建议是不要用,它是通过手机的屏幕分辨率来选择的分辨率,现在国产手机分辨率有很多不是16:9,4:3的,所以它这套算法下来,会选取比较低的分辨率,就导致预览的时候模糊看不清。
    我个人建议是先选定自己想要的分辨率,(我用的是1080*1920)然后设置使用TextureView设置宽为match_parent,最后动态设置高度为 textureView高度 = textureView宽 * 预览高 / 预览宽

2.Camera2功能支持情况 我做的是扫描软件,同时又要求要高清图,为了保证预览无卡顿,所以要做到拍摄图片时,预览不能暂停,但是发现oppo手机不行,取一张图就卡一次,用户体验非常不好,我也傻到联系他们客服(当然客服跟你讲的都是官方话术)这里要感谢一位大佬 这是他写 https://www.jianshu.com/p/23e8789fbc10 以下是摘抄

查询Camera2功能支持情况
上面说过, 不是所以手机都支持完整的Camera2功能, 现在都2018了, Camera2出来都有4年左右了, 但估计还有些中低端手机使用的HAL1, 使用HAL1就会导致Camera2一些高级功能都没法使用了, 下面讲一下如何查询设备对应Camera2的支持情况.
INFO_SUPPORTED_HARDWARE_LEVEL
硬件层面支持的Camera2功能等级, 主要分为5个等级:

INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY
INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED
INFO_SUPPORTED_HARDWARE_LEVEL_FULL
INFO_SUPPORTED_HARDWARE_LEVEL_3
INFO_SUPPORTED_HARDWARE_LEVEL_EXTERNAL

LEVEL_LEGACY: 向后兼容模式, 如果是此等级, 基本没有额外功能, HAL层大概率就是HAL1(我遇到过的都是)
LEVEL_LIMITED: 有最基本的功能, 还支持一些额外的高级功能, 这些高级功能是LEVEL_FULL的子集
LEVEL_FULL: 支持对每一帧数据进行控制,还支持高速率的图片拍摄
LEVEL_3: 支持YUV后处理和Raw格式图片拍摄, 还支持额外的输出流配置
LEVEL_EXTERNAL: API28中加入的, 应该是外接的摄像头, 功能和LIMITED类似
各个等级从支持的功能多少排序为: LEGACY < LIMITED < FULL < LEVEL_3
获取等级相关代码

private int isHardwareSupported(CameraCharacteristics characteristics) {Integer deviceLevel = characteristics.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL);if (deviceLevel == null) {Log.e(TAG, "can not get INFO_SUPPORTED_HARDWARE_LEVEL");return -1;}switch (deviceLevel) {case CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_FULL:Log.w(TAG, "hardware supported level:LEVEL_FULL");break;case CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY:Log.w(TAG, "hardware supported level:LEVEL_LEGACY");break;case CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_3:Log.w(TAG, "hardware supported level:LEVEL_3");break;case CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED:Log.w(TAG, "hardware supported level:LEVEL_LIMITED");break;}return deviceLevel;}

. 测试了几款手机 oppo手机的等级就是LEVEL_LEGACY,也就是个five。所以oppo用camera2的话,预览的时候就不要想拿高分辨的图了,也不要拍照,直接获取低分辨率预览图,也是可以使用的。

开始贴代码

public class CameraActivity2 extends BaseActivityimplements ActivityCompat.OnRequestPermissionsResultCallback {private static final SparseIntArray ORIENTATIONS = new SparseIntArray();private static final int REQUEST_CAMERA_PERMISSION = 1;private static final int TIME_OUT = 1010;//鉴别超时private ImageView ivOutJb,iv_tishi,iv_light,iv_biaozhi;private ViewfinderView viewfinderView;static {ORIENTATIONS.append(Surface.ROTATION_0, 90);ORIENTATIONS.append(Surface.ROTATION_90, 0);ORIENTATIONS.append(Surface.ROTATION_180, 270);ORIENTATIONS.append(Surface.ROTATION_270, 180);}/*** Tag for the {@link Log}.*/private CameraManager manager;/*** Camera state: Showing camera preview.*/private static final int STATE_PREVIEW = 0;/*** Camera state: Waiting for the focus to be locked.*/private static final int STATE_WAITING_LOCK = 1;/*** Camera state: Waiting for the exposure to be precapture state.*/private static final int STATE_WAITING_PRECAPTURE = 2;/*** Camera state: Waiting for the exposure state to be something other than precapture.*/private static final int STATE_WAITING_NON_PRECAPTURE = 3;/*** Camera state: Picture was taken.*/private static final int STATE_PICTURE_TAKEN = 4;/*** Max preview width that is guaranteed by Camera2 API*/private static final int MAX_PREVIEW_WIDTH = 1920;/*** Max preview height that is guaranteed by Camera2 API*/private static final int MAX_PREVIEW_HEIGHT = 1080;private int picWidth;private int picHeight;/*** {@link TextureView.SurfaceTextureListener} handles several lifecycle events on a* {@link TextureView}.*/private final TextureView.SurfaceTextureListener mSurfaceTextureListener= new TextureView.SurfaceTextureListener() {@Overridepublic void onSurfaceTextureAvailable(SurfaceTexture texture, int width, int height) {openCamera(width, height);}@Overridepublic void onSurfaceTextureSizeChanged(SurfaceTexture texture, int width, int height) {configureTransform(width, height);}@Overridepublic boolean onSurfaceTextureDestroyed(SurfaceTexture texture) {return true;}@Overridepublic void onSurfaceTextureUpdated(SurfaceTexture texture) {}};/*** ID of the current {@link CameraDevice}.*/private String mCameraId;/*** An {@link AutoFitTextureView} for camera preview.*/private TextureView mTextureView;/*** A {@link CameraCaptureSession } for camera preview.*/private CameraCaptureSession mCaptureSession;/*** A reference to the opened {@link CameraDevice}.*/private CameraDevice mCameraDevice;/*** 预览*/private Size mPreviewSize;//JPEG格式下支持拍摄图片的数组集合private Size [] pic;/*** {@link CameraDevice.StateCallback} is called when {@link CameraDevice} changes its state.*/private final CameraDevice.StateCallback mStateCallback = new CameraDevice.StateCallback() {@Overridepublic void onOpened(@NonNull CameraDevice cameraDevice) {// This method is called when the camera is opened.  We start camera preview here.mCameraOpenCloseLock.release();mCameraDevice = cameraDevice;createCameraPreviewSession();}@Overridepublic void onDisconnected(@NonNull CameraDevice cameraDevice) {mCameraOpenCloseLock.release();cameraDevice.close();mCameraDevice = null;}@Overridepublic void onError(@NonNull CameraDevice cameraDevice, int error) {mCameraOpenCloseLock.release();cameraDevice.close();mCameraDevice = null;finish();}};/*** An additional thread for running tasks that shouldn't block the UI.*/private HandlerThread mBackgroundThread;/*** A {@link Handler} for running tasks in the background.*/private Handler mBackgroundHandler;/*** An {@link ImageReader} that handles still image capture.*/private ImageReader mImageReader;/*** This is the output file for our picture.*/private File mFile;/*** This a callback object for the {@link ImageReader}. "onImageAvailable" will be called when a* still image is ready to be saved.*/private final ImageReader.OnImageAvailableListener mOnImageAvailableListener= new ImageReader.OnImageAvailableListener() {@Overridepublic void onImageAvailable(ImageReader reader) {mBackgroundHandler.post(new ImageSaver(reader.acquireLatestImage(), mFile));}};/*** {@link CaptureRequest.Builder} for the camera preview*/private CaptureRequest.Builder mPreviewRequestBuilder;/*** {@link CaptureRequest} generated by {@link #mPreviewRequestBuilder}*/private CaptureRequest mPreviewRequest;/*** The current state of camera state for taking pictures.** @see #mCaptureCallback*/private int mState = STATE_PREVIEW;/*** A {@link Semaphore} to prevent the app from exiting before closing the camera.*/private Semaphore mCameraOpenCloseLock = new Semaphore(1);/*** Whether the current camera device supports Flash or not.*/private boolean mFlashSupported;/*** Orientation of the camera sensor*/private int mSensorOrientation;/*** A {@link CameraCaptureSession.CaptureCallback} that handles events related to JPEG capture.*/private CameraCaptureSession.CaptureCallback mCaptureCallback= new CameraCaptureSession.CaptureCallback() {private void process(CaptureResult result) {switch (mState) {case STATE_PREVIEW: {Log.d("stateinfo","STATE_PREVIEW");// We have nothing to do when the camera preview is working normally.break;}case STATE_WAITING_LOCK: {Integer afState = result.get(CaptureResult.CONTROL_AF_STATE);if (afState == null) {captureStillPicture();} else if (CaptureResult.CONTROL_AF_STATE_PASSIVE_FOCUSED == afState) {mState = STATE_PREVIEW;captureStillPicture();}break;}}}@Overridepublic void onCaptureProgressed(@NonNull CameraCaptureSession session,@NonNull CaptureRequest request,@NonNull CaptureResult partialResult) {process(partialResult);}@Overridepublic void onCaptureCompleted(@NonNull CameraCaptureSession session,@NonNull CaptureRequest request,@NonNull TotalCaptureResult result) {process(result);}};/*** Shows a {@link Toast} on the UI thread.** @param text The message to show*/private void showToast(final String text) {runOnUiThread(new Runnable() {@Overridepublic void run() {Toast.makeText(CameraActivity2.this, text, Toast.LENGTH_SHORT).show();}});}//这边做了修改 选择比较合适的分辨率private Size chooseOptimalSize(Size[] choices, int textureViewWidth,int textureViewHeight, int maxWidth, int maxHeight, Size aspectRatio) {List<Size> bigEnough = new ArrayList<>();List<Size> bestBigEnough = new ArrayList<>();List<Size> notBigEnough = new ArrayList<>();List<Size> bestSize = new ArrayList<>();//以1080p为基准高于1080p的则视为高分辨率相反则视为低分辨率for (Size option : choices) {int w = option.getWidth();int h = option.getHeight();double rate = (double) w/h;String  rateStr = String.valueOf(rate);if (w > 1920 && h > 1080){bigEnough.add(option);if (rateStr.startsWith("1.7")){bestBigEnough.add(option);}}else {if (rateStr.startsWith("1.7")){bestSize.add(option);}notBigEnough.add(option);}}//choose 16:9if (bestSize.size() > 0){return Collections.max(bestSize,new CompareSizesByArea());}else if (notBigEnough.size() > 0){return Collections.max(notBigEnough, new CompareSizesByArea());}else if (bestBigEnough.size()> 0){return Collections.min(bestBigEnough, new CompareSizesByArea());}else if (bigEnough.size() > 0){return Collections.min(bigEnough, new CompareSizesByArea());} else {return choices[0];}}@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.capture1);AppManager.getAppManager().addActivity(this);getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);setScreenBrightness(200);mTextureView = findViewById(R.id.preview_view);viewfinderView = findViewById(R.id.scanner_view);mFile = new File(Environment.getExternalStorageDirectory(), "自己取名字" +"Pic.jpg");mCurrentState = AppManager.getAppManager().getCurrentLightState();if (mCurrentState == 0){iv_light.setImageResource(R.drawable.a31);}else {iv_light.setImageResource(R.drawable.a32);}Toast.makeText(this, R.string.mingliang, Toast.LENGTH_SHORT).show();getScreenInfo();}/*** 开始计时*/private void startTimeCount() {time = 0;start();}private int screenWidth;private int screenHeight;private void getScreenInfo(){//获取内屏分辨率(华为手机有bar这个值不会变)
//        WindowManager windowManager = getWindowManager();
//        Display d = windowManager.getDefaultDisplay();
//        DisplayMetrics realDis = new DisplayMetrics();
//        d.getRealMetrics(realDis);
//        screenHeight = realDis.heightPixels;
//        screenWidth = realDis.widthPixels;Point screenPoint = Camera2Manager.getCamera2Manager().getScreenPoint();screenWidth = screenPoint.x;screenHeight = screenPoint.y;}@Overridepublic void onResume() {super.onResume();Log.d("decodeMessage","onResume");startBackgroundThread();isFirstIn = true;startTimeCount();// When the screen is turned off and turned back on, the SurfaceTexture is already// available, and "onSurfaceTextureAvailable" will not be called. In that case, we can open// a camera and start preview from here (otherwise, we wait until the surface is ready in// the SurfaceTextureListener).if (mTextureView.isAvailable()) {openCamera(mTextureView.getWidth(), mTextureView.getHeight());} else {mTextureView.setSurfaceTextureListener(mSurfaceTextureListener);}}@Overridepublic void onPause() {closeCamera();stop();stopBackgroundThread();super.onPause();}/*** Sets up member variables related to camera.** @param width  The width of available size for camera preview* @param height The height of available size for camera preview*/private CameraCharacteristics mCharacteristics;private Rect mZoom;@SuppressWarnings("SuspiciousNameCombination")private void setUpCameraOutputs(int width, int height) {manager = (CameraManager)getSystemService(Context.CAMERA_SERVICE);try {for (String cameraId : manager.getCameraIdList()) {CameraCharacteristics characteristics= manager.getCameraCharacteristics(cameraId);mCharacteristics = characteristics;// We don't use a front facing camera in this sample.Integer facing = characteristics.get(CameraCharacteristics.LENS_FACING);if (facing != null && facing == CameraCharacteristics.LENS_FACING_FRONT) {continue;}StreamConfigurationMap map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);if (map == null) {continue;}// For still image captures, we use the largest available size.pic =  map.getOutputSizes(ImageFormat.JPEG);Size largest = Collections.max(Arrays.asList(pic),new CompareSizesByArea());// Find out if we need to swap dimension to get the preview size relative to sensor// coordinate.int displayRotation = getWindowManager().getDefaultDisplay().getRotation();//noinspection ConstantConditionsmSensorOrientation = characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);boolean swappedDimensions = false;switch (displayRotation) {case Surface.ROTATION_0:case Surface.ROTATION_180:if (mSensorOrientation == 90 || mSensorOrientation == 270) {swappedDimensions = true;}break;case Surface.ROTATION_90:case Surface.ROTATION_270:if (mSensorOrientation == 0 || mSensorOrientation == 180) {swappedDimensions = true;}break;default:Log.e(TAG, "Display rotation is invalid: " + displayRotation);}Point displaySize = new Point();getWindowManager().getDefaultDisplay().getSize(displaySize);int rotatedPreviewWidth = width;int rotatedPreviewHeight = height;int maxPreviewWidth = displaySize.x;int maxPreviewHeight = displaySize.y;if (swappedDimensions) {rotatedPreviewWidth = height;rotatedPreviewHeight = width;maxPreviewWidth = displaySize.y;maxPreviewHeight = displaySize.x;}if (maxPreviewWidth > MAX_PREVIEW_WIDTH) {maxPreviewWidth = MAX_PREVIEW_WIDTH;}if (maxPreviewHeight > MAX_PREVIEW_HEIGHT) {maxPreviewHeight = MAX_PREVIEW_HEIGHT;}// Danger, W.R.! Attempting to use too large a preview size could  exceed the camera// bus' bandwidth limitation, resulting in gorgeous previews but the storage of// garbage capture data.mPreviewSize = chooseOptimalSize(map.getOutputSizes(SurfaceTexture.class),rotatedPreviewWidth, rotatedPreviewHeight, maxPreviewWidth,maxPreviewHeight, largest);Size bestSize  = chooseBestSize(pic);picWidth = bestSize.getWidth();picHeight = bestSize.getHeight();
//                viewfinderView.setPicSize(picWidth,picHeight);mImageReader = ImageReader.newInstance(picWidth, picHeight,ImageFormat.JPEG, /*maxImages*/1);
//                mImageReader = ImageReader.newInstance(1440, 1080,
//                        ImageFormat.JPEG, /*maxImages*/1);mImageReader.setOnImageAvailableListener(mOnImageAvailableListener, mBackgroundHandler);//保存预览尺寸后面要用Camera2Manager.getCamera2Manager().setPreviewWidth(mPreviewSize.getWidth());Camera2Manager.getCamera2Manager().setPreviewHeight(mPreviewSize.getHeight());// We fit the aspect ratio of TextureView to the size of preview we picked.RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) mTextureView.getLayoutParams();layoutParams.height = mPreviewSize.getWidth() * screenWidth / mPreviewSize.getHeight() ;layoutParams.width = mPreviewSize.getWidth();mTextureView.setLayoutParams(layoutParams);// Check if the flash is supported.Boolean available = characteristics.get(CameraCharacteristics.FLASH_INFO_AVAILABLE);mFlashSupported = available == null ? false : available;mCameraId = cameraId;return;}} catch (CameraAccessException e) {e.printStackTrace();} catch (NullPointerException e) {// Currently an NPE is thrown when the Camera2API is used but not supported on the// device this code runs.
//            ErrorDialog.newInstance(getString(R.string.camera_error))
//                    .show(getChildFragmentManager(), FRAGMENT_DIALOG);}}//选取和预览比例一样的照片像素private Size chooseBestSize(Size[] pic) {int width = mPreviewSize.getWidth();int height = mPreviewSize.getHeight();//先获取比例一样的double rate = (double)width / height;rate = m1(rate);List<Size> sameRateSize = new ArrayList<>();List<Size> bigPixel = new ArrayList<>();List<Size> bigSameSize = new ArrayList<>();for (int i = 0;i<pic.length;i++){double rate1 = (double) pic[i].getWidth()/pic[i].getHeight();rate1 = m1(rate1);if (pic[i].getWidth()> 3000 && pic[i].getHeight()>1500){bigPixel.add(pic[i]);}if (rate == rate1){sameRateSize.add(pic[i]);}if (rate == rate1 && pic[i].getWidth()>3000 && pic[i].getHeight()>1500){bigSameSize.add(pic[i]);}}
//        return getMinSize(bigPixel);//先看有没有比例一样的大尺寸if (bigSameSize.size() == 0){//没有比例一样的大尺寸取大尺寸if (bigPixel.size() == 0){//没有大尺寸取比例一样的小尺寸if (sameRateSize.size() == 0){//没有比例一样的取预览的return mPreviewSize;}else {//有比例一样的取最大的return getMaxSize(sameRateSize);}}else {//有大尺寸取最小的return getMinSize(bigPixel);}}else {//有比例一样的大尺寸取最小的
//            return getMinSize(bigSameSize);return getMinSize(bigSameSize);}
//        if (sameRateSize.size() == 0){
//            if (bigPixel.size() == 0){
//                return mPreviewSize;
//            }else {
//                for (int j = 0;j < bigPixel.size()-1;j++){
//                    for (int k = 0 ; k< bigPixel.size() -1;k++){
//                    }
//                }
//                return Collections.min(bigPixel, new CompareSizesByArea());
//            }
//
//        }
//        //一个就直接返回
//        if (sameRateSize.size() == 1){
//            return new Size(sameRateSize.get(0).getWidth(),sameRateSize.get(0).getHeight());
//        }
//        //多个冒泡排序 选择第1个
//        int length = sameRateSize.size();
//        for (int j = 0;j<length-1;j++){
//            for (int k = 0;k<length-1;k++){
//                if (pic[k].getWidth() > pic[k+1].getWidth()){
//                    Size temp = pic[k];
//                    pic[k] = pic[k+1];
//                    pic[k+1] = temp;
//                }
//            }
//        }
//        return Collections.min(bigSameSize,new CompareSizesByArea());
//        return sameRateSize.get(length-2);}/*** Opens the camera specified by {@link #mCameraId}.*/private void openCamera(int width, int height) {if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)!= PackageManager.PERMISSION_GRANTED) {return;}if (isFirstIn){isFirstIn = false;setUpCameraOutputs(width, height);}configureTransform(width, height);manager = (CameraManager)getSystemService(Context.CAMERA_SERVICE);try {if (!mCameraOpenCloseLock.tryAcquire(2500, TimeUnit.MILLISECONDS)) {throw new RuntimeException("Time out waiting to lock camera opening.");}manager.openCamera(mCameraId, mStateCallback, mBackgroundHandler);} catch (CameraAccessException e) {e.printStackTrace();} catch (InterruptedException e) {throw new RuntimeException("Interrupted while trying to lock camera opening.", e);}}/*** Closes the current {@link CameraDevice}.*/private void closeCamera() {try {mCameraOpenCloseLock.acquire();if (null != mCaptureSession) {mCaptureSession.close();mCaptureSession = null;}if (null != mCameraDevice) {mCameraDevice.close();mCameraDevice = null;}if (null != mImageReader) {mImageReader.close();mImageReader = null;}} catch (InterruptedException e) {throw new RuntimeException("Interrupted while trying to lock camera closing.", e);} finally {mCameraOpenCloseLock.release();}}/*** Starts a background thread and its {@link Handler}.*/private void startBackgroundThread() {mBackgroundThread = new HandlerThread("CameraBackground");mBackgroundThread.start();mBackgroundHandler = new Handler(mBackgroundThread.getLooper());}/*** Stops the background thread and its {@link Handler}.*/private void stopBackgroundThread() {mBackgroundThread.quitSafely();try {mBackgroundThread.join();mBackgroundThread = null;mBackgroundHandler = null;} catch (InterruptedException e) {e.printStackTrace();}}/*** Creates a new {@link CameraCaptureSession} for camera preview.*/private void createCameraPreviewSession() {try {SurfaceTexture texture = mTextureView.getSurfaceTexture();assert texture != null;// We configure the size of default buffer to be the size of camera preview we want.texture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());
//            Toast.makeText(this,"预览宽高:"+mPreviewSize.getWidth()+"*"+mPreviewSize.getHeight(),Toast.LENGTH_SHORT).show();// This is the output Surface we need to start preview.Surface surface = new Surface(texture);// We set up a CaptureRequest.Builder with the output Surface.mPreviewRequestBuilder= mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);mPreviewRequestBuilder.addTarget(surface);// Here, we create a CameraCaptureSession for camera preview.mCameraDevice.createCaptureSession(Arrays.asList(surface, mImageReader.getSurface()),new CameraCaptureSession.StateCallback() {@Overridepublic void onConfigured(@NonNull CameraCaptureSession cameraCaptureSession) {// The camera is already closedif (null == mCameraDevice) {return;}// When the session is ready, we start displaying the preview.mCaptureSession = cameraCaptureSession;try {// Auto focus should be continuous for camera preview.mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE,CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);if (mCurrentState == 0){mPreviewRequestBuilder.set(CaptureRequest.FLASH_MODE,CameraMetadata.FLASH_MODE_OFF);}else {mPreviewRequestBuilder.set(CaptureRequest.FLASH_MODE,CameraMetadata.FLASH_MODE_TORCH);}// Flash is automatically enabled when necessary.
//                                setAutoFlash(mPreviewRequestBuilder);// Finally, we start displaying the camera preview.mPreviewRequest = mPreviewRequestBuilder.build();mCaptureSession.setRepeatingRequest(mPreviewRequest,mCaptureCallback, mBackgroundHandler);mState = STATE_WAITING_LOCK;
//                                takePicture();} catch (CameraAccessException e) {e.printStackTrace();}}@Overridepublic void onConfigureFailed(@NonNull CameraCaptureSession cameraCaptureSession) {showToast("Failed");}}, null);} catch (CameraAccessException e) {e.printStackTrace();}}/*** Configures the necessary {@link Matrix} transformation to `mTextureView`.* This method should be called after the camera preview size is determined in* setUpCameraOutputs and also the size of `mTextureView` is fixed.** @param viewWidth  The width of `mTextureView`* @param viewHeight The height of `mTextureView`*/private void configureTransform(int viewWidth, int viewHeight) {if (null == mTextureView || null == mPreviewSize) {return;}int rotation = getWindowManager().getDefaultDisplay().getRotation();Matrix matrix = new Matrix();RectF viewRect = new RectF(0, 0, viewWidth, viewHeight);RectF bufferRect = new RectF(0, 0, mPreviewSize.getHeight(), mPreviewSize.getWidth());float centerX = viewRect.centerX();float centerY = viewRect.centerY();if (Surface.ROTATION_90 == rotation || Surface.ROTATION_270 == rotation) {bufferRect.offset(centerX - bufferRect.centerX(), centerY - bufferRect.centerY());matrix.setRectToRect(viewRect, bufferRect, Matrix.ScaleToFit.FILL);float scale = Math.max((float) viewHeight / mPreviewSize.getHeight(),(float) viewWidth / mPreviewSize.getWidth());matrix.postScale(scale, scale, centerX, centerY);matrix.postRotate(90 * (rotation - 2), centerX, centerY);} else if (Surface.ROTATION_180 == rotation) {matrix.postRotate(180, centerX, centerY);}mTextureView.setTransform(matrix);}/*** Initiate a still image capture.*/private void takePicture() {
//        try {
//            mPreviewRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
//            SurfaceTexture texture = mTextureView.getSurfaceTexture();
//            Surface surface = new Surface(texture);
//            mPreviewRequestBuilder.addTarget(surface);
//            mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER,CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_CANCEL);
//
//        } catch (CameraAccessException e) {
//            e.printStackTrace();
//        }lockFocus();}/*** Lock the focus as the first step for a still image capture.*/private void lockFocus() {try {toast("又拍一张");// This is how to tell the camera to lock focus.
//            mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER,
//                    CameraMetadata.CONTROL_AF_TRIGGER_START);// Tell #mCaptureCallback to wait for the lock.Log.d("decodeInfo","take pic time = " + System.currentTimeMillis());mState = STATE_WAITING_LOCK;if (mCaptureSession == null)return;mCaptureSession.capture(mPreviewRequestBuilder.build(), mCaptureCallback,mBackgroundHandler);} catch (CameraAccessException e) {e.printStackTrace();}}/*** Run the precapture sequence for capturing a still image. This method should be called when* we get a response in {@link #mCaptureCallback} from {@link #lockFocus()}.*/private void runPrecaptureSequence() {try {// This is how to tell the camera to trigger.mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER,CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_START);// Tell #mCaptureCallback to wait for the precapture sequence to be set.mState = STATE_WAITING_PRECAPTURE;mCaptureSession.capture(mPreviewRequestBuilder.build(), mCaptureCallback,mBackgroundHandler);} catch (CameraAccessException e) {e.printStackTrace();}}/*** Capture a still picture. This method should be called when we get a response in* {@link #mCaptureCallback} from both {@link #lockFocus()}.*/private  void captureStillPicture() {if ( null == mCameraDevice) {return;}final CaptureRequest.Builder captureBuilder;try {captureBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);if (mCurrentState == 0){captureBuilder.set(CaptureRequest.FLASH_MODE,CaptureRequest.FLASH_MODE_OFF);}else {captureBuilder.set(CaptureRequest.FLASH_MODE,CaptureRequest.FLASH_MODE_TORCH);}captureBuilder.addTarget(mImageReader.getSurface());//            // Use the same AE and AF modes as the preview.
//            captureBuilder.set(CaptureRequest.CONTROL_AF_MODE,
//                    CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_START);
//            setAutoFlash(captureBuilder);// Orientationint rotation = getWindowManager().getDefaultDisplay().getRotation();
//            captureBuilder.set(CaptureRequest.JPEG_ORIENTATION, getOrientation(rotation));CameraCaptureSession.CaptureCallback CaptureCallback= new CameraCaptureSession.CaptureCallback() {@Overridepublic void onCaptureCompleted(@NonNull CameraCaptureSession session,@NonNull CaptureRequest request,@NonNull TotalCaptureResult result) {unlockFocus();}};//            mCaptureSession.stopRepeating();
//            mCaptureSession.abortCaptures();mCaptureSession.capture(captureBuilder.build(), CaptureCallback, null);} catch (CameraAccessException e) {e.printStackTrace();}}/*** Retrieves the JPEG orientation from the specified screen rotation.** @param rotation The screen rotation.* @return The JPEG orientation (one of 0, 90, 270, and 360)*/private int getOrientation(int rotation) {// Sensor orientation is 90 for most devices, or 270 for some devices (eg. Nexus 5X)// We have to take that into account and rotate JPEG properly.// For devices with orientation of 90, we simply return our mapping from ORIENTATIONS.// For devices with orientation of 270, we need to rotate the JPEG 180 degrees.return (ORIENTATIONS.get(rotation) + mSensorOrientation + 270) % 360;}/*** Unlock the focus. This method should be called when still image capture sequence is* finished.*/private void unlockFocus() {try {// Reset the auto-focus trigger
//            mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER,
//                    CameraMetadata.CONTROL_AF_TRIGGER_CANCEL);
//            setAutoFlash(mPreviewRequestBuilder);
//            mCaptureSession.capture(mPreviewRequestBuilder.build(), mCaptureCallback,
//                    mBackgroundHandler);// After this, the camera will go back to the normal state of preview.mState = STATE_PREVIEW;mCaptureSession.setRepeatingRequest(mPreviewRequestBuilder.build(), mCaptureCallback,mBackgroundHandler);} catch (CameraAccessException e) {e.printStackTrace();}}private int mCurrentState;//0关1开@Overridepublic void onClick(View view) {switch (view.getId()){case R.id.iv_light:closeOrOpenLight();break;case R.id.iv_outJb:finish();break;}}//开启或关闭闪光灯private void closeOrOpenLight(){if (!mFlashSupported){iv_light.setVisibility(View.GONE);return;}if (mCurrentState == 0){//打开mPreviewRequestBuilder.set(CaptureRequest.FLASH_MODE,CameraMetadata.FLASH_MODE_TORCH);try {if (mCaptureSession == null)return;mCaptureSession.setRepeatingRequest(mPreviewRequestBuilder.build(), mCaptureCallback,mBackgroundHandler);} catch (CameraAccessException e) {e.printStackTrace();}mCurrentState = 1;}else {//关闭
//            mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_OFF);mPreviewRequestBuilder.set(CaptureRequest.FLASH_MODE,CameraMetadata.FLASH_MODE_OFF);try {mCaptureSession.setRepeatingRequest(mPreviewRequestBuilder.build(), mCaptureCallback,mBackgroundHandler);} catch (CameraAccessException e) {e.printStackTrace();}mCurrentState = 0;}AppManager.getAppManager().setCurrentLightState(mCurrentState);if (mCurrentState == 0){iv_light.setImageResource(R.drawable.a31);}else {iv_light.setImageResource(R.drawable.a32);}}private void setAutoFlash(CaptureRequest.Builder requestBuilder) {if (mFlashSupported) {requestBuilder.set(CaptureRequest.FLASH_MODE,
//                    CaptureRequest.CONTROL_AE_ANTIBANDING_MODE_50HZ);CameraMetadata.FLASH_MODE_TORCH);}}/*** Saves a JPEG {@link Image} into the specified {@link File}.*/private  class ImageSaver implements Runnable {/*** The JPEG image*/private Image mImage;/*** The file we save the image into.*/private  File mFile;ImageSaver(Image image, File file) {mImage = image;mFile = file;}@Overridepublic void run() {Log.d("decodeInfo","get Pic Success");if (mImage == null)return;ByteBuffer buffer = mImage.getPlanes()[0].getBuffer();byte[] bytes = new byte[buffer.remaining()];buffer.get(bytes);FileOutputStream output = null;try {output = new FileOutputStream(mFile);output.write(bytes);} catch (IOException e) {e.printStackTrace();} finally {mImage.close();if (null != output) {try {output.close();decodeHandler.sendEmptyMessage(DECODE);} catch (IOException e) {e.printStackTrace();}}}}}/*** Compares two {@code Size}s based on their areas.*/static class CompareSizesByArea implements Comparator<Size> {@Overridepublic int compare(Size lhs, Size rhs) {// We cast here to ensure the multiplications won't overflowreturn Long.signum((long) lhs.getWidth() * lhs.getHeight() -(long) rhs.getWidth() * rhs.getHeight());}}public Handler decodeHandler = new Handler(){@Overridepublic synchronized void handleMessage(Message msg) {switch (msg.what){case DECODE :decode();break;case DECODE_SUCCESS:stop();startResultActivity((String) msg.obj);decodeHandler.removeCallbacksAndMessages(null);break;case GET_PASSWORD:time = 0;String message =msg.obj.toString();AppManager.getAppManager().SetUSBCodeData(message);takePicture();break;case PUT_LABEL_IN_RECT:time = 0;Toast.makeText(CameraActivity2.this,R.string.zhongjian,Toast.LENGTH_SHORT).show();takePicture();break;case NO_FANGUANG:time = 0;Toast.makeText(CameraActivity2.this,R.string.fanguang,Toast.LENGTH_SHORT).show();takePicture();break;case LABEL_SMALL:time = 0;Toast.makeText(CameraActivity2.this,R.string.kaojin,Toast.LENGTH_SHORT).show();takePicture();break;case DECODE_FAILED:takePicture();break;case DECODE_TISHI:stop();ResultParam result = (ResultParam) msg.obj;String text = result.getResultString();Bitmap bitmap = result.getBitmap();ByteArrayOutputStream bos = new ByteArrayOutputStream();bitmap.compress(Bitmap.CompressFormat.JPEG, 90, bos);String baseFile = Base64.encodeBytes(bos.toByteArray());dealwith(text, baseFile);break;case R.id.decode_sucess_message:stop();Map<String, Object> map = (Map<String, Object>) msg.obj;Double ii = (Double) map.get("ret");String substring = String.valueOf(ii).substring(0, String.valueOf(ii).indexOf("."));int integer = Integer.parseInt(substring);if (integer == 0) {// 名单中没有// 扫到的二维码是中准标签下的showPopwindow(1);} else if (integer == 2) {// 黑名单// 扫到的二维码是假冒标签的String url = (String) map.get("url");if(!TextUtils.isEmpty(url)){String doublerand = (String) map.get("rand");String code = (String) map.get("qrcode");String rand = String.valueOf(doublerand);Intent intent = new Intent(CameraActivity2.this, NotTagActivity.class);intent.putExtra("url", url);
//                  intent.putExtra("rand", rand.substring(0,rand.indexOf(".")));intent.putExtra("rand", rand);intent.putExtra("qrcode", code);startActivity(intent);}} else {// 白名单if (map.containsKey("url")){String url = (String) map.get("url");if (!TextUtils.isEmpty(url)){//判断是纯文字还是urlif (url.startsWith("http")){String doublerand = (String) map.get("rand");String code = (String) map.get("qrcode");String rand = String.valueOf(doublerand);Intent intent = new Intent(CameraActivity2.this, NotTagActivity.class);intent.putExtra("url", url);
//                  intent.putExtra("rand", rand.substring(0,rand.indexOf(".")));intent.putExtra("rand", rand);intent.putExtra("qrcode", code);startActivity(intent);}else {//纯文字showPopwindow(2,url);}}else {showPopwindow(2);}}else {//不存在url字段showPopwindow(2);}}break;case R.id.decode_fail_message:time = 0;ToastUtils.makeToast(CameraActivity2.this, R.string.network_not_connected, Toast.LENGTH_LONG);takePicture();break;case R.id.popdismiss:if(popupWindow != null){popupWindow.dismiss();start();}break;case TIME_OUT:Intent intent = new Intent(CameraActivity2.this,TimeOutActivity.class);startActivity(intent);decodeHandler.removeCallbacksAndMessages(null);stop();break;}}};private void startResultActivity(String info) {Intent intent = new Intent(this,ResultActivity.class);String info1 = Base64.encodeBytes(info.getBytes());intent.putExtra("txtFile",info1);startActivity(intent);}private void decode(){Log.d("decodeInfo","start decode");new Thread(){@Overridepublic void run() {Bitmap bitmap = BitmapFactory.decodeFile(mFile.getPath());if (bitmap == null){takePicture();toast("图片为空");return;}//剪裁图片Bitmap decodeBitmap = cropBitmap(bitmap);
//                saveBitmap("decodeBitmap",decodeBitmap);Bitmap qrDecode = cropBitmap(bitmap);//QR识别byte[] bitmapdata = ImageUtils.getYUV420sp(qrDecode.getWidth(),qrDecode.getHeight(), qrDecode);try {PlanarYUVLuminanceSource source = new PlanarYUVLuminanceSource(bitmapdata,qrDecode.getWidth(),qrDecode.getHeight(),0,0,qrDecode.getWidth(),qrDecode.getHeight());BinaryBitmap newbitmap = new BinaryBitmap(new HybridBinarizer(source));
//                    Vector<BarcodeFormat> decodeFormats = new Vector<>();
//                    decodeFormats.add(BarcodeFormat.QR_CODE);
//                    decodeFormats.add(BarcodeFormat.DATA_MATRIX);
//                    decodeFormats.add(BarcodeFormat.PDF_417);
//                    decodeFormats.add(BarcodeFormat.AZTEC);
//                    decodeFormats.add(BarcodeFormat.MAXICODE);Hashtable<DecodeHintType, Object> hints = new Hashtable();hints.put(DecodeHintType.CHARACTER_SET, "utf-8");hints.put(DecodeHintType.TRY_HARDER, Boolean.TRUE);hints.put(DecodeHintType.POSSIBLE_FORMATS, BarcodeFormat.QR_CODE);QRCodeReader multiFormatReader = new QRCodeReader();
//                    multiFormatReader.setHints(hints);Result result = multiFormatReader.decode(newbitmap);if (result != null) {Message message = Message.obtain(decodeHandler,DECODE_TISHI);ResultParam resultParam = new ResultParam();resultParam.setBitmap(bitmap);resultParam.setResultString(result.getText());message.obj = resultParam;message.sendToTarget();return;}} catch (Exception e) {e.printStackTrace();}CodeDecJni cdj = new CodeDecJni();Object[] objResult = null;try{objResult = cdj.decode(decodeBitmap);}catch (OutOfMemoryError e){bitmap.recycle();decodeBitmap.recycle();toast("内存溢出");}
//                Rect frame = viewfinderView.getFramingRect();
//                int preWidth = frame.right - frame.left;
//                int preHeight = frame.bottom - frame.top;
//                preWidth = preWidth*mBitmapHeight/screenHeight;
//                preHeight = preHeight*mBitmapWidth/screenWidth;Log.d("objectInfo","objResult[0]toString ="+objResult[0].toString());if (objResult[0] == null || objResult[0].toString().length() == 0) {//原图没找到,原图旋转3次鉴别,返回鉴别结果
//                    takePicture();Bitmap lrBitmap = leftRightDecode(decodeBitmap);DecodeState state = mirrorDecode(lrBitmap,cdj);if (state != null && !state.isState()){Bitmap tbBitmap = topBottomDecode(decodeBitmap);DecodeState state1 = mirrorDecode(tbBitmap,cdj);if (state1 != null && !state1.isState()){takePicture();}}}else {toast("1cg");doSuccess(objResult,decodeBitmap);}decodeBitmap.recycle();bitmap.recycle();}}.start();}/*** 镜像鉴别* @param bitmap* @param cdj*/private DecodeState mirrorDecode(Bitmap bitmap, CodeDecJni cdj) {try{toast("镜像鉴别");Object[] objects = cdj.decode(bitmap);if (objects[0] == null || objects[0].toString().length() == 0){DecodeState state = new DecodeState(false,null,null);return state;}else {toast("1cg");doSuccess(objects,bitmap);}}catch (OutOfMemoryError error){Runtime.getRuntime().freeMemory();bitmap.recycle();takePicture();}return null;}/*** 第一个库返回成功进行下一步鉴别* @param objects*/private void doSuccess(Object[] objects,Bitmap bitmap) {Rect frame = viewfinderView.getFramingRect();int preWidth = bitmap.getWidth()+40;int preHeight = bitmap.getHeight()+40;
//        int preWidth = frame.right - frame.left;
//        int preHeight = frame.bottom - frame.top;
//        preWidth = preWidth*mBitmapHeight/screenHeight;
//        preHeight = preHeight*mBitmapWidth/screenWidth;
//        preWidth = (preWidth/4+1)*4+40;
//        preHeight = (preHeight/4+1)*4+40;byte[] retStr = (byte[]) objects[1];int[] retParam = (int[]) objects[2];
//        int xBig = retParam[11] > retParam[17] ?  retParam[11] : retParam[17];
//        int xSmall = retParam[13] > retParam[15] ? retParam[15] : retParam[13];
//        int yBig = retParam[16] > retParam[18] ? retParam[16] : retParam[18];
//        int ySmall = retParam[12] > retParam[14] ? retParam[14] : retParam[12];
//        int xOffset = xBig - xSmall;
//        int yOffset = yBig - ySmall;
//        retParam[1] = xOffset;
//        retParam[2] = yOffset;ResultParam rp = new ResultParam();StringBuffer sb = new StringBuffer();for (int kk = 0; kk < retParam[0]; kk++) {sb.append(retStr[kk]);}AppManager.getAppManager().setStrLBData(sb.toString());DataPreProcess dataPreProcess = new DataPreProcess();DataClass data1 = dataPreProcess.AnayDecodeData(retParam, retStr, bitmap,preWidth, preHeight);if (data1.getRet() == 1) {Bitmap bitmap1 = data1.getRetBmp();if (bitmap1.getWidth() < 220 || bitmap1.getHeight()<220){decodeHandler.sendEmptyMessage(LABEL_SMALL);return;}AppManager.getAppManager().setBitmap(bitmap1);rp.setResultString(data1.getStrRet());Message message = Message.obtain(decodeHandler,DECODE_SUCCESS);message.obj = data1.getStrRet();message.sendToTarget();bitmap.recycle();}else {bitmap.recycle();int Er =data1.getErData();if (Er == 4){getNetData();}else {if (Er != -1){if (Er == 9){ErCountEdge++;}else if (Er == 10){ErCountArea++;}else {ErCount2++;}if (ErCount1 >= ER_COUNT_NUM){ErCount1 = 0;Message msg = Message.obtain(decodeHandler,PUT_LABEL_IN_RECT);msg.sendToTarget();}if (ErCount2 >= ER_COUNT_NUM){ErCount2 = 0;Message msg = Message.obtain(decodeHandler,NO_FANGUANG);msg.sendToTarget();}if (ErCountArea >= ER_COUNT_NUM){ErCountArea = 0;Message msg = Message.obtain(decodeHandler,LABEL_SMALL);msg.sendToTarget();}}}Message message = Message.obtain(decodeHandler,DECODE_FAILED);message.sendToTarget();}}//上下镜像之后的图private Bitmap topBottomDecode(Bitmap decodeBitmap) {int w = decodeBitmap.getWidth();int h = decodeBitmap.getHeight();Matrix sxM = new Matrix();sxM.postScale(1, -1);Bitmap sxbmp = Bitmap.createBitmap(decodeBitmap, 0, 0, w, h, sxM,true);return sxbmp;}//左右镜像之后的图private Bitmap leftRightDecode(Bitmap decodeBitmap) {int w = decodeBitmap.getWidth();int h = decodeBitmap.getHeight();Matrix zyM =new Matrix();zyM.postScale(-1,1);Bitmap zyBitmap = Bitmap.createBitmap(decodeBitmap,0,0,w,h,zyM,true);return zyBitmap;}int mBitmapWidth;int mBitmapHeight;private Bitmap cropBitmap(Bitmap bitmap){mBitmapWidth = bitmap.getWidth();mBitmapHeight = bitmap.getHeight();int[] scannerInfo = Camera2Manager.getCamera2Manager().getScannerViewInfo();int screenLeft = scannerInfo[0];int screenTop =scannerInfo[1];int screenLength = scannerInfo[2];int left = screenLeft*mBitmapHeight/screenWidth;int top = screenTop*mBitmapWidth/screenHeight;int width = screenLength*mBitmapHeight/screenWidth;int height = screenLength*mBitmapWidth/screenHeight;width = (width/4+1)*4;height = (height/4+1)*4;int length = width>height ? width : height;Bitmap bitmap2 = Bitmap.createBitmap(bitmap,top-8,left-8 ,length+16,length+16);return  scaleCanvas(bitmap2,new Rect(0,0,700,700));}private void toast(final String str){runOnUiThread(new Runnable() {@Overridepublic void run() {}});Log.d("decodeMessage",str);}private void saveBitmap(String name,Bitmap bm){File file = new File(Environment.getExternalStorageDirectory(),name+".jpg");if (file.exists()){file.delete();}try{FileOutputStream out = new FileOutputStream(file);bm.compress(Bitmap.CompressFormat.PNG, 90, out);out.flush();out.close();Log.d("decodeMessage","小图保存成功");}catch (FileNotFoundException e){}catch (IOException e){}}//获取加密文件public void getNetData() {new Thread() {public void run() {// AppManager.getAppManager().SetUSBCodeData(null);String urlDownload = "http://jb.stanic.com.cn:90/zzserver/checkversion/USBCodeData";String data = ApiClient._post(urlDownload,null);if (!TextUtils.isEmpty(data) && data.contains("result")){JiaMi jiaMi = JSONObject.parseObject(data,JiaMi.class);String jiamiStr = jiaMi.getResult();Message msg = decodeHandler.obtainMessage(GET_PASSWORD, jiamiStr);decodeHandler.sendMessage(msg);}}}.start();}/*** 获取最小的Size* @param list* @return*/private Size getMinSize(List<Size> list){int length = list.size();for (int i = 0 ; i<length-1;i++){for (int j = 0;j<length-1;j++){if (list.get(j).getHeight() > list.get(j+1).getHeight()){Size temp = list.get(i);list.set(j,list.get(j+1));list.set(j+1,temp);}}}return list.get(0);}/*** 获取最大的* @param list* @return*/private Size getMaxSize(List<Size> list){int length = list.size();for (int i = 0 ; i<length-1;i++){for (int j = 0;j<length-1;j++){if (list.get(j).getHeight() > list.get(j+1).getHeight()){Size temp = list.get(i);list.set(j,list.get(j+1));list.set(j+1,temp);}}}return list.get(length-1);}private void dealwith(final String text, String baseFile) {final Map<String, Object> map = new HashMap<String, Object>();map.put("qrcode", text);map.put("qrimg", baseFile);map.put("txtposition", AppManager.getAppManager().location.strData);map.put("imei", AppManager.getAppManager().getStrImei());map.put("imsi", AppManager.getAppManager().getStrImsi());map.put("iccid", AppManager.getAppManager().getStrImel());map.put("longitude", AppManager.getAppManager().location.lng+ "");map.put("latitude", AppManager.getAppManager().location.lat + "");try {String versionName = getPackageManager().getPackageInfo(getPackageName(), 0).versionName;map.put("version", versionName);byte[] digest = MessageDigest.getInstance("MD5").digest(text.getBytes("UTF-8"));StringBuilder hex = new StringBuilder(digest.length * 2);for (byte b : digest) {if ((b & 0xFF) < 0x10)hex.append("0");hex.append(Integer.toHexString(b & 0xFF));}String md5text = hex.toString();map.put("qrmd5", md5text);DataPreProcess dataPre = new DataPreProcess();final String url = "http://jb.stanic.com.cn:90/" + "zzserver/QrQuery_queryQrCode1";//正式new Thread(new Runnable() {@Overridepublic void run() {String _post = ApiClient._post(url, map);if (!TextUtils.isEmpty(_post) & _post.contains("ret")) {Gson gson = new Gson();Map<String, Object> map = gson.fromJson(_post,new TypeToken<Map<String, Object>>() {}.getType());map.put("qrcode", text);Message message = new Message();message.what = R.id.decode_sucess_message;message.obj = map;decodeHandler.sendMessage(message);} else {decodeHandler.sendEmptyMessage(R.id.decode_fail_message);}}}).start();} catch (Exception e) {e.printStackTrace();decodeHandler.sendEmptyMessage(R.id.decode_fail_message);}}boolean popshow = false;private PopupWindow popupWindow;@SuppressWarnings("deprecation")private void showPopwindow(int type) {popshow = true;View inflate = View.inflate(CameraActivity2.this, R.layout.popupwindow, null);ImageView iv_slt = inflate.findViewById(R.id.iv_slt);ImageUtil.setImagePng(36,iv_slt);TextView typeid =  inflate.findViewById(R.id.type_text);if(type == 1){typeid.setText(R.string.tishi);Toast.makeText(CameraActivity2.this, R.string.tishi, Toast.LENGTH_LONG).show();}else {Toast.makeText(CameraActivity2.this, R.string.texttishi, Toast.LENGTH_LONG).show();typeid.setText(R.string.texttishi);}View rootview = LayoutInflater.from(CameraActivity2.this).inflate(R.layout.capture,null);Display defaultDisplay = getWindowManager().getDefaultDisplay();int width = defaultDisplay.getWidth();int height = defaultDisplay.getHeight();int widthdoubleValue = (int) BigDecimal.valueOf(width).multiply(BigDecimal.valueOf(0.8)).doubleValue();int heightdoubleValue = (int) BigDecimal.valueOf(height).multiply(BigDecimal.valueOf(0.6)).doubleValue();popupWindow = new PopupWindow(inflate,ActionBar.LayoutParams.WRAP_CONTENT, ActionBar.LayoutParams.WRAP_CONTENT, true);popupWindow.setWidth(widthdoubleValue);popupWindow.setHeight(heightdoubleValue);popupWindow.setContentView(inflate);popupWindow.setBackgroundDrawable(new ColorDrawable(0));popupWindow.setOutsideTouchable(true);Button button = (Button) inflate.findViewById(R.id.button);popupWindow.setOnDismissListener(new PopupWindow.OnDismissListener() {@Overridepublic void onDismiss() {popshow = false;takePicture();}});popupWindow.showAtLocation(rootview, Gravity.CENTER, 0, 0);button.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {start();popupWindow.dismiss();}});final long starttime = System.currentTimeMillis();new Thread(new Runnable() {@Overridepublic void run() {while(popshow){long lasttime = System.currentTimeMillis();if(lasttime - starttime >= 15000){decodeHandler.sendEmptyMessage(R.id.popdismiss);}}}}).start();}@SuppressWarnings("deprecation")private void showPopwindow(int type,String toastStr) {popshow = true;View inflate = View.inflate(this, R.layout.popupwindow, null);TextView typeid = (TextView) inflate.findViewById(R.id.type_text);if(type == 1){typeid.setText(R.string.tishi);}else {typeid.setText(R.string.texttishi);}View rootview = LayoutInflater.from(this).inflate(R.layout.capture,null);Display defaultDisplay = getWindowManager().getDefaultDisplay();int width = defaultDisplay.getWidth();int height = defaultDisplay.getHeight();int widthdoubleValue = (int) BigDecimal.valueOf(width).multiply(BigDecimal.valueOf(0.8)).doubleValue();int heightdoubleValue = (int) BigDecimal.valueOf(height).multiply(BigDecimal.valueOf(0.6)).doubleValue();popupWindow = new PopupWindow(inflate,ActionBar.LayoutParams.WRAP_CONTENT, ActionBar.LayoutParams.WRAP_CONTENT, true);popupWindow.setWidth(widthdoubleValue);popupWindow.setHeight(heightdoubleValue);popupWindow.setContentView(inflate);popupWindow.setBackgroundDrawable(new ColorDrawable(0));popupWindow.setOutsideTouchable(true);Button button = inflate.findViewById(R.id.button);ImageView iv_slt = inflate.findViewById(R.id.iv_slt);ImageUtil.setImagePng(36,iv_slt);popupWindow.setOnDismissListener(new PopupWindow.OnDismissListener() {@Overridepublic void onDismiss() {popshow = false;takePicture();}});popupWindow.showAtLocation(rootview, Gravity.CENTER, 0, 0);button.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {popupWindow.dismiss();}});final long starttime = System.currentTimeMillis();new Thread(new Runnable() {@Overridepublic void run() {while(popshow){long lasttime = System.currentTimeMillis();if(lasttime - starttime >= 15000){decodeHandler.sendEmptyMessage(R.id.popdismiss);}}}}).start();}private double m1(double d){String str = String.valueOf(d);if (str.length()>4){str = str.substring(0,4);}else {str = str.substring(0,str.length()-1);}return Double.parseDouble(str);}private Bitmap adjustPhotoRotation(Bitmap bitmap,int orientationDegree){Matrix m = new Matrix();m.setRotate(orientationDegree, (float) bitmap.getWidth() / 2, (float) bitmap.getHeight() / 2);try {Bitmap bm1 = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), m, true);return bm1;} catch (OutOfMemoryError ex) {bitmap.recycle();}return null;}private int time;private TimeThread timeThread;private class TimeThread extends Thread{public boolean stop;@Overridepublic void run() {super.run();while (!stop){time++;if (time == 20){decodeHandler.sendEmptyMessage(TIME_OUT);}try{Thread.sleep(1000);}catch (InterruptedException e){e.printStackTrace();}}}}private void start(){if (timeThread  == null){timeThread = new TimeThread();timeThread.start();}}private void stop(){time = 0;if (timeThread != null){timeThread.stop = true;timeThread = null;}}private void setScreenBrightness(int paramInt){Window localWindow = getWindow();WindowManager.LayoutParams localLayoutParams = localWindow.getAttributes();float f = paramInt / 255.0F;localLayoutParams.screenBrightness = f;localWindow.setAttributes(localLayoutParams);}@Overrideprotected void onStop() {super.onStop();decodeHandler.removeCallbacksAndMessages(null);}private boolean isFirstIn;@Overrideprotected void onDestroy() {super.onDestroy();isFirstIn = false;}public Bitmap scaleCanvas(Bitmap bitmap, Rect rect) {Bitmap newBitmap = Bitmap.createBitmap(rect.width(), rect.height(), Bitmap.Config.ARGB_8888);//创建和目标相同大小的空BitmapCanvas canvas = new Canvas(newBitmap);Paint paint = new Paint();Bitmap temp = bitmap;//针对绘制bitmap添加抗锯齿PaintFlagsDrawFilter pfd= new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG|Paint.FILTER_BITMAP_FLAG);paint.setFilterBitmap(true); //对Bitmap进行滤波处理paint.setAntiAlias(true);//设置抗锯齿canvas.setDrawFilter(pfd);canvas.drawBitmap(temp, null, rect, paint);return newBitmap;}
}

Android camera2扫描相关推荐

  1. android获取卡号号码,Android银行卡扫描获取银行卡号

    ard.io开源的银行卡扫描的三方库真的是很好用啊. 首先需要在你的module的gradle的依赖文件中添加依赖 compile 'io.card:android-sdk:5.5.1' 2 清单文件 ...

  2. android camera2获取摄像头支持的分辨率

    android camera2 获取摄像头支持的分辨率 41的for循环我注释了,代码是获取最匹配的分辨率. private Size getMatchingSize2(){Size selectSi ...

  3. android 上下扫描动画,Android扫描雷达动画

    很简单的一个组合动画,用好基本动画啥子效果都不怕 老规矩先上图 效果图.gif ok 来 既然往下翻那就看看如何实现的吧 首先效果分为两部分 第一部分中间指针(其实这里就是一张图片) 第二部分就是波纹 ...

  4. Android Camera2 拍照(四)——对焦模式

    原文:Android Camera2 拍照(四)--对焦模式 本篇将重点介绍使用Camera2 API进行手动对焦的设置,以及在手动对焦与自动对焦模式之间切换. 一.手动对焦响应事件 首先我们要实现点 ...

  5. android camera捕捉,通过android camera2 API捕捉4:3相机图片与16:9传感器阵列相机

    我想从使用Camera2 API(Android 5.0版本中添加)的Android fron-facing相机以4:3的宽高比捕捉视频.它工作正常,除非相机有16:9传感器阵列(作为三星Galaxy ...

  6. 如何实现RTMP推送Android Camera2数据

    Camera2简介 在Google 推出Android 5.0的时候, Android Camera API 版本升级到了API2(android.hardware.camera2), 之前使用的AP ...

  7. android Camera2 API使用详解

    原文:android Camera2 API使用详解 由于最近需要使用相机拍照等功能,鉴于老旧的相机API问题多多,而且新的设备都是基于安卓5.0以上的,于是本人决定研究一下安卓5.0新引入的Came ...

  8. Android Camera2 教程 · 第三章 · 预览

    Android Camera2 教程 · 第三章 · 预览 DarylGo关注 Android Camera 上一章<Camera2 开启相机>我们学习了如何开启和关闭相机,接下来我们来学 ...

  9. 【Android Camera2】玩转图像数据 -- NV21图像旋转,镜像,转rgba代码分析,性能优化

    [Android Camera2]玩转图像数据 业务场景介绍 NV21数据旋转 逐像素遍历法 NV21数据镜像 逐像素遍历法 中心翻转法 NV21转RGB/RGBA数据 逐像素遍历法 NV21组合操作 ...

最新文章

  1. sybase 数据导入mysql_Windows环境下Sybase12.5 数据库创建与导入数据库.docx
  2. 思科:四分之三的物联网项目将以失败告终
  3. power(乘幂)函数剖析
  4. windows编译MaskRCNN
  5. 基于Flex的迷你工作流的设计与实现(序)
  6. Flask-WTF CSRF 保护P3
  7. 【转】测试用例设计——WEB通用测试用例
  8. fastdfs 集群 java,第四套:FastDFS 分布式文件系统集群与应用(视频)
  9. 计算身份证号码的校验码Python
  10. 【教程】生态环境影响评价技术应用及典型实践案例分析
  11. 中链云矿主办Web3.0 中国财富峰会
  12. php服务器怎么设置cookie,PHP之COOKIE支持详解
  13. bilibili视频批量下载
  14. Ubuntu下输入金钱符号时只能输入“₵“无法输入“$“
  15. 如何免费体验腾讯云虚拟主机(云服务器)
  16. 蓝桥杯2016初赛python题解
  17. [转]解剖PetShop
  18. GSoC: GitHub Checks API 项目第一阶段总结
  19. Python超级详细的上台阶楼梯问题,算法运行速度极快,内含计算排列的方法。问题:有n级台阶,每步可以走一级或两级,问有多少种不同的走法。k为传入的参数,默认值为3
  20. 2022电大国家开放大学网上形考任务-建设项目管理非免费(非答案)

热门文章

  1. AE关键帧动画基础概念
  2. 玩转华为ENSP模拟器系列 | 配置OSPFv3 ABR路由聚合示例
  3. python简易程序教程_Python-自制简易程序挂机刷御魂
  4. 把自己的电脑作为网络代理服务器
  5. Java版本和JDK版本对应关系
  6. G-sensor工作原理
  7. xss基础认证钓鱼代码收集
  8. 如何记账,记录家庭收支情况
  9. 数据显示 IT 工人结婚率并不低
  10. MQTT——java简单测试(二)