Skip to content

Commit

Permalink
Merge pull request #2 from iamlfc/master
Browse files Browse the repository at this point in the history
优化图片识别逻辑
  • Loading branch information
hpuhsp authored Sep 8, 2021
2 parents 5d9679c + b3a00f7 commit 11d1204
Show file tree
Hide file tree
Showing 5 changed files with 307 additions and 18 deletions.
3 changes: 2 additions & 1 deletion app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,13 @@
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />

<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:requestLegacyExternalStorage="true"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.QRScanner">
Expand Down
14 changes: 8 additions & 6 deletions scanner/src/main/java/com/hnsh/scanner/CaptureActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,25 +42,25 @@
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;

import com.hnsh.scanner.decode.DecodeHandler;
import com.hnsh.scanner.decode.DecodeThread;
import com.hnsh.scanner.zbarUtils.Constants;
import com.hnsh.scanner.zbarUtils.camera.CameraManager;
import com.hnsh.scanner.zbarUtils.utils.BeepManager;
import com.hnsh.scanner.zbarUtils.utils.FileUtils;
import com.hnsh.scanner.zbarUtils.utils.InactivityTimer;
import com.hnsh.scanner.zbarUtils.utils.QRCodeParseUtils;
import com.hnsh.scanner.zbarUtils.utils.ReplacerUtils;
import com.hnsh.scanner.zbarUtils.utils.FileUtils;
import com.hnsh.scanner.zbarUtils.utils.ThreadUtils;

import java.lang.ref.WeakReference;
import java.lang.reflect.Field;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;

/**
* This activity opens the camera and does the actual scanning on a background
* thread. It draws a viewfinder to help the user place the barcode correctly,
Expand Down Expand Up @@ -323,6 +323,8 @@ protected void onActivityResult(int requestCode, int resultCode, @Nullable @org.
if (null != data && null != data.getData()) {
String path = FileUtils.getRealPathFromUri(CaptureActivity.this, data.getData());
if (null != path && !path.isEmpty()) {
// String strResult = BitmapUtils.parseQRcode(path);
// Log.d("TAG", "strResult: " + strResult);
new QrCodeAsyncTask(this, path, data.getData()).execute(path);
} else {
Toast.makeText(CaptureActivity.this, "获取图片路径失败!", Toast.LENGTH_SHORT).show();
Expand Down
113 changes: 113 additions & 0 deletions scanner/src/main/java/com/hnsh/scanner/utils/BitmapUtils.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
package com.hnsh.scanner.utils;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;

import com.google.zxing.BinaryBitmap;
import com.google.zxing.ChecksumException;
import com.google.zxing.DecodeHintType;
import com.google.zxing.FormatException;
import com.google.zxing.NotFoundException;
import com.google.zxing.RGBLuminanceSource;
import com.google.zxing.Result;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.qrcode.QRCodeReader;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.EnumMap;
import java.util.Map;

/**
* @author ansen
* @create time 2018/10/25
*/
public class BitmapUtils {
/**
* 解析二维码图片
* @param bitmapPath 文件路径
* @return
*/
public static String parseQRcode(String bitmapPath){
Bitmap bitmap = BitmapFactory.decodeFile(bitmapPath, null);
String result=parseQRcode(bitmap);
return result;
}

public static String parseQRcode(Bitmap bmp){
bmp=comp(bmp);//bitmap压缩 如果不压缩的话在低配置的手机上解码很慢

int width = bmp.getWidth();//图片宽度
int height = bmp.getHeight();//图片高度
int[] pixels = new int[width * height];
bmp.getPixels(pixels, 0, width, 0, 0, width, height);

QRCodeReader reader = new QRCodeReader();
Map<DecodeHintType, Object> hints = new EnumMap<>(DecodeHintType.class);
hints.put(DecodeHintType.TRY_HARDER, Boolean.TRUE);//优化精度
hints.put(DecodeHintType.CHARACTER_SET,"utf-8");//解码设置编码方式为:utf-8
try {
Result result = reader.decode(new BinaryBitmap(new HybridBinarizer(new RGBLuminanceSource(width, height, pixels))), hints);
return result.getText();
} catch (NotFoundException e) {
Log.i("ansen",""+e.toString());
e.printStackTrace();
} catch (ChecksumException e) {
e.printStackTrace();
} catch (FormatException e) {
e.printStackTrace();
}
return null;
}

//图片按比例大小压缩方法(根据Bitmap图片压缩)
private static Bitmap comp(Bitmap image) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
image.compress(Bitmap.CompressFormat.JPEG, 100, baos);
if( baos.toByteArray().length / 1024>1024) {//判断如果图片大于1M,进行压缩避免在生成图片(BitmapFactory.decodeStream)时溢出
baos.reset();//重置baos即清空baos
image.compress(Bitmap.CompressFormat.JPEG, 50, baos);//这里压缩50%,把压缩后的数据存放到baos中
}
ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());
BitmapFactory.Options newOpts = new BitmapFactory.Options();
//开始读入图片,此时把options.inJustDecodeBounds 设回true了
newOpts.inJustDecodeBounds = true;
Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, newOpts);
newOpts.inJustDecodeBounds = false;
int w = newOpts.outWidth;
int h = newOpts.outHeight;
//现在主流手机比较多是800*480分辨率,所以高和宽我们设置为
float hh = 400f;//这里设置高度为800f
float ww = 400f;//这里设置宽度为480f
//缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可
int be = 1;//be=1表示不缩放
if (w > h && w > ww) {//如果宽度大的话根据宽度固定大小缩放
be = (int) (newOpts.outWidth / ww);
} else if (w < h && h > hh) {//如果高度高的话根据宽度固定大小缩放
be = (int) (newOpts.outHeight / hh);
}
if (be <= 0)
be = 1;
newOpts.inSampleSize = be;//设置缩放比例
//重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了
isBm = new ByteArrayInputStream(baos.toByteArray());
bitmap = BitmapFactory.decodeStream(isBm, null, newOpts);
return compressImage(bitmap);//压缩好比例大小后再进行质量压缩
}

