+ * 通过继承 {@link BarcodeCameraScanActivity}或{@link BarcodeCameraScanFragment}可快速实现扫码识别
+ *
+ * @author Jenly
+ */
+public abstract class BarcodeCameraScanActivity extends BaseCameraScanActivity
+ * 通过继承 {@link BarcodeCameraScanActivity}或{@link BarcodeCameraScanFragment}可快速实现扫码识别
+ *
+ * @author Jenly
+ */
+public abstract class BarcodeCameraScanFragment extends BaseCameraScanFragment
- * 快速实现扫描识别主要有以下几种方式:
- *
- * 1、通过继承 {@link CaptureActivity}或者{@link CaptureFragment}或其子类,可快速实现扫描识别。
- * (适用于大多数场景,自定义布局时需覆写getLayoutId方法)
- *
- * 2、在你项目的Activity或者Fragment中实例化一个{@link DefaultCameraScan}。(适用于想在扫码界面写交互逻辑,又因为项目
- * 架构或其它原因,无法直接或间接继承{@link CaptureActivity}或{@link CaptureFragment}时使用)
- *
- * 3、继承{@link CameraScan}自己实现一个,可参照默认实现类{@link DefaultCameraScan},其他步骤同方式2。(高级用法,谨慎使用)
- *
- * @author Jenly
- */
-public abstract class CameraScan implements ICamera, ICameraControl {
-
- /**
- * 扫描返回结果的key;解析方式可参见:{@link #parseScanResult(Intent)}
- */
- public static String SCAN_RESULT = "SCAN_RESULT";
-
- /**
- * A camera on the device facing the same direction as the device's screen.
- */
- public static int LENS_FACING_FRONT = CameraSelector.LENS_FACING_FRONT;
- /**
- * A camera on the device facing the opposite direction as the device's screen.
- */
- public static int LENS_FACING_BACK = CameraSelector.LENS_FACING_BACK;
-
- /**
- * 纵横比:4:3
- */
- public static final float ASPECT_RATIO_4_3 = 4.0F / 3.0F;
- /**
- * 纵横比:16:9
- */
- public static final float ASPECT_RATIO_16_9 = 16.0F / 9.0F;
-
- /**
- * 是否需要支持自动缩放
- */
- private boolean isNeedAutoZoom = false;
-
- /**
- * 是否需要支持触摸缩放
- */
- private boolean isNeedTouchZoom = true;
-
- /**
- * 是否需要支持触摸缩放
- *
- * @return 返回是否需要支持触摸缩放
- */
- protected boolean isNeedTouchZoom() {
- return isNeedTouchZoom;
- }
-
- /**
- * 设置是否需要支持触摸缩放
- *
- * @param needTouchZoom 是否需要支持触摸缩放
- * @return {@link CameraScan}
- */
- public CameraScan setNeedTouchZoom(boolean needTouchZoom) {
- isNeedTouchZoom = needTouchZoom;
- return this;
- }
-
- /**
- * 是否需要支持自动缩放
- *
- * @return 是否需要支持自动缩放
- */
- protected boolean isNeedAutoZoom() {
- return isNeedAutoZoom;
- }
-
- /**
- * 设置是否需要支持自动缩放
- *
- * @param needAutoZoom 是否需要支持自动缩放
- * @return {@link CameraScan}
- */
- public CameraScan setNeedAutoZoom(boolean needAutoZoom) {
- isNeedAutoZoom = needAutoZoom;
- return this;
- }
-
- /**
- * 设置相机配置,请在{@link #startCamera()}之前调用
- *
- * @param cameraConfig 相机配置
- * @return {@link CameraScan}
- */
- public abstract CameraScan setCameraConfig(CameraConfig cameraConfig);
-
- /**
- * 设置是否分析图像,通过此方法可以动态控制是否分析图像,常用于中断扫码识别。如:连扫时,扫到结果,然后停止分析图像
- *
- * 1. 因为分析图像默认为true,如果想支持连扫,在{@link OnScanResultCallback#onScanResultCallback(Result)}返回true拦截即可。
- * 当连扫的处理逻辑比较复杂时,请在处理逻辑前通过调用setAnalyzeImage(false)来停止分析图像,
- * 等逻辑处理完后再调用getCameraScan().setAnalyzeImage(true)来继续分析图像。
- *
- * 2. 如果只是想拦截扫码结果回调自己处理逻辑,但并不想继续分析图像(即不想连扫),可通过
- * 调用getCameraScan().setAnalyzeImage(false)来停止分析图像。
- *
- * @param analyze 是否分析图像
- * @return {@link CameraScan}
- */
- public abstract CameraScan setAnalyzeImage(boolean analyze);
-
- /**
- * 设置分析器,如果内置的一些分析器不满足您的需求,你也可以自定义{@link Analyzer},
- * 自定义时,切记需在{@link #startCamera()}之前调用才有效。
- *
- * 内置了一些{@link Analyzer}的实现类如下:
- *
- * @param analyzer 分析器
- * @return {@link CameraScan}
- * @see {@link MultiFormatAnalyzer}
- * @see {@link AreaRectAnalyzer}
- * @see {@link ImageAnalyzer}
- * @see {@link BarcodeFormatAnalyzer}
- * @see {@link QRCodeReader}
- */
- public abstract CameraScan setAnalyzer(Analyzer analyzer);
-
- /**
- * 设置是否振动
- *
- * @param vibrate 是否振动
- * @return {@link CameraScan}
- */
- public abstract CameraScan setVibrate(boolean vibrate);
-
- /**
- * 设置是否播放提示音
- *
- * @param playBeep 是否播放蜂鸣提示音
- * @return {@link CameraScan}
- */
- public abstract CameraScan setPlayBeep(boolean playBeep);
-
- /**
- * 设置扫码结果回调
- *
- * @param callback 扫码结果回调
- * @return {@link CameraScan}
- */
- public abstract CameraScan setOnScanResultCallback(OnScanResultCallback callback);
-
- /**
- * 绑定手电筒,绑定后可根据光线传感器,动态显示或隐藏手电筒
- *
- * @param v 手电筒视图
- * @return {@link CameraScan}
- */
- public abstract CameraScan bindFlashlightView(@Nullable View v);
-
- /**
- * 设置光线足够暗的阈值(单位:lux),需要通过{@link #bindFlashlightView(View)}绑定手电筒才有效
- *
- * @param lightLux 光线亮度阈值
- * @return {@link CameraScan}
- */
- public abstract CameraScan setDarkLightLux(float lightLux);
-
- /**
- * 设置光线足够明亮的阈值(单位:lux),需要通过{@link #bindFlashlightView(View)}绑定手电筒才有效
- *
- * @param lightLux 光线亮度阈值
- * @return {@link CameraScan}
- */
- public abstract CameraScan setBrightLightLux(float lightLux);
-
- /**
- * 扫描结果回调
- */
- public interface OnScanResultCallback {
- /**
- * 扫码结果回调
- *
- * @param result
- * @return 返回false表示不拦截,将关闭扫码界面并将结果返回给调用界面;
- * 返回true表示拦截,需自己处理逻辑。当isAnalyze为true时,默认会继续分析图像(也就是连扫)。
- * 如果只是想拦截扫码结果回调,并不想继续分析图像(不想连扫),请在拦截扫码逻辑处通过调
- * 用{@link CameraScan#setAnalyzeImage(boolean)},
- * 因为{@link CameraScan#setAnalyzeImage(boolean)}方法能动态控制是否继续分析图像。
- */
- boolean onScanResultCallback(Result result);
-
- /**
- * 扫码结果识别失败时触发此回调方法
- */
- default void onScanResultFailure() {
-
- }
- }
-
- /**
- * 解析扫描结果
- *
- * @param data 需解析的意图数据
- * @return 返回解析结果
- */
- @Nullable
- public static String parseScanResult(Intent data) {
- if (data != null) {
- return data.getStringExtra(SCAN_RESULT);
- }
- return null;
- }
-
-}
diff --git a/zxing-lite/src/main/java/com/king/zxing/CaptureActivity.java b/zxing-lite/src/main/java/com/king/zxing/CaptureActivity.java
deleted file mode 100644
index 8cb1230..0000000
--- a/zxing-lite/src/main/java/com/king/zxing/CaptureActivity.java
+++ /dev/null
@@ -1,241 +0,0 @@
-/*
- * Copyright (C) 2018 Jenly Yu
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.king.zxing;
-
-import android.Manifest;
-import android.os.Bundle;
-import android.view.View;
-
-import com.google.zxing.Result;
-import com.king.zxing.util.LogUtils;
-import com.king.zxing.util.PermissionUtils;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.appcompat.app.AppCompatActivity;
-import androidx.camera.view.PreviewView;
-
-/**
- * 相机扫描基类;{@link CaptureActivity} 内部持有{@link CameraScan},便于快速实现扫描识别。
- *
- * 快速实现扫描识别主要有以下几种方式:
- *
- * 1、通过继承 {@link CaptureActivity}或者{@link CaptureFragment}或其子类,可快速实现扫描识别。
- * (适用于大多数场景,自定义布局时需覆写getLayoutId方法)
- *
- * 2、在你项目的Activity或者Fragment中实例化一个{@link DefaultCameraScan}。(适用于想在扫码界面写交互逻辑,又因为项目
- * 架构或其它原因,无法直接或间接继承{@link CaptureActivity}或{@link CaptureFragment}时使用)
- *
- * 3、继承{@link CameraScan}自己实现一个,可参照默认实现类{@link DefaultCameraScan},其他步骤同方式2。(高级用法,谨慎使用)
- *
- * @author Jenly
- */
-public class CaptureActivity extends AppCompatActivity implements CameraScan.OnScanResultCallback {
-
- /**
- * 相机权限请求代码
- */
- private static final int CAMERA_PERMISSION_REQUEST_CODE = 0X86;
- /**
- * 预览视图
- */
- protected PreviewView previewView;
- /**
- * 取景视图
- */
- protected ViewfinderView viewfinderView;
- /**
- * 手电筒视图
- */
- protected View ivFlashlight;
- /**
- * CameraScan
- */
- private CameraScan mCameraScan;
-
- @Override
- protected void onCreate(@Nullable Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- if (isContentView()) {
- setContentView(getLayoutId());
- }
- initUI();
- }
-
- /**
- * 初始化
- */
- public void initUI() {
- previewView = findViewById(getPreviewViewId());
- int viewfinderViewId = getViewfinderViewId();
- if (viewfinderViewId != 0 && viewfinderViewId != View.NO_ID) {
- viewfinderView = findViewById(viewfinderViewId);
- }
- int ivFlashlightId = getFlashlightId();
- if (ivFlashlightId != 0 && ivFlashlightId != View.NO_ID) {
- ivFlashlight = findViewById(ivFlashlightId);
- if (ivFlashlight != null) {
- ivFlashlight.setOnClickListener(v -> onClickFlashlight());
- }
- }
- initCameraScan();
- startCamera();
- }
-
- /**
- * 点击手电筒
- */
- protected void onClickFlashlight() {
- toggleTorchState();
- }
-
- /**
- * 初始化CameraScan
- */
- public void initCameraScan() {
- mCameraScan = new DefaultCameraScan(this, previewView);
- mCameraScan.setOnScanResultCallback(this);
- }
-
- /**
- * 启动相机预览
- */
- public void startCamera() {
- if (mCameraScan != null) {
- if (PermissionUtils.checkPermission(this, Manifest.permission.CAMERA)) {
- mCameraScan.startCamera();
- } else {
- LogUtils.d("checkPermissionResult != PERMISSION_GRANTED");
- PermissionUtils.requestPermission(this, Manifest.permission.CAMERA, CAMERA_PERMISSION_REQUEST_CODE);
- }
- }
- }
-
- /**
- * 释放相机
- */
- private void releaseCamera() {
- if (mCameraScan != null) {
- mCameraScan.release();
- }
- }
-
- /**
- * 切换闪光灯状态(开启/关闭)
- */
- protected void toggleTorchState() {
- if (mCameraScan != null) {
- boolean isTorch = mCameraScan.isTorchEnabled();
- mCameraScan.enableTorch(!isTorch);
- if (ivFlashlight != null) {
- ivFlashlight.setSelected(!isTorch);
- }
- }
- }
-
- @Override
- public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
- super.onRequestPermissionsResult(requestCode, permissions, grantResults);
- if (requestCode == CAMERA_PERMISSION_REQUEST_CODE) {
- requestCameraPermissionResult(permissions, grantResults);
- }
- }
-
- /**
- * 请求Camera权限回调结果
- *
- * @param permissions 权限
- * @param grantResults 授权结果
- */
- public void requestCameraPermissionResult(@NonNull String[] permissions, @NonNull int[] grantResults) {
- if (PermissionUtils.requestPermissionsResult(Manifest.permission.CAMERA, permissions, grantResults)) {
- startCamera();
- } else {
- finish();
- }
- }
-
- @Override
- protected void onDestroy() {
- releaseCamera();
- super.onDestroy();
- }
-
- /**
- * 返回true时会自动初始化{@link #setContentView(int)},返回为false是需自己去初始化{@link #setContentView(int)}
- *
- * @return 默认返回true
- */
- public boolean isContentView() {
- return true;
- }
-
- /**
- * 布局ID;通过覆写此方法可以自定义布局
- *
- * @return 布局ID
- */
- public int getLayoutId() {
- return R.layout.zxl_capture;
- }
-
- /**
- * {@link #viewfinderView} 的 ID
- *
- * @return 默认返回{@code R.id.viewfinderView}, 如果不需要扫码框可以返回0
- */
- public int getViewfinderViewId() {
- return R.id.viewfinderView;
- }
-
- /**
- * 预览界面{@link #previewView} 的ID;可通过覆写此方法自定义ID
- *
- * @return 默认返回{@code R.id.previewView}
- */
- public int getPreviewViewId() {
- return R.id.previewView;
- }
-
- /**
- * 获取 {@link #ivFlashlight} 的ID
- *
- * @return 默认返回{@code R.id.ivFlashlight}, 如果不需要手电筒按钮可以返回0
- */
- public int getFlashlightId() {
- return R.id.ivFlashlight;
- }
-
- /**
- * 获取 {@link CameraScan}
- *
- * @return {@link #mCameraScan}
- */
- public CameraScan getCameraScan() {
- return mCameraScan;
- }
-
- /**
- * 接收扫码结果回调
- *
- * @param result 扫码结果
- * @return 返回true表示拦截,将不自动执行后续逻辑,为false表示不拦截,默认不拦截
- */
- @Override
- public boolean onScanResultCallback(Result result) {
- return false;
- }
-}
\ No newline at end of file
diff --git a/zxing-lite/src/main/java/com/king/zxing/CaptureFragment.java b/zxing-lite/src/main/java/com/king/zxing/CaptureFragment.java
deleted file mode 100644
index 5793c19..0000000
--- a/zxing-lite/src/main/java/com/king/zxing/CaptureFragment.java
+++ /dev/null
@@ -1,285 +0,0 @@
-/*
- * Copyright (C) 2019 Jenly Yu
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.king.zxing;
-
-import android.Manifest;
-import android.os.Bundle;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-
-import com.google.zxing.Result;
-import com.king.zxing.util.LogUtils;
-import com.king.zxing.util.PermissionUtils;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.camera.view.PreviewView;
-import androidx.fragment.app.Fragment;
-
-/**
- * 相机扫描基类;{@link CaptureFragment} 内部持有{@link CameraScan},便于快速实现扫描识别。
- *
- * 快速实现扫描识别主要有以下几种方式:
- *
- * 1、通过继承 {@link CaptureActivity}或者{@link CaptureFragment}或其子类,可快速实现扫描识别。
- * (适用于大多数场景,自定义布局时需覆写getLayoutId方法)
- *
- * 2、在你项目的Activity或者Fragment中实例化一个{@link DefaultCameraScan}。(适用于想在扫码界面写交互逻辑,又因为项目
- * 架构或其它原因,无法直接或间接继承{@link CaptureActivity}或{@link CaptureFragment}时使用)
- *
- * 3、继承{@link CameraScan}自己实现一个,可参照默认实现类{@link DefaultCameraScan},其他步骤同方式2。(高级用法,谨慎使用)
- *
- * @author Jenly
- */
-public class CaptureFragment extends Fragment implements CameraScan.OnScanResultCallback {
-
- /**
- * 相机权限请求代码
- */
- private static final int CAMERA_PERMISSION_REQUEST_CODE = 0X86;
- /**
- * 根视图
- */
- private View mRootView;
- /**
- * 预览视图
- */
- protected PreviewView previewView;
- /**
- * 取景视图
- */
- protected ViewfinderView viewfinderView;
- /**
- * 手电筒视图
- */
- protected View ivFlashlight;
- /**
- * CameraScan
- */
- private CameraScan mCameraScan;
-
- public static CaptureFragment newInstance() {
-
- Bundle args = new Bundle();
-
- CaptureFragment fragment = new CaptureFragment();
- fragment.setArguments(args);
- return fragment;
- }
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- if (isContentView()) {
- mRootView = createRootView(inflater, container);
- }
- return mRootView;
- }
-
- @Override
- public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
- super.onViewCreated(view, savedInstanceState);
- initUI();
- }
-
- /**
- * 初始化
- */
- public void initUI() {
- previewView = mRootView.findViewById(getPreviewViewId());
- int viewfinderViewId = getViewfinderViewId();
- if (viewfinderViewId != 0 && viewfinderViewId != View.NO_ID) {
- viewfinderView = mRootView.findViewById(viewfinderViewId);
- }
- int ivFlashlightId = getFlashlightId();
- if (ivFlashlightId != 0 && ivFlashlightId != View.NO_ID) {
- ivFlashlight = mRootView.findViewById(ivFlashlightId);
- if (ivFlashlight != null) {
- ivFlashlight.setOnClickListener(v -> onClickFlashlight());
- }
- }
- initCameraScan();
- startCamera();
- }
-
- /**
- * 点击手电筒
- */
- protected void onClickFlashlight() {
- toggleTorchState();
- }
-
- /**
- * 初始化CameraScan
- */
- public void initCameraScan() {
- mCameraScan = new DefaultCameraScan(this, previewView);
- mCameraScan.setOnScanResultCallback(this);
- }
-
- /**
- * 启动相机预览
- */
- public void startCamera() {
- if (mCameraScan != null) {
- if (PermissionUtils.checkPermission(getContext(), Manifest.permission.CAMERA)) {
- mCameraScan.startCamera();
- } else {
- LogUtils.d("checkPermissionResult != PERMISSION_GRANTED");
- PermissionUtils.requestPermission(this, Manifest.permission.CAMERA, CAMERA_PERMISSION_REQUEST_CODE);
- }
- }
- }
-
- /**
- * 释放相机
- */
- private void releaseCamera() {
- if (mCameraScan != null) {
- mCameraScan.release();
- }
- }
-
- /**
- * 切换闪光灯状态(开启/关闭)
- */
- protected void toggleTorchState() {
- if (mCameraScan != null) {
- boolean isTorch = mCameraScan.isTorchEnabled();
- mCameraScan.enableTorch(!isTorch);
- if (ivFlashlight != null) {
- ivFlashlight.setSelected(!isTorch);
- }
- }
- }
-
- @Override
- public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
- super.onRequestPermissionsResult(requestCode, permissions, grantResults);
- if (requestCode == CAMERA_PERMISSION_REQUEST_CODE) {
- requestCameraPermissionResult(permissions, grantResults);
- }
- }
-
- /**
- * 请求Camera权限回调结果
- *
- * @param permissions 权限
- * @param grantResults 授权结果
- */
- public void requestCameraPermissionResult(@NonNull String[] permissions, @NonNull int[] grantResults) {
- if (PermissionUtils.requestPermissionsResult(Manifest.permission.CAMERA, permissions, grantResults)) {
- startCamera();
- } else {
- getActivity().finish();
- }
- }
-
- @Override
- public void onDestroyView() {
- releaseCamera();
- super.onDestroyView();
- }
-
- /**
- * 返回true时会自动初始化{@link #createRootView(LayoutInflater, ViewGroup)},返回为false是需自己去初始化{@link #createRootView(LayoutInflater, ViewGroup)}
- *
- * @return 默认返回true
- */
- public boolean isContentView() {
- return true;
- }
-
- /**
- * 创建{@link #mRootView}
- *
- * @param inflater
- * @param container
- * @return
- */
- @NonNull
- public View createRootView(LayoutInflater inflater, ViewGroup container) {
- return inflater.inflate(getLayoutId(), container, false);
- }
-
- /**
- * 布局ID;通过覆写此方法可以自定义布局
- *
- * @return 布局ID
- */
- public int getLayoutId() {
- return R.layout.zxl_capture;
- }
-
- /**
- * {@link #viewfinderView} 的 ID
- *
- * @return 默认返回{@code R.id.viewfinderView}, 如果不需要扫码框可以返回0
- */
- public int getViewfinderViewId() {
- return R.id.viewfinderView;
- }
-
- /**
- * 预览界面{@link #previewView} 的ID;可通过覆写此方法自定义ID
- *
- * @return 默认返回{@code R.id.previewView}
- */
- public int getPreviewViewId() {
- return R.id.previewView;
- }
-
- /**
- * 获取 {@link #ivFlashlight} 的ID
- *
- * @return 默认返回{@code R.id.ivFlashlight}, 如果不需要手电筒按钮可以返回0
- */
- public int getFlashlightId() {
- return R.id.ivFlashlight;
- }
-
- /**
- * 获取 {@link CameraScan}
- *
- * @return {@link #mCameraScan}
- */
- public CameraScan getCameraScan() {
- return mCameraScan;
- }
-
- /**
- * 接收扫码结果回调
- *
- * @param result 扫码结果
- * @return 返回true表示拦截,将不自动执行后续逻辑,为false表示不拦截,默认不拦截
- */
- @Override
- public boolean onScanResultCallback(Result result) {
- return false;
- }
-
- //--------------------------------------------
-
- /**
- * 获取根视图
- *
- * @return {@link #mRootView}
- */
- public View getRootView() {
- return mRootView;
- }
-
-}
diff --git a/zxing-lite/src/main/java/com/king/zxing/DecodeConfig.java b/zxing-lite/src/main/java/com/king/zxing/DecodeConfig.java
index b059277..a5418fe 100644
--- a/zxing-lite/src/main/java/com/king/zxing/DecodeConfig.java
+++ b/zxing-lite/src/main/java/com/king/zxing/DecodeConfig.java
@@ -6,7 +6,6 @@ import com.google.zxing.BarcodeFormat;
import com.google.zxing.DecodeHintType;
import com.google.zxing.common.GlobalHistogramBinarizer;
import com.google.zxing.common.HybridBinarizer;
-import com.king.zxing.config.CameraConfig;
import java.util.Map;
@@ -35,7 +34,6 @@ import androidx.annotation.FloatRange;
* {@link #setAreaRectRatio(float)} 设置识别区域比例,默认{@link #DEFAULT_AREA_RECT_RATIO},设置的比例最终会在预览区域裁剪基于此比例的一个矩形进行扫码识别,优先级最低
*
* 因为{@link androidx.camera.view.PreviewView}的预览区域是经过裁剪的,所以这里的区域并不是用户所能预览到的区域,而是指Camera预览的真实区域,
- * 您还可以通过{@link CameraScan#setCameraConfig(CameraConfig)}去自定义配置{@link CameraConfig}的配置信息控制预览相关配置信息
*
* 即判定区域分析的优先级顺序为:{@link #setFullAreaScan(boolean)} -> {@link #setAnalyzeAreaRect(Rect)} -> {@link #setAreaRectRatio(float)}
* >
@@ -247,7 +245,6 @@ public class DecodeConfig {
* {@link #setAreaRectRatio(float)} 设置识别区域比例,默认{@link #DEFAULT_AREA_RECT_RATIO},设置的比例最终会在预览区域裁剪基于此比例的一个矩形进行扫码识别,优先级最低
*
* 因为{@link androidx.camera.view.PreviewView}的预览区域是经过裁剪的,所以这里的区域并不是用户所能预览到的区域,而是指Camera预览的真实区域,
- * 您还可以通过{@link CameraScan#setCameraConfig(CameraConfig)}去自定义配置{@link CameraConfig}的配置信息控制预览相关配置信息
*
* 即判定区域分析的优先级顺序为:{@link #setFullAreaScan(boolean)} -> {@link #setAnalyzeAreaRect(Rect)} -> {@link #setAreaRectRatio(float)}
* @return {@link DecodeConfig}
@@ -277,7 +274,6 @@ public class DecodeConfig {
* {@link #setAreaRectRatio(float)} 设置识别区域比例,默认{@link #DEFAULT_AREA_RECT_RATIO},设置的比例最终会在预览区域裁剪基于此比例的一个矩形进行扫码识别,优先级最低
*
* 因为{@link androidx.camera.view.PreviewView}的预览区域是经过裁剪的,所以这里的区域并不是用户所能预览到的区域,而是指Camera预览的真实区域,
- * 您还可以通过{@link CameraScan#setCameraConfig(CameraConfig)}去自定义配置{@link CameraConfig}的配置信息控制预览相关配置信息
*
* 即判定区域分析的优先级顺序为:{@link #setFullAreaScan(boolean)} -> {@link #setAnalyzeAreaRect(Rect)} -> {@link #setAreaRectRatio(float)}
* @return {@link DecodeConfig}
@@ -305,7 +301,6 @@ public class DecodeConfig {
* {@link #setAreaRectRatio(float)} 设置识别区域比例,默认{@link #DEFAULT_AREA_RECT_RATIO},设置的比例最终会在预览区域裁剪基于此比例的一个矩形进行扫码识别,优先级最低
*
* 因为{@link androidx.camera.view.PreviewView}的预览区域是经过裁剪的,所以这里的区域并不是用户所能预览到的区域,而是指Camera预览的真实区域,
- * 您还可以通过{@link CameraScan#setCameraConfig(CameraConfig)}去自定义配置{@link CameraConfig}的配置信息控制预览相关配置信息
*
* 即判定区域分析的优先级顺序为:{@link #setFullAreaScan(boolean)} -> {@link #setAnalyzeAreaRect(Rect)} -> {@link #setAreaRectRatio(float)}
* @return {@link DecodeConfig}
diff --git a/zxing-lite/src/main/java/com/king/zxing/DecodeFormatManager.java b/zxing-lite/src/main/java/com/king/zxing/DecodeFormatManager.java
index 10d6e91..f3bc97c 100644
--- a/zxing-lite/src/main/java/com/king/zxing/DecodeFormatManager.java
+++ b/zxing-lite/src/main/java/com/king/zxing/DecodeFormatManager.java
@@ -57,6 +57,10 @@ public final class DecodeFormatManager {
addDecodeHintTypes(DEFAULT_HINTS, getDefaultFormats());
}
+ private DecodeFormatManager() {
+ throw new AssertionError();
+ }
+
/**
* 所有支持的{@link BarcodeFormat}
*
diff --git a/zxing-lite/src/main/java/com/king/zxing/DefaultCameraScan.java b/zxing-lite/src/main/java/com/king/zxing/DefaultCameraScan.java
deleted file mode 100644
index c2d6971..0000000
--- a/zxing-lite/src/main/java/com/king/zxing/DefaultCameraScan.java
+++ /dev/null
@@ -1,604 +0,0 @@
-package com.king.zxing;
-
-import android.annotation.SuppressLint;
-import android.app.Activity;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.util.DisplayMetrics;
-import android.view.MotionEvent;
-import android.view.ScaleGestureDetector;
-import android.view.View;
-
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.zxing.BarcodeFormat;
-import com.google.zxing.Result;
-import com.google.zxing.ResultPoint;
-import com.google.zxing.common.detector.MathUtils;
-import com.king.zxing.analyze.Analyzer;
-import com.king.zxing.analyze.MultiFormatAnalyzer;
-import com.king.zxing.config.AspectRatioCameraConfig;
-import com.king.zxing.config.CameraConfig;
-import com.king.zxing.config.ResolutionCameraConfig;
-import com.king.zxing.manager.AmbientLightManager;
-import com.king.zxing.manager.BeepManager;
-import com.king.zxing.util.LogUtils;
-
-import java.util.concurrent.Executors;
-
-import androidx.annotation.FloatRange;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.camera.core.Camera;
-import androidx.camera.core.CameraInfo;
-import androidx.camera.core.CameraSelector;
-import androidx.camera.core.FocusMeteringAction;
-import androidx.camera.core.ImageAnalysis;
-import androidx.camera.core.MeteringPoint;
-import androidx.camera.core.Preview;
-import androidx.camera.core.TorchState;
-import androidx.camera.core.ZoomState;
-import androidx.camera.lifecycle.ProcessCameraProvider;
-import androidx.camera.view.PreviewView;
-import androidx.core.content.ContextCompat;
-import androidx.fragment.app.Fragment;
-import androidx.fragment.app.FragmentActivity;
-import androidx.lifecycle.LifecycleOwner;
-import androidx.lifecycle.MutableLiveData;
-
-/**
- * 相机扫描基类;{@link DefaultCameraScan} 为 {@link CameraScan} 的默认实现
- *
- * 快速实现扫描识别主要有以下几种方式:
- *
- * 1、通过继承 {@link CaptureActivity}或者{@link CaptureFragment}或其子类,可快速实现扫描识别。
- * (适用于大多数场景,自定义布局时需覆写getLayoutId方法)
- *
- * 2、在你项目的Activity或者Fragment中实例化一个{@link DefaultCameraScan}。(适用于想在扫码界面写交互逻辑,又因为项目
- * 架构或其它原因,无法直接或间接继承{@link CaptureActivity}或{@link CaptureFragment}时使用)
- *
- * 3、继承{@link CameraScan}自己实现一个,可参照默认实现类{@link DefaultCameraScan},其他步骤同方式2。(高级用法,谨慎使用)
- *
- * @author Jenly
- */
-public class DefaultCameraScan extends CameraScan {
-
- /**
- * Defines the maximum duration in milliseconds between a touch pad
- * touch and release for a given touch to be considered a tap (click) as
- * opposed to a hover movement gesture.
- */
- private static final int HOVER_TAP_TIMEOUT = 150;
- /**
- * Defines the maximum distance in pixels that a touch pad touch can move
- * before being released for it to be considered a tap (click) as opposed
- * to a hover movement gesture.
- */
- private static final int HOVER_TAP_SLOP = 20;
- /**
- * 每次缩放改变的步长
- */
- private static final float ZOOM_STEP_SIZE = 0.1F;
-
- private FragmentActivity mFragmentActivity;
- private Context mContext;
- private LifecycleOwner mLifecycleOwner;
- /**
- * 预览视图
- */
- private PreviewView mPreviewView;
-
- private ListenableFuture
- * 库中内置实现{@link CameraConfig}的有{@link AspectRatioCameraConfig}和{@link ResolutionCameraConfig};
- *
- * 这里简单说下各自的特点:
- *
- * {@link CameraConfig} - 默认的相机配置
- *
- * {@link AspectRatioCameraConfig} - 根据纵横比配置相机,使输出分析的图像尽可能的接近屏幕的比例
- *
- * {@link ResolutionCameraConfig} - 根据尺寸配置相机的目标图像大小,使输出分析的图像的分辨率尽可能的接近屏幕尺寸
- *
- * 当使用默认的 {@link CameraConfig}在某些机型上体验欠佳时,你可以尝试使用{@link AspectRatioCameraConfig}或
- * {@link ResolutionCameraConfig}会有意想不到奇效。
- *
- * 你也可以自定义或覆写 {@link CameraConfig} 中的 {@link #options} 方法,根据需要定制配置。
- *
- * @author Jenly
- */
-public class CameraConfig {
-
- public CameraConfig() {
-
- }
-
- /**
- * 配置 {@link Preview.Builder};可参考:{@link AspectRatioCameraConfig} 或 {@link ResolutionCameraConfig}
- *
- * 如配置目标旋转角度为90度:{@code builder.setTargetRotation(Surface.ROTATION_90)}
- *
- * 切记,外部请勿直接调用 {@link #options(Preview.Builder)}
- *
- * @param builder
- * @return
- */
- @NonNull
- public Preview options(@NonNull Preview.Builder builder) {
- return builder.build();
- }
-
- /**
- * 配置 {@link CameraSelector.Builder};可参考:{@link AspectRatioCameraConfig} 或 {@link ResolutionCameraConfig}
- *
- * 如配置前置摄像头:{@code builder.requireLensFacing(CameraSelector.LENS_FACING_FRONT)}
- *
- * 切记,外部请勿直接调用 {@link #options(CameraSelector.Builder)}
- *
- * @param builder
- * @return
- */
- @NonNull
- public CameraSelector options(@NonNull CameraSelector.Builder builder) {
- return builder.build();
- }
-
- /**
- * 配置 {@link ImageAnalysis.Builder};可参考:{@link AspectRatioCameraConfig} 或 {@link ResolutionCameraConfig}
- *
- * 如配置目标旋转角度为90度:{@code builder.setTargetRotation(Surface.ROTATION_90)}
- *
- * 切记,外部请勿直接调用 {@link #options(ImageAnalysis.Builder)}
- *
- * @param builder
- * @return
- */
- @NonNull
- public ImageAnalysis options(@NonNull ImageAnalysis.Builder builder) {
- return builder.build();
- }
-
-}
-
diff --git a/zxing-lite/src/main/java/com/king/zxing/config/ResolutionCameraConfig.java b/zxing-lite/src/main/java/com/king/zxing/config/ResolutionCameraConfig.java
deleted file mode 100644
index e8b5376..0000000
--- a/zxing-lite/src/main/java/com/king/zxing/config/ResolutionCameraConfig.java
+++ /dev/null
@@ -1,109 +0,0 @@
-package com.king.zxing.config;
-
-import android.content.Context;
-import android.util.DisplayMetrics;
-import android.util.Size;
-
-import com.king.zxing.CameraScan;
-import com.king.zxing.util.LogUtils;
-
-import java.util.Locale;
-
-import androidx.annotation.NonNull;
-import androidx.camera.core.CameraSelector;
-import androidx.camera.core.ImageAnalysis;
-import androidx.camera.core.Preview;
-
-/**
- * 相机配置:根据尺寸配置相机的目标图像大小,使输出分析的图像的分辨率尽可能的接近屏幕尺寸
- *
- * @author Jenly
- */
-public class ResolutionCameraConfig extends CameraConfig {
-
- /**
- * 1080P
- */
- public static final int IMAGE_QUALITY_1080P = 1080;
- /**
- * 720P
- */
- public static final int IMAGE_QUALITY_720P = 720;
-
- /**
- * 目标尺寸
- */
- private Size mTargetSize;
-
- /**
- * 构造
- *
- * @param context 上下文
- */
- public ResolutionCameraConfig(Context context) {
- this(context, IMAGE_QUALITY_1080P);
- }
-
- /**
- * 构造
- *
- * @param context 上下文
- * @param imageQuality 图像质量;此参数只是期望的图像质量,最终以实际计算结果为准
- */
- public ResolutionCameraConfig(Context context, int imageQuality) {
- super();
- initTargetResolutionSize(context, imageQuality);
- }
-
- /**
- * 初始化 {@link #mTargetSize}
- *
- * @param context 上下文
- * @param imageQuality 图像质量;此参数只是期望的图像质量,最终以实际计算结果为准
- */
- private void initTargetResolutionSize(Context context, int imageQuality) {
- DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
- int width = displayMetrics.widthPixels;
- int height = displayMetrics.heightPixels;
- LogUtils.d(String.format(Locale.getDefault(), "displayMetrics: %dx%d", width, height));
-
- // 因为为了保持流畅性和性能,尽可能的限制在imageQuality(默认:1080p),在此前提下尽可能的找到屏幕接近的分辨率
- if (width < height) {
- float ratio = height / (float) width;
- int size = Math.min(width, imageQuality);
- if (Math.abs(ratio - CameraScan.ASPECT_RATIO_4_3) < Math.abs(ratio - CameraScan.ASPECT_RATIO_16_9)) {
- mTargetSize = new Size(size, Math.round(size * CameraScan.ASPECT_RATIO_4_3));
- } else {
- mTargetSize = new Size(size, Math.round(size * CameraScan.ASPECT_RATIO_16_9));
- }
- } else {
- int size = Math.min(height, imageQuality);
- float ratio = width / (float) height;
- if (Math.abs(ratio - CameraScan.ASPECT_RATIO_4_3) < Math.abs(ratio - CameraScan.ASPECT_RATIO_16_9)) {
- mTargetSize = new Size(Math.round(size * CameraScan.ASPECT_RATIO_4_3), size);
- } else {
- mTargetSize = new Size(Math.round(size * CameraScan.ASPECT_RATIO_16_9), size);
- }
- }
- LogUtils.d("targetSize: " + mTargetSize);
- }
-
- @NonNull
- @Override
- public Preview options(@NonNull Preview.Builder builder) {
- return super.options(builder);
- }
-
- @NonNull
- @Override
- public CameraSelector options(@NonNull CameraSelector.Builder builder) {
- return super.options(builder);
- }
-
- @NonNull
- @Override
- public ImageAnalysis options(@NonNull ImageAnalysis.Builder builder) {
- builder.setTargetResolution(mTargetSize);
- return super.options(builder);
- }
-}
diff --git a/zxing-lite/src/main/java/com/king/zxing/manager/AmbientLightManager.java b/zxing-lite/src/main/java/com/king/zxing/manager/AmbientLightManager.java
deleted file mode 100644
index c3d94b3..0000000
--- a/zxing-lite/src/main/java/com/king/zxing/manager/AmbientLightManager.java
+++ /dev/null
@@ -1,141 +0,0 @@
-package com.king.zxing.manager;
-
-import android.content.Context;
-import android.hardware.Sensor;
-import android.hardware.SensorEvent;
-import android.hardware.SensorEventListener;
-import android.hardware.SensorManager;
-
-/**
- * 环境光线管理器:主要通过传感器来监听光线的亮度变化
- *
- * @author Jenly
- */
-public class AmbientLightManager implements SensorEventListener {
-
- private static final int INTERVAL_TIME = 200;
-
- protected static final float DARK_LUX = 45.0F;
- protected static final float BRIGHT_LUX = 100.0F;
-
- /**
- * 光线太暗时,默认:照度45 lux
- */
- private float darkLightLux = DARK_LUX;
- /**
- * 光线足够亮时,默认:照度100 lux
- */
- private float brightLightLux = BRIGHT_LUX;
-
- private SensorManager sensorManager;
- private Sensor lightSensor;
-
- private long lastTime;
-
- private boolean isLightSensorEnabled;
-
- private OnLightSensorEventListener mOnLightSensorEventListener;
-
- public AmbientLightManager(Context context) {
- sensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
- lightSensor = sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
- isLightSensorEnabled = true;
- }
-
- public void register() {
- if (sensorManager != null && lightSensor != null) {
- sensorManager.registerListener(this, lightSensor, SensorManager.SENSOR_DELAY_NORMAL);
- }
- }
-
- public void unregister() {
- if (sensorManager != null && lightSensor != null) {
- sensorManager.unregisterListener(this);
- }
- }
-
-
- @Override
- public void onSensorChanged(SensorEvent sensorEvent) {
- if (isLightSensorEnabled) {
- long currentTime = System.currentTimeMillis();
- if (currentTime - lastTime < INTERVAL_TIME) {
- // 降低频率
- return;
- }
- lastTime = currentTime;
-
- if (mOnLightSensorEventListener != null) {
- float lightLux = sensorEvent.values[0];
- mOnLightSensorEventListener.onSensorChanged(lightLux);
- if (lightLux <= darkLightLux) {
- mOnLightSensorEventListener.onSensorChanged(true, lightLux);
- } else if (lightLux >= brightLightLux) {
- mOnLightSensorEventListener.onSensorChanged(false, lightLux);
- }
- }
- }
- }
-
- /**
- * 设置光线足够暗的阈值(单位:lux)
- *
- * @param lightLux
- */
- public void setDarkLightLux(float lightLux) {
- this.darkLightLux = lightLux;
- }
-
- /**
- * 设置光线足够明亮的阈值(单位:lux)
- *
- * @param lightLux
- */
- public void setBrightLightLux(float lightLux) {
- this.brightLightLux = lightLux;
- }
-
- @Override
- public void onAccuracyChanged(Sensor sensor, int accuracy) {
- // do nothing
- }
-
- public boolean isLightSensorEnabled() {
- return isLightSensorEnabled;
- }
-
- /**
- * 设置是否启用光线亮度传感器
- *
- * @param lightSensorEnabled
- */
- public void setLightSensorEnabled(boolean lightSensorEnabled) {
- isLightSensorEnabled = lightSensorEnabled;
- }
-
- /**
- * 设置光线亮度传感器监听器,只有在 {@link #isLightSensorEnabled} 为{@code true} 才有效
- *
- * @param listener
- */
- public void setOnLightSensorEventListener(OnLightSensorEventListener listener) {
- mOnLightSensorEventListener = listener;
- }
-
- public interface OnLightSensorEventListener {
- /**
- * @param lightLux 当前检测到的光线照度值
- */
- default void onSensorChanged(float lightLux) {
-
- }
-
- /**
- * 传感器改变事件
- *
- * @param dark 是否太暗了,当检测到的光线照度值小于{@link #darkLightLux}时,为{@code true}
- * @param lightLux 当前检测到的光线照度值
- */
- void onSensorChanged(boolean dark, float lightLux);
- }
-}
\ No newline at end of file
diff --git a/zxing-lite/src/main/java/com/king/zxing/manager/BeepManager.java b/zxing-lite/src/main/java/com/king/zxing/manager/BeepManager.java
deleted file mode 100644
index e36dbe2..0000000
--- a/zxing-lite/src/main/java/com/king/zxing/manager/BeepManager.java
+++ /dev/null
@@ -1,101 +0,0 @@
-package com.king.zxing.manager;
-
-import android.content.Context;
-import android.content.res.AssetFileDescriptor;
-import android.media.MediaPlayer;
-import android.os.Build;
-import android.os.VibrationEffect;
-import android.os.Vibrator;
-
-import com.king.zxing.R;
-import com.king.zxing.util.LogUtils;
-
-import java.io.Closeable;
-
-/**
- * 蜂鸣音效管理器:主要用于播放蜂鸣提示音和振动效果
- *
- * @author Jenly
- */
-public final class BeepManager implements MediaPlayer.OnErrorListener, Closeable {
-
- private static final long VIBRATE_DURATION = 200L;
-
- private final Context context;
- private MediaPlayer mediaPlayer;
- private Vibrator vibrator;
- private boolean playBeep;
- private boolean vibrate;
-
- public BeepManager(Context context) {
- this.context = context;
- this.mediaPlayer = null;
- updatePrefs();
- }
-
- public void setVibrate(boolean vibrate) {
- this.vibrate = vibrate;
- }
-
- public void setPlayBeep(boolean playBeep) {
- this.playBeep = playBeep;
- }
-
- private synchronized void updatePrefs() {
- if (mediaPlayer == null) {
- mediaPlayer = buildMediaPlayer(context);
- }
- if (vibrator == null) {
- vibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
- }
- }
-
- public synchronized void playBeepSoundAndVibrate() {
- if (playBeep && mediaPlayer != null) {
- mediaPlayer.start();
- }
- if (vibrate && vibrator.hasVibrator()) {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
- vibrator.vibrate(VibrationEffect.createOneShot(VIBRATE_DURATION, VibrationEffect.DEFAULT_AMPLITUDE));
- } else {
- vibrator.vibrate(VIBRATE_DURATION);
- }
- }
- }
-
- private MediaPlayer buildMediaPlayer(Context context) {
- MediaPlayer mediaPlayer = new MediaPlayer();
- try {
- AssetFileDescriptor file = context.getResources().openRawResourceFd(R.raw.zxl_beep);
- mediaPlayer.setDataSource(file.getFileDescriptor(), file.getStartOffset(), file.getLength());
- mediaPlayer.setOnErrorListener(this);
- mediaPlayer.setLooping(false);
- mediaPlayer.prepare();
- return mediaPlayer;
- } catch (Exception e) {
- LogUtils.w(e);
- mediaPlayer.release();
- return null;
- }
- }
-
- @Override
- public synchronized boolean onError(MediaPlayer mp, int what, int extra) {
- close();
- updatePrefs();
- return true;
- }
-
- @Override
- public synchronized void close() {
- try {
- if (mediaPlayer != null) {
- mediaPlayer.release();
- mediaPlayer = null;
- }
- } catch (Exception e) {
- LogUtils.e(e);
- }
- }
-
-}
\ No newline at end of file
diff --git a/zxing-lite/src/main/java/com/king/zxing/util/BitmapUtils.java b/zxing-lite/src/main/java/com/king/zxing/util/BitmapUtils.java
deleted file mode 100644
index 19f7c77..0000000
--- a/zxing-lite/src/main/java/com/king/zxing/util/BitmapUtils.java
+++ /dev/null
@@ -1,273 +0,0 @@
-package com.king.zxing.util;
-
-import android.annotation.SuppressLint;
-import android.content.ContentResolver;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.graphics.ImageFormat;
-import android.graphics.Matrix;
-import android.graphics.Rect;
-import android.graphics.YuvImage;
-import android.media.ExifInterface;
-import android.media.Image;
-import android.net.Uri;
-import android.os.Build;
-import android.provider.MediaStore;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.ByteBuffer;
-
-import androidx.annotation.Nullable;
-import androidx.annotation.RequiresApi;
-import androidx.camera.core.ImageProxy;
-
-/**
- * Utils functions for bitmap conversions.
- *
- * @see BitmapUtils
- */
-public class BitmapUtils {
-
- private BitmapUtils() {
- throw new AssertionError();
- }
-
- /**
- * Converts NV21 format byte buffer to bitmap.
- */
- @Nullable
- public static Bitmap getBitmap(ByteBuffer data, int width, int height, int rotationDegrees) {
- data.rewind();
- byte[] imageInBuffer = new byte[data.limit()];
- data.get(imageInBuffer, 0, imageInBuffer.length);
- try {
- YuvImage image = new YuvImage(
- imageInBuffer, ImageFormat.NV21, width, height, null);
- ByteArrayOutputStream stream = new ByteArrayOutputStream();
- image.compressToJpeg(new Rect(0, 0, width, height), 80, stream);
-
- Bitmap bmp = BitmapFactory.decodeByteArray(stream.toByteArray(), 0, stream.size());
-
- stream.close();
- return rotateBitmap(bmp, rotationDegrees, false, false);
- } catch (Exception e) {
- LogUtils.e("Error: " + e.getMessage());
- }
- return null;
- }
-
- /**
- * Converts a YUV_420_888 image from CameraX API to a bitmap.
- */
- @Nullable
- public static Bitmap getBitmap(ImageProxy image) {
-
- @SuppressLint("UnsafeOptInUsageError")
- ByteBuffer nv21Buffer = yuv420ThreePlanesToNV21(image.getImage().getPlanes(), image.getWidth(), image.getHeight());
- return getBitmap(nv21Buffer, image.getWidth(), image.getHeight(), image.getImageInfo().getRotationDegrees());
- }
-
- /**
- * Rotates a bitmap if it is converted from a bytebuffer.
- */
- private static Bitmap rotateBitmap(
- Bitmap bitmap, int rotationDegrees, boolean flipX, boolean flipY) {
- Matrix matrix = new Matrix();
-
- // Rotate the image back to straight.
- matrix.postRotate(rotationDegrees);
-
- // Mirror the image along the X or Y axis.
- matrix.postScale(flipX ? -1.0f : 1.0f, flipY ? -1.0f : 1.0f);
- Bitmap rotatedBitmap =
- Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
-
- // Recycle the old bitmap if it has changed.
- if (rotatedBitmap != bitmap) {
- bitmap.recycle();
- }
- return rotatedBitmap;
- }
-
- @RequiresApi(api = Build.VERSION_CODES.N)
- @Nullable
- public static Bitmap getBitmapFromContentUri(ContentResolver contentResolver, Uri imageUri)
- throws IOException {
- Bitmap decodedBitmap = MediaStore.Images.Media.getBitmap(contentResolver, imageUri);
- if (decodedBitmap == null) {
- return null;
- }
- int orientation = getExifOrientationTag(contentResolver, imageUri);
-
- int rotationDegrees = 0;
- boolean flipX = false;
- boolean flipY = false;
- // See e.g. https://magnushoff.com/articles/jpeg-orientation/ for a detailed explanation on each
- // orientation.
- switch (orientation) {
- case ExifInterface.ORIENTATION_FLIP_HORIZONTAL:
- flipX = true;
- break;
- case ExifInterface.ORIENTATION_ROTATE_90:
- rotationDegrees = 90;
- break;
- case ExifInterface.ORIENTATION_TRANSPOSE:
- rotationDegrees = 90;
- flipX = true;
- break;
- case ExifInterface.ORIENTATION_ROTATE_180:
- rotationDegrees = 180;
- break;
- case ExifInterface.ORIENTATION_FLIP_VERTICAL:
- flipY = true;
- break;
- case ExifInterface.ORIENTATION_ROTATE_270:
- rotationDegrees = -90;
- break;
- case ExifInterface.ORIENTATION_TRANSVERSE:
- rotationDegrees = -90;
- flipX = true;
- break;
- case ExifInterface.ORIENTATION_UNDEFINED:
- case ExifInterface.ORIENTATION_NORMAL:
- default:
- // No transformations necessary in this case.
- }
-
- return rotateBitmap(decodedBitmap, rotationDegrees, flipX, flipY);
- }
-
- @RequiresApi(api = Build.VERSION_CODES.N)
- private static int getExifOrientationTag(ContentResolver resolver, Uri imageUri) {
- // We only support parsing EXIF orientation tag from local file on the device.
- // See also:
- // https://android-developers.googleblog.com/2016/12/introducing-the-exifinterface-support-library.html
- if (!ContentResolver.SCHEME_CONTENT.equals(imageUri.getScheme())
- && !ContentResolver.SCHEME_FILE.equals(imageUri.getScheme())) {
- return 0;
- }
-
- ExifInterface exif;
- try (InputStream inputStream = resolver.openInputStream(imageUri)) {
- if (inputStream == null) {
- return 0;
- }
-
- exif = new ExifInterface(inputStream);
- } catch (IOException e) {
- LogUtils.e("failed to open file to read rotation meta data: " + imageUri, e);
- return 0;
- }
-
- return exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
- }
-
- /**
- * Converts YUV_420_888 to NV21 bytebuffer.
- *
- * The NV21 format consists of a single byte array containing the Y, U and V values. For an
- * image of size S, the first S positions of the array contain all the Y values. The remaining
- * positions contain interleaved V and U values. U and V are subsampled by a factor of 2 in both
- * dimensions, so there are S/4 U values and S/4 V values. In summary, the NV21 array will contain
- * S Y values followed by S/4 VU values: YYYYYYYYYYYYYY(...)YVUVUVUVU(...)VU
- *
- * YUV_420_888 is a generic format that can describe any YUV image where U and V are subsampled
- * by a factor of 2 in both dimensions. {@link Image#getPlanes} returns an array with the Y, U and
- * V planes. The Y plane is guaranteed not to be interleaved, so we can just copy its values into
- * the first part of the NV21 array. The U and V planes may already have the representation in the
- * NV21 format. This happens if the planes share the same buffer, the V buffer is one position
- * before the U buffer and the planes have a pixelStride of 2. If this is case, we can just copy
- * them to the NV21 array.
- */
- public static ByteBuffer yuv420ThreePlanesToNV21(Image.Plane[] yuv420888planes, int width, int height) {
- int imageSize = width * height;
- byte[] out = new byte[imageSize + 2 * (imageSize / 4)];
-
- if (areUVPlanesNV21(yuv420888planes, width, height)) {
- // Copy the Y values.
- yuv420888planes[0].getBuffer().get(out, 0, imageSize);
-
- ByteBuffer uBuffer = yuv420888planes[1].getBuffer();
- ByteBuffer vBuffer = yuv420888planes[2].getBuffer();
- // Get the first V value from the V buffer, since the U buffer does not contain it.
- vBuffer.get(out, imageSize, 1);
- // Copy the first U value and the remaining VU values from the U buffer.
- uBuffer.get(out, imageSize + 1, 2 * imageSize / 4 - 1);
- } else {
- // Fallback to copying the UV values one by one, which is slower but also works.
- // Unpack Y.
- unpackPlane(yuv420888planes[0], width, height, out, 0, 1);
- // Unpack U.
- unpackPlane(yuv420888planes[1], width, height, out, imageSize + 1, 2);
- // Unpack V.
- unpackPlane(yuv420888planes[2], width, height, out, imageSize, 2);
- }
-
- return ByteBuffer.wrap(out);
- }
-
- /**
- * Checks if the UV plane buffers of a YUV_420_888 image are in the NV21 format.
- */
- private static boolean areUVPlanesNV21(Image.Plane[] planes, int width, int height) {
- int imageSize = width * height;
-
- ByteBuffer uBuffer = planes[1].getBuffer();
- ByteBuffer vBuffer = planes[2].getBuffer();
-
- // Backup buffer properties.
- int vBufferPosition = vBuffer.position();
- int uBufferLimit = uBuffer.limit();
-
- // Advance the V buffer by 1 byte, since the U buffer will not contain the first V value.
- vBuffer.position(vBufferPosition + 1);
- // Chop off the last byte of the U buffer, since the V buffer will not contain the last U value.
- uBuffer.limit(uBufferLimit - 1);
-
- // Check that the buffers are equal and have the expected number of elements.
- boolean areNV21 =
- (vBuffer.remaining() == (2 * imageSize / 4 - 2)) && (vBuffer.compareTo(uBuffer) == 0);
-
- // Restore buffers to their initial state.
- vBuffer.position(vBufferPosition);
- uBuffer.limit(uBufferLimit);
-
- return areNV21;
- }
-
- /**
- * Unpack an image plane into a byte array.
- *
- * The input plane data will be copied in 'out', starting at 'offset' and every pixel will be
- * spaced by 'pixelStride'. Note that there is no row padding on the output.
- */
- private static void unpackPlane(
- Image.Plane plane, int width, int height, byte[] out, int offset, int pixelStride) {
- ByteBuffer buffer = plane.getBuffer();
- buffer.rewind();
-
- // Compute the size of the current plane.
- // We assume that it has the aspect ratio as the original image.
- int numRow = (buffer.limit() + plane.getRowStride() - 1) / plane.getRowStride();
- if (numRow == 0) {
- return;
- }
- int scaleFactor = height / numRow;
- int numCol = width / scaleFactor;
-
- // Extract the data in the output buffer.
- int outputPos = offset;
- int rowStart = 0;
- for (int row = 0; row < numRow; row++) {
- int inputPos = rowStart;
- for (int col = 0; col < numCol; col++) {
- out[outputPos] = buffer.get(inputPos);
- outputPos += pixelStride;
- inputPos += plane.getPixelStride();
- }
- rowStart += plane.getRowStride();
- }
- }
-}
diff --git a/zxing-lite/src/main/java/com/king/zxing/util/CodeUtils.java b/zxing-lite/src/main/java/com/king/zxing/util/CodeUtils.java
index 7d9be52..c594382 100644
--- a/zxing-lite/src/main/java/com/king/zxing/util/CodeUtils.java
+++ b/zxing-lite/src/main/java/com/king/zxing/util/CodeUtils.java
@@ -43,6 +43,7 @@ import com.google.zxing.common.GlobalHistogramBinarizer;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
+import com.king.camera.scan.util.LogUtils;
import com.king.zxing.DecodeFormatManager;
import java.util.HashMap;
diff --git a/zxing-lite/src/main/java/com/king/zxing/util/LogUtils.java b/zxing-lite/src/main/java/com/king/zxing/util/LogUtils.java
deleted file mode 100644
index 3007af9..0000000
--- a/zxing-lite/src/main/java/com/king/zxing/util/LogUtils.java
+++ /dev/null
@@ -1,327 +0,0 @@
-/*
- Copyright © 2015, 2016 Jenly Yu Jenly
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-package com.king.zxing.util;
-
-import android.util.Log;
-
-import java.util.Locale;
-
-/**
- * @author Jenly Jenly
- */
-public class LogUtils {
-
- public static final String TAG = "ZXingLite";
-
- public static final String VERTICAL = "|";
-
- /**
- * 是否显示Log日志
- */
- private static boolean isShowLog = true;
-
- /**
- * Log日志优先权
- */
- private static int priority = 1;
-
- /**
- * Priority constant for the println method;use System.out.println
- */
- public static final int PRINTLN = 1;
-
- /**
- * Priority constant for the println method; use Log.v.
- */
- public static final int VERBOSE = 2;
-
- /**
- * Priority constant for the println method; use Log.d.
- */
- public static final int DEBUG = 3;
-
- /**
- * Priority constant for the println method; use Log.i.
- */
- public static final int INFO = 4;
-
- /**
- * Priority constant for the println method; use Log.w.
- */
- public static final int WARN = 5;
-
- /**
- * Priority constant for the println method; use Log.e.
- */
- public static final int ERROR = 6;
-
- /**
- * Priority constant for the println method.use Log.wtf.
- */
- public static final int ASSERT = 7;
-
- public static final String TAG_FORMAT = "%s.%s(%s:%d)";
-
- private LogUtils() {
- throw new AssertionError();
- }
-
- public static void setShowLog(boolean isShowLog) {
-
- LogUtils.isShowLog = isShowLog;
- }
-
- public static boolean isShowLog() {
-
- return isShowLog;
- }
-
- public static int getPriority() {
-
- return priority;
- }
-
- public static void setPriority(int priority) {
-
- LogUtils.priority = priority;
- }
-
- /**
- * 根据堆栈生成TAG
- *
- * @return TAG|className.methodName(fileName:lineNumber)
- */
- private static String generateTag(StackTraceElement caller) {
- String tag = TAG_FORMAT;
- String callerClazzName = caller.getClassName();
- callerClazzName = callerClazzName.substring(callerClazzName.lastIndexOf(".") + 1);
- tag = String.format(Locale.getDefault(), tag, callerClazzName, caller.getMethodName(), caller.getFileName(), caller.getLineNumber());
- return new StringBuilder().append(TAG).append(VERTICAL).append(tag).toString();
- }
-
- /**
- * 获取堆栈
- *
- * @param n n=0 VMStack
- * n=1 Thread
- * n=3 CurrentStack
- * n=4 CallerStack
- * ...
- * @return
- */
- public static StackTraceElement getStackTraceElement(int n) {
- return Thread.currentThread().getStackTrace()[n];
- }
-
- /**
- * 获取调用方的堆栈TAG
- *
- * @return
- */
- private static String getCallerStackLogTag() {
- return generateTag(getStackTraceElement(5));
- }
-
- /**
- * @param t
- * @return
- */
- private static String getStackTraceString(Throwable t) {
- return Log.getStackTraceString(t);
- }
-
- // -----------------------------------Log.v
-
- /**
- * Log.v
- *
- * @param msg
- */
- public static void v(String msg) {
- if (isShowLog && priority <= VERBOSE)
- Log.v(getCallerStackLogTag(), String.valueOf(msg));
-
- }
-
- public static void v(Throwable t) {
- if (isShowLog && priority <= VERBOSE)
- Log.v(getCallerStackLogTag(), getStackTraceString(t));
- }
-
- public static void v(String msg, Throwable t) {
- if (isShowLog && priority <= VERBOSE)
- Log.v(getCallerStackLogTag(), String.valueOf(msg), t);
- }
-
- // -----------------------------------Log.d
-
- /**
- * Log.d
- *
- * @param msg
- */
- public static void d(String msg) {
- if (isShowLog && priority <= DEBUG)
- Log.d(getCallerStackLogTag(), String.valueOf(msg));
- }
-
- public static void d(Throwable t) {
- if (isShowLog && priority <= DEBUG)
- Log.d(getCallerStackLogTag(), getStackTraceString(t));
- }
-
- public static void d(String msg, Throwable t) {
- if (isShowLog && priority <= DEBUG)
- Log.d(getCallerStackLogTag(), String.valueOf(msg), t);
- }
-
- // -----------------------------------Log.i
-
- /**
- * Log.i
- *
- * @param msg
- */
- public static void i(String msg) {
- if (isShowLog && priority <= INFO)
- Log.i(getCallerStackLogTag(), String.valueOf(msg));
- }
-
- public static void i(Throwable t) {
- if (isShowLog && priority <= INFO)
- Log.i(getCallerStackLogTag(), getStackTraceString(t));
- }
-
- public static void i(String msg, Throwable t) {
- if (isShowLog && priority <= INFO)
- Log.i(getCallerStackLogTag(), String.valueOf(msg), t);
- }
-
- // -----------------------------------Log.w
-
- /**
- * Log.w
- *
- * @param msg
- */
- public static void w(String msg) {
- if (isShowLog && priority <= WARN)
- Log.w(getCallerStackLogTag(), String.valueOf(msg));
- }
-
- public static void w(Throwable t) {
- if (isShowLog && priority <= WARN)
- Log.w(getCallerStackLogTag(), getStackTraceString(t));
- }
-
- public static void w(String msg, Throwable t) {
- if (isShowLog && priority <= WARN)
- Log.w(getCallerStackLogTag(), String.valueOf(msg), t);
- }
-
- // -----------------------------------Log.e
-
- /**
- * Log.e
- *
- * @param msg
- */
- public static void e(String msg) {
- if (isShowLog && priority <= ERROR)
- Log.e(getCallerStackLogTag(), String.valueOf(msg));
- }
-
- public static void e(Throwable t) {
- if (isShowLog && priority <= ERROR)
- Log.e(getCallerStackLogTag(), getStackTraceString(t));
- }
-
- public static void e(String msg, Throwable t) {
- if (isShowLog && priority <= ERROR)
- Log.e(getCallerStackLogTag(), String.valueOf(msg), t);
- }
-
- // -----------------------------------Log.wtf
-
- /**
- * Log.wtf
- *
- * @param msg
- */
- public static void wtf(String msg) {
- if (isShowLog && priority <= ASSERT)
- Log.wtf(getCallerStackLogTag(), String.valueOf(msg));
- }
-
- public static void wtf(Throwable t) {
- if (isShowLog && priority <= ASSERT)
- Log.wtf(getCallerStackLogTag(), getStackTraceString(t));
- }
-
- public static void wtf(String msg, Throwable t) {
- if (isShowLog && priority <= ASSERT)
- Log.wtf(getCallerStackLogTag(), String.valueOf(msg), t);
- }
-
- // -----------------------------------System.out.print
-
- /**
- * System.out.print
- *
- * @param msg
- */
- public static void print(String msg) {
- if (isShowLog && priority <= PRINTLN)
- System.out.print(msg);
- }
-
- public static void print(Object obj) {
- if (isShowLog && priority <= PRINTLN)
- System.out.print(obj);
- }
-
- // -----------------------------------System.out.printf
-
- /**
- * System.out.printf
- *
- * @param msg
- */
- public static void printf(String msg) {
- if (isShowLog && priority <= PRINTLN)
- System.out.printf(msg);
- }
-
- // -----------------------------------System.out.println
-
- /**
- * System.out.println
- *
- * @param msg
- */
- public static void println(String msg) {
- if (isShowLog && priority <= PRINTLN)
- System.out.println(msg);
- }
-
- public static void println(Object obj) {
- if (isShowLog && priority <= PRINTLN)
- System.out.println(obj);
- }
-
-}
-
diff --git a/zxing-lite/src/main/java/com/king/zxing/util/PermissionUtils.java b/zxing-lite/src/main/java/com/king/zxing/util/PermissionUtils.java
deleted file mode 100644
index 88b406f..0000000
--- a/zxing-lite/src/main/java/com/king/zxing/util/PermissionUtils.java
+++ /dev/null
@@ -1,118 +0,0 @@
-package com.king.zxing.util;
-
-import android.app.Activity;
-import android.content.Context;
-import android.content.pm.PackageManager;
-
-import androidx.annotation.IntRange;
-import androidx.annotation.NonNull;
-import androidx.core.app.ActivityCompat;
-import androidx.fragment.app.Fragment;
-
-/**
- * @author Jenly
- */
-public class PermissionUtils {
-
- private PermissionUtils() {
- throw new AssertionError();
- }
-
- /**
- * 检测是否授权
- *
- * @param context
- * @param permission
- * @return 返回{@code true} 表示已授权,{@code false}表示未授权
- */
- public static boolean checkPermission(@NonNull Context context, @NonNull String permission) {
- return ActivityCompat.checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED;
- }
-
- /**
- * 请求权限
- *
- * @param activity
- * @param permission
- * @param requestCode
- */
- public static void requestPermission(@NonNull Activity activity, @NonNull String permission, @IntRange(from = 0) int requestCode) {
- requestPermissions(activity, new String[]{permission}, requestCode);
- }
-
- /**
- * 请求权限
- *
- * @param fragment
- * @param permission
- * @param requestCode
- */
- public static void requestPermission(@NonNull Fragment fragment, @NonNull String permission, @IntRange(from = 0) int requestCode) {
- requestPermissions(fragment, new String[]{permission}, requestCode);
- }
-
- /**
- * 请求权限
- *
- * @param activity
- * @param permissions
- * @param requestCode
- */
- public static void requestPermissions(@NonNull Activity activity, @NonNull String[] permissions, @IntRange(from = 0) int requestCode) {
- ActivityCompat.requestPermissions(activity, permissions, requestCode);
- }
-
- /**
- * 请求权限
- *
- * @param fragment
- * @param permissions
- * @param requestCode
- */
- public static void requestPermissions(@NonNull Fragment fragment, @NonNull String[] permissions, @IntRange(from = 0) int requestCode) {
- fragment.requestPermissions(permissions, requestCode);
- }
-
- /**
- * 请求权限结果
- *
- * @param requestPermission 请求的权限
- * @param permissions
- * @param grantResults
- * @return 返回{@code true} 表示已授权,{@code false}表示未授权
- */
- public static boolean requestPermissionsResult(@NonNull String requestPermission, @NonNull String[] permissions, @NonNull int[] grantResults) {
- int length = permissions.length;
- for (int i = 0; i < length; i++) {
- if (requestPermission.equals(permissions[i])) {
- if (grantResults[i] == PackageManager.PERMISSION_GRANTED) {
- return true;
- }
- }
- }
- return false;
- }
-
- /**
- * 请求权限结果
- *
- * @param requestPermissions 请求的权限
- * @param permissions
- * @param grantResults
- * @return 返回{@code true} 表示全部已授权,{@code false}表示未全部授权
- */
- public static boolean requestPermissionsResult(@NonNull String[] requestPermissions, @NonNull String[] permissions, @NonNull int[] grantResults) {
- int length = permissions.length;
- for (int i = 0; i < length; i++) {
- for (int j = 0; j < requestPermissions.length; j++) {
- if (requestPermissions[j].equals(permissions[i])) {
- if (grantResults[i] != PackageManager.PERMISSION_GRANTED) {
- return false;
- }
- }
- }
- }
- return true;
- }
-
-}
diff --git a/zxing-lite/src/main/res/drawable/zxl_flashlight_off.xml b/zxing-lite/src/main/res/drawable/zxl_flashlight_off.xml
deleted file mode 100644
index 938acbd..0000000
--- a/zxing-lite/src/main/res/drawable/zxl_flashlight_off.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-