//质量压缩方法
private static Bitmap compressImage(Bitmap image) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
image.compress(Bitmap.CompressFormat.JPEG, 100, baos);//质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中
int options = 100;
while (baos.toByteArray().length/1024>100) { //循环判断如果压缩后图片是否大于100kb,大于继续压缩
baos.reset();//重置baos即清空baos
image.compress(Bitmap.CompressFormat.JPEG, options, baos);//这里压缩options%,把压缩后的数据存放到baos中
options -= 10;//每次都减少10
}
ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());//把压缩后的数据baos存放到ByteArrayInputStream中
Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);//把ByteArrayInputStream数据生成图片
return bitmap;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
import android.os.Environment;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
import android.util.Log;

import java.io.File;
import java.io.FileFilter;
Expand Down Expand Up @@ -87,6 +86,8 @@ public static String getRealPathFromUri(Context context, Uri uri) {
private static String getRealPathFromUriAboveApiAndroidQ(Context context, Uri uri) {
Cursor cursor = null;
String path = getRealPathFromUriAboveApiAndroidK(context, uri);
if (true)
return path;
try {
cursor = context.getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
new String[]{MediaStore.Images.Media._ID}, MediaStore.Images.Media.DATA + "=? ",
Expand Down Expand Up @@ -216,19 +217,24 @@ public boolean accept(File pathname) {
* @return {@code true}: success<br>{@code false}: fail
*/
public static boolean deleteFilesInDirWithFilter(final File dir, final FileFilter filter) {
if (dir == null || filter == null) return false;
if (dir == null || filter == null)
return false;
// dir doesn't exist then return true
if (!dir.exists()) return true;
if (!dir.exists())
return true;
// dir isn't a directory then return false
if (!dir.isDirectory()) return false;
if (!dir.isDirectory())
return false;
File[] files = dir.listFiles();
if (files != null && files.length != 0) {
for (File file : files) {
if (filter.accept(file)) {
if (file.isFile()) {
if (!file.delete()) return false;
if (!file.delete())
return false;
} else if (file.isDirectory()) {
if (!deleteDir(file)) return false;
if (!deleteDir(file))
return false;
}
}
}
Expand All @@ -243,18 +249,23 @@ public static boolean deleteFilesInDirWithFilter(final File dir, final FileFilte
* @return {@code true}: success<br>{@code false}: fail
*/
private static boolean deleteDir(final File dir) {
if (dir == null) return false;
if (dir == null)
return false;
// dir doesn't exist then return true
if (!dir.exists()) return true;
if (!dir.exists())
return true;
// dir isn't a directory then return false
if (!dir.isDirectory()) return false;
if (!dir.isDirectory())
return false;
File[] files = dir.listFiles();
if (files != null && files.length > 0) {
for (File file : files) {
if (file.isFile()) {
if (!file.delete()) return false;
if (!file.delete())
return false;
} else if (file.isDirectory()) {
if (!deleteDir(file)) return false;
if (!deleteDir(file))
return false;
}
}
}
Expand Down
Loading

0 comments on commit 11d1204

Please sign in to comment.