version:
bugfixes: update:去掉ocr目录
This commit is contained in:
@@ -147,14 +147,14 @@ public class SelectToSpeakService extends AccessibilityService {
|
|||||||
if (mCurrentStep != Step.FIND_CONTACT) {
|
if (mCurrentStep != Step.FIND_CONTACT) {
|
||||||
mCurrentStep = Step.CLICK_CONTACT;
|
mCurrentStep = Step.CLICK_CONTACT;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
case "com.tencent.mm.plugin.label.ui.ContactLabelManagerUI":
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case "com.tencent.mm.plugin.account.ui.WelcomeActivity":
|
case "com.tencent.mm.plugin.account.ui.WelcomeActivity":
|
||||||
case "com.tencent.mm.plugin.account.ui.LoginPasswordUI":
|
case "com.tencent.mm.plugin.account.ui.LoginPasswordUI":
|
||||||
Toaster.showLong("请先登录微信");
|
Toaster.showLong("请先登录微信");
|
||||||
mCurrentStep = Step.WAITING;
|
mCurrentStep = Step.WAITING;
|
||||||
|
break;
|
||||||
|
case "com.tencent.mm.plugin.label.ui.ContactLabelManagerUI":
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -137,6 +137,7 @@ public class CallWechatActivity extends BaseMvvmActivity<CallWechatViewModel, Ac
|
|||||||
// } else {
|
// } else {
|
||||||
startService(intent);
|
startService(intent);
|
||||||
// }
|
// }
|
||||||
|
finish();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -151,6 +152,7 @@ public class CallWechatActivity extends BaseMvvmActivity<CallWechatViewModel, Ac
|
|||||||
intent.putExtra("WechatInfo", mContact);
|
intent.putExtra("WechatInfo", mContact);
|
||||||
intent.putExtra("call_type", SelectToSpeakService.TYPE_VOICE);
|
intent.putExtra("call_type", SelectToSpeakService.TYPE_VOICE);
|
||||||
startService(intent);
|
startService(intent);
|
||||||
|
finish();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,105 +0,0 @@
|
|||||||
package com.vscool.os.ocr.paddle;
|
|
||||||
|
|
||||||
import android.graphics.Bitmap;
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
|
||||||
|
|
||||||
public class OCRPredictorNative {
|
|
||||||
|
|
||||||
private static final AtomicBoolean isSOLoaded = new AtomicBoolean();
|
|
||||||
|
|
||||||
public static void loadLibrary() throws RuntimeException {
|
|
||||||
if (!isSOLoaded.get() && isSOLoaded.compareAndSet(false, true)) {
|
|
||||||
try {
|
|
||||||
System.loadLibrary("Native");
|
|
||||||
} catch (Throwable e) {
|
|
||||||
RuntimeException exception = new RuntimeException(
|
|
||||||
"Load libNative.so failed, please check it exists in apk file.", e);
|
|
||||||
throw exception;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Config config;
|
|
||||||
|
|
||||||
private long nativePointer = 0;
|
|
||||||
|
|
||||||
public OCRPredictorNative(Config config) {
|
|
||||||
this.config = config;
|
|
||||||
loadLibrary();
|
|
||||||
nativePointer = init(config.detModelFilename, config.recModelFilename, config.clsModelFilename, config.useOpencl,
|
|
||||||
config.cpuThreadNum, config.cpuPower);
|
|
||||||
Log.i("OCRPredictorNative", "load success " + nativePointer);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public ArrayList<OcrResultModel> runImage(Bitmap originalImage, int max_size_len, int run_det, int run_cls, int run_rec) {
|
|
||||||
Log.i("OCRPredictorNative", "begin to run image ");
|
|
||||||
float[] rawResults = forward(nativePointer, originalImage, max_size_len, run_det, run_cls, run_rec);
|
|
||||||
ArrayList<OcrResultModel> results = postprocess(rawResults);
|
|
||||||
return results;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Config {
|
|
||||||
public int useOpencl;
|
|
||||||
public int cpuThreadNum;
|
|
||||||
public String cpuPower;
|
|
||||||
public String detModelFilename;
|
|
||||||
public String recModelFilename;
|
|
||||||
public String clsModelFilename;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void destroy() {
|
|
||||||
if (nativePointer != 0) {
|
|
||||||
release(nativePointer);
|
|
||||||
nativePointer = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected native long init(String detModelPath, String recModelPath, String clsModelPath, int useOpencl, int threadNum, String cpuMode);
|
|
||||||
|
|
||||||
protected native float[] forward(long pointer, Bitmap originalImage, int max_size_len, int run_det, int run_cls, int run_rec);
|
|
||||||
|
|
||||||
protected native void release(long pointer);
|
|
||||||
|
|
||||||
private ArrayList<OcrResultModel> postprocess(float[] raw) {
|
|
||||||
ArrayList<OcrResultModel> results = new ArrayList<OcrResultModel>();
|
|
||||||
int begin = 0;
|
|
||||||
|
|
||||||
while (begin < raw.length) {
|
|
||||||
int point_num = Math.round(raw[begin]);
|
|
||||||
int word_num = Math.round(raw[begin + 1]);
|
|
||||||
OcrResultModel res = parse(raw, begin + 2, point_num, word_num);
|
|
||||||
begin += 2 + 1 + point_num * 2 + word_num + 2;
|
|
||||||
results.add(res);
|
|
||||||
}
|
|
||||||
|
|
||||||
return results;
|
|
||||||
}
|
|
||||||
|
|
||||||
private OcrResultModel parse(float[] raw, int begin, int pointNum, int wordNum) {
|
|
||||||
int current = begin;
|
|
||||||
OcrResultModel res = new OcrResultModel();
|
|
||||||
res.setConfidence(raw[current]);
|
|
||||||
current++;
|
|
||||||
for (int i = 0; i < pointNum; i++) {
|
|
||||||
res.addPoints(Math.round(raw[current + i * 2]), Math.round(raw[current + i * 2 + 1]));
|
|
||||||
}
|
|
||||||
current += (pointNum * 2);
|
|
||||||
for (int i = 0; i < wordNum; i++) {
|
|
||||||
int index = Math.round(raw[current + i]);
|
|
||||||
res.addWordIndex(index);
|
|
||||||
}
|
|
||||||
current += wordNum;
|
|
||||||
res.setClsIdx(raw[current]);
|
|
||||||
res.setClsConfidence(raw[current + 1]);
|
|
||||||
Log.i("OCRPredictorNative", "word finished " + wordNum);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,79 +0,0 @@
|
|||||||
package com.vscool.os.ocr.paddle;
|
|
||||||
|
|
||||||
import android.graphics.Point;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class OcrResultModel {
|
|
||||||
private List<Point> points;
|
|
||||||
private List<Integer> wordIndex;
|
|
||||||
private String label;
|
|
||||||
private float confidence;
|
|
||||||
private float cls_idx;
|
|
||||||
private String cls_label;
|
|
||||||
private float cls_confidence;
|
|
||||||
|
|
||||||
public OcrResultModel() {
|
|
||||||
super();
|
|
||||||
points = new ArrayList<>();
|
|
||||||
wordIndex = new ArrayList<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addPoints(int x, int y) {
|
|
||||||
Point point = new Point(x, y);
|
|
||||||
points.add(point);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addWordIndex(int index) {
|
|
||||||
wordIndex.add(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Point> getPoints() {
|
|
||||||
return points;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Integer> getWordIndex() {
|
|
||||||
return wordIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getLabel() {
|
|
||||||
return label;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLabel(String label) {
|
|
||||||
this.label = label;
|
|
||||||
}
|
|
||||||
|
|
||||||
public float getConfidence() {
|
|
||||||
return confidence;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setConfidence(float confidence) {
|
|
||||||
this.confidence = confidence;
|
|
||||||
}
|
|
||||||
|
|
||||||
public float getClsIdx() {
|
|
||||||
return cls_idx;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setClsIdx(float idx) {
|
|
||||||
this.cls_idx = idx;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getClsLabel() {
|
|
||||||
return cls_label;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setClsLabel(String label) {
|
|
||||||
this.cls_label = label;
|
|
||||||
}
|
|
||||||
|
|
||||||
public float getClsConfidence() {
|
|
||||||
return cls_confidence;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setClsConfidence(float confidence) {
|
|
||||||
this.cls_confidence = confidence;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,283 +0,0 @@
|
|||||||
package com.vscool.os.ocr.paddle;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.graphics.Bitmap;
|
|
||||||
import android.graphics.Canvas;
|
|
||||||
import android.graphics.Color;
|
|
||||||
import android.graphics.Paint;
|
|
||||||
import android.graphics.Path;
|
|
||||||
import android.graphics.Point;
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Vector;
|
|
||||||
|
|
||||||
public class Predictor {
|
|
||||||
private static final String TAG = Predictor.class.getSimpleName();
|
|
||||||
public boolean isLoaded = false;
|
|
||||||
public int warmupIterNum = 1;
|
|
||||||
public int inferIterNum = 1;
|
|
||||||
public int cpuThreadNum = 6;
|
|
||||||
public String cpuPowerMode = "LITE_POWER_HIGH";
|
|
||||||
public String modelPath = "";
|
|
||||||
public String modelName = "";
|
|
||||||
protected OCRPredictorNative paddlePredictor = null;
|
|
||||||
protected float inferenceTime = 0;
|
|
||||||
// Only for object detection
|
|
||||||
protected Vector<String> wordLabels = new Vector<String>();
|
|
||||||
protected int detLongSize = 960;
|
|
||||||
protected float scoreThreshold = 0.1f;
|
|
||||||
protected Bitmap inputImage = null;
|
|
||||||
protected Bitmap outputImage = null;
|
|
||||||
protected volatile String outputResult = "";
|
|
||||||
protected float postprocessTime = 0;
|
|
||||||
protected ArrayList<OcrResultModel> mOcrResultModels;
|
|
||||||
|
|
||||||
public Predictor() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean init(Context appCtx, String modelPath, String labelPath, int useOpencl, int cpuThreadNum, String cpuPowerMode) {
|
|
||||||
isLoaded = loadModel(appCtx, modelPath, useOpencl, cpuThreadNum, cpuPowerMode);
|
|
||||||
if (!isLoaded) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
isLoaded = loadLabel(appCtx, labelPath);
|
|
||||||
return isLoaded;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public boolean init(Context appCtx, String modelPath, String labelPath, int useOpencl, int cpuThreadNum, String cpuPowerMode,
|
|
||||||
int detLongSize, float scoreThreshold) {
|
|
||||||
boolean isLoaded = init(appCtx, modelPath, labelPath, useOpencl, cpuThreadNum, cpuPowerMode);
|
|
||||||
if (!isLoaded) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
this.detLongSize = detLongSize;
|
|
||||||
this.scoreThreshold = scoreThreshold;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected boolean loadModel(Context appCtx, String modelPath, int useOpencl, int cpuThreadNum, String cpuPowerMode) {
|
|
||||||
// Release model if exists
|
|
||||||
releaseModel();
|
|
||||||
|
|
||||||
// Load model
|
|
||||||
if (modelPath.isEmpty()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
String realPath = modelPath;
|
|
||||||
if (!modelPath.substring(0, 1).equals("/")) {
|
|
||||||
// Read model files from custom path if the first character of mode path is '/'
|
|
||||||
// otherwise copy model to cache from assets
|
|
||||||
realPath = appCtx.getCacheDir() + "/" + modelPath;
|
|
||||||
Utils.copyDirectoryFromAssets(appCtx, modelPath, realPath);
|
|
||||||
}
|
|
||||||
if (realPath.isEmpty()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
OCRPredictorNative.Config config = new OCRPredictorNative.Config();
|
|
||||||
config.useOpencl = useOpencl;
|
|
||||||
config.cpuThreadNum = cpuThreadNum;
|
|
||||||
config.cpuPower = cpuPowerMode;
|
|
||||||
config.detModelFilename = realPath + File.separator + "det_db.nb";
|
|
||||||
config.recModelFilename = realPath + File.separator + "rec_crnn.nb";
|
|
||||||
config.clsModelFilename = realPath + File.separator + "cls.nb";
|
|
||||||
Log.i("Predictor", "model path" + config.detModelFilename + " ; " + config.recModelFilename + ";" + config.clsModelFilename);
|
|
||||||
paddlePredictor = new OCRPredictorNative(config);
|
|
||||||
|
|
||||||
this.cpuThreadNum = cpuThreadNum;
|
|
||||||
this.cpuPowerMode = cpuPowerMode;
|
|
||||||
this.modelPath = realPath;
|
|
||||||
this.modelName = realPath.substring(realPath.lastIndexOf("/") + 1);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void releaseModel() {
|
|
||||||
if (paddlePredictor != null) {
|
|
||||||
paddlePredictor.destroy();
|
|
||||||
paddlePredictor = null;
|
|
||||||
}
|
|
||||||
isLoaded = false;
|
|
||||||
cpuThreadNum = 1;
|
|
||||||
cpuPowerMode = "LITE_POWER_HIGH";
|
|
||||||
modelPath = "";
|
|
||||||
modelName = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
protected boolean loadLabel(Context appCtx, String labelPath) {
|
|
||||||
wordLabels.clear();
|
|
||||||
wordLabels.add("black");
|
|
||||||
// Load word labels from file
|
|
||||||
try {
|
|
||||||
InputStream assetsInputStream = appCtx.getAssets().open(labelPath);
|
|
||||||
int available = assetsInputStream.available();
|
|
||||||
byte[] lines = new byte[available];
|
|
||||||
assetsInputStream.read(lines);
|
|
||||||
assetsInputStream.close();
|
|
||||||
String words = new String(lines);
|
|
||||||
String[] contents = words.split("\n");
|
|
||||||
for (String content : contents) {
|
|
||||||
wordLabels.add(content);
|
|
||||||
}
|
|
||||||
wordLabels.add(" ");
|
|
||||||
Log.i(TAG, "Word label size: " + wordLabels.size());
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.e(TAG, e.getMessage());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public boolean runModel(int run_det, int run_cls, int run_rec) {
|
|
||||||
if (inputImage == null || !isLoaded()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
Log.d(TAG, "runModel: " + inputImage.getWidth() + "x" + inputImage.getHeight());
|
|
||||||
// Warm up
|
|
||||||
for (int i = 0; i < warmupIterNum; i++) {
|
|
||||||
paddlePredictor.runImage(inputImage, detLongSize, run_det, run_cls, run_rec);
|
|
||||||
}
|
|
||||||
warmupIterNum = 0; // do not need warm
|
|
||||||
// Run inference
|
|
||||||
Date start = new Date();
|
|
||||||
ArrayList<OcrResultModel> results = paddlePredictor.runImage(inputImage, detLongSize, run_det, run_cls, run_rec);
|
|
||||||
Date end = new Date();
|
|
||||||
inferenceTime = (end.getTime() - start.getTime()) / (float) inferIterNum;
|
|
||||||
|
|
||||||
results = postprocess(results);
|
|
||||||
mOcrResultModels = results;
|
|
||||||
Log.i(TAG, "[stat] Inference Time: " + inferenceTime + " ;Box Size " + results.size());
|
|
||||||
drawResults(results);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ArrayList<OcrResultModel> getOcrResultModels() {
|
|
||||||
return mOcrResultModels;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isLoaded() {
|
|
||||||
return paddlePredictor != null && isLoaded;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String modelPath() {
|
|
||||||
return modelPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String modelName() {
|
|
||||||
return modelName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int cpuThreadNum() {
|
|
||||||
return cpuThreadNum;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String cpuPowerMode() {
|
|
||||||
return cpuPowerMode;
|
|
||||||
}
|
|
||||||
|
|
||||||
public float inferenceTime() {
|
|
||||||
return inferenceTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Bitmap inputImage() {
|
|
||||||
return inputImage;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Bitmap outputImage() {
|
|
||||||
return outputImage;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String outputResult() {
|
|
||||||
return outputResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
public float postprocessTime() {
|
|
||||||
return postprocessTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void setInputImage(Bitmap image) {
|
|
||||||
if (image == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.inputImage = image.copy(Bitmap.Config.ARGB_8888, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
private ArrayList<OcrResultModel> postprocess(ArrayList<OcrResultModel> results) {
|
|
||||||
for (OcrResultModel r : results) {
|
|
||||||
StringBuffer word = new StringBuffer();
|
|
||||||
for (int index : r.getWordIndex()) {
|
|
||||||
if (index >= 0 && index < wordLabels.size()) {
|
|
||||||
word.append(wordLabels.get(index));
|
|
||||||
} else {
|
|
||||||
Log.e(TAG, "Word index is not in label list:" + index);
|
|
||||||
word.append("×");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
r.setLabel(word.toString());
|
|
||||||
r.setClsLabel(r.getClsIdx() == 1 ? "180" : "0");
|
|
||||||
}
|
|
||||||
return results;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void drawResults(ArrayList<OcrResultModel> results) {
|
|
||||||
StringBuffer outputResultSb = new StringBuffer("");
|
|
||||||
for (int i = 0; i < results.size(); i++) {
|
|
||||||
OcrResultModel result = results.get(i);
|
|
||||||
StringBuilder sb = new StringBuilder("");
|
|
||||||
if (result.getPoints().size() > 0) {
|
|
||||||
sb.append("Det: ");
|
|
||||||
for (Point p : result.getPoints()) {
|
|
||||||
sb.append("(").append(p.x).append(",").append(p.y).append(") ");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (result.getLabel().length() > 0) {
|
|
||||||
sb.append("\n Rec: ").append(result.getLabel());
|
|
||||||
sb.append(",").append(result.getConfidence());
|
|
||||||
}
|
|
||||||
if (result.getClsIdx() != -1) {
|
|
||||||
sb.append(" Cls: ").append(result.getClsLabel());
|
|
||||||
sb.append(",").append(result.getClsConfidence());
|
|
||||||
}
|
|
||||||
Log.i(TAG, sb.toString()); // show LOG in Logcat panel
|
|
||||||
outputResultSb.append(i + 1).append(": ").append(sb.toString()).append("\n");
|
|
||||||
}
|
|
||||||
outputResult = outputResultSb.toString();
|
|
||||||
outputImage = inputImage;
|
|
||||||
Canvas canvas = new Canvas(outputImage);
|
|
||||||
Paint paintFillAlpha = new Paint();
|
|
||||||
paintFillAlpha.setStyle(Paint.Style.FILL);
|
|
||||||
paintFillAlpha.setColor(Color.parseColor("#3B85F5"));
|
|
||||||
paintFillAlpha.setAlpha(50);
|
|
||||||
|
|
||||||
Paint paint = new Paint();
|
|
||||||
paint.setColor(Color.parseColor("#3B85F5"));
|
|
||||||
paint.setStrokeWidth(5);
|
|
||||||
paint.setStyle(Paint.Style.STROKE);
|
|
||||||
|
|
||||||
for (OcrResultModel result : results) {
|
|
||||||
Path path = new Path();
|
|
||||||
List<Point> points = result.getPoints();
|
|
||||||
if (points.size() == 0) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
path.moveTo(points.get(0).x, points.get(0).y);
|
|
||||||
for (int i = points.size() - 1; i >= 0; i--) {
|
|
||||||
Point p = points.get(i);
|
|
||||||
path.lineTo(p.x, p.y);
|
|
||||||
}
|
|
||||||
canvas.drawPath(path, paint);
|
|
||||||
canvas.drawPath(path, paintFillAlpha);
|
|
||||||
}
|
|
||||||
Log.d(TAG, "drawResults: " + outputImage.getWidth() + "x" + outputImage.getHeight());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,165 +0,0 @@
|
|||||||
package com.vscool.os.ocr.paddle;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.graphics.Bitmap;
|
|
||||||
import android.graphics.Matrix;
|
|
||||||
import android.media.ExifInterface;
|
|
||||||
import android.os.Environment;
|
|
||||||
|
|
||||||
import java.io.BufferedInputStream;
|
|
||||||
import java.io.BufferedOutputStream;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
|
|
||||||
public class Utils {
|
|
||||||
private static final String TAG = Utils.class.getSimpleName();
|
|
||||||
|
|
||||||
public static void copyFileFromAssets(Context appCtx, String srcPath, String dstPath) {
|
|
||||||
if (srcPath.isEmpty() || dstPath.isEmpty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
InputStream is = null;
|
|
||||||
OutputStream os = null;
|
|
||||||
try {
|
|
||||||
is = new BufferedInputStream(appCtx.getAssets().open(srcPath));
|
|
||||||
os = new BufferedOutputStream(new FileOutputStream(new File(dstPath)));
|
|
||||||
byte[] buffer = new byte[1024];
|
|
||||||
int length = 0;
|
|
||||||
while ((length = is.read(buffer)) != -1) {
|
|
||||||
os.write(buffer, 0, length);
|
|
||||||
}
|
|
||||||
} catch (FileNotFoundException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} finally {
|
|
||||||
try {
|
|
||||||
os.close();
|
|
||||||
is.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void copyDirectoryFromAssets(Context appCtx, String srcDir, String dstDir) {
|
|
||||||
if (srcDir.isEmpty() || dstDir.isEmpty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
if (!new File(dstDir).exists()) {
|
|
||||||
new File(dstDir).mkdirs();
|
|
||||||
}
|
|
||||||
for (String fileName : appCtx.getAssets().list(srcDir)) {
|
|
||||||
String srcSubPath = srcDir + File.separator + fileName;
|
|
||||||
String dstSubPath = dstDir + File.separator + fileName;
|
|
||||||
if (new File(srcSubPath).isDirectory()) {
|
|
||||||
copyDirectoryFromAssets(appCtx, srcSubPath, dstSubPath);
|
|
||||||
} else {
|
|
||||||
copyFileFromAssets(appCtx, srcSubPath, dstSubPath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static float[] parseFloatsFromString(String string, String delimiter) {
|
|
||||||
String[] pieces = string.trim().toLowerCase().split(delimiter);
|
|
||||||
float[] floats = new float[pieces.length];
|
|
||||||
for (int i = 0; i < pieces.length; i++) {
|
|
||||||
floats[i] = Float.parseFloat(pieces[i].trim());
|
|
||||||
}
|
|
||||||
return floats;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static long[] parseLongsFromString(String string, String delimiter) {
|
|
||||||
String[] pieces = string.trim().toLowerCase().split(delimiter);
|
|
||||||
long[] longs = new long[pieces.length];
|
|
||||||
for (int i = 0; i < pieces.length; i++) {
|
|
||||||
longs[i] = Long.parseLong(pieces[i].trim());
|
|
||||||
}
|
|
||||||
return longs;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getSDCardDirectory() {
|
|
||||||
return Environment.getExternalStorageDirectory().getAbsolutePath();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isSupportedNPU() {
|
|
||||||
return false;
|
|
||||||
// String hardware = android.os.Build.HARDWARE;
|
|
||||||
// return hardware.equalsIgnoreCase("kirin810") || hardware.equalsIgnoreCase("kirin990");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Bitmap resizeWithStep(Bitmap bitmap, int maxLength, int step) {
|
|
||||||
int width = bitmap.getWidth();
|
|
||||||
int height = bitmap.getHeight();
|
|
||||||
int maxWH = Math.max(width, height);
|
|
||||||
float ratio = 1;
|
|
||||||
int newWidth = width;
|
|
||||||
int newHeight = height;
|
|
||||||
if (maxWH > maxLength) {
|
|
||||||
ratio = maxLength * 1.0f / maxWH;
|
|
||||||
newWidth = (int) Math.floor(ratio * width);
|
|
||||||
newHeight = (int) Math.floor(ratio * height);
|
|
||||||
}
|
|
||||||
|
|
||||||
newWidth = newWidth - newWidth % step;
|
|
||||||
if (newWidth == 0) {
|
|
||||||
newWidth = step;
|
|
||||||
}
|
|
||||||
newHeight = newHeight - newHeight % step;
|
|
||||||
if (newHeight == 0) {
|
|
||||||
newHeight = step;
|
|
||||||
}
|
|
||||||
return Bitmap.createScaledBitmap(bitmap, newWidth, newHeight, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Bitmap rotateBitmap(Bitmap bitmap, int orientation) {
|
|
||||||
|
|
||||||
Matrix matrix = new Matrix();
|
|
||||||
switch (orientation) {
|
|
||||||
case ExifInterface.ORIENTATION_NORMAL:
|
|
||||||
return bitmap;
|
|
||||||
case ExifInterface.ORIENTATION_FLIP_HORIZONTAL:
|
|
||||||
matrix.setScale(-1, 1);
|
|
||||||
break;
|
|
||||||
case ExifInterface.ORIENTATION_ROTATE_180:
|
|
||||||
matrix.setRotate(180);
|
|
||||||
break;
|
|
||||||
case ExifInterface.ORIENTATION_FLIP_VERTICAL:
|
|
||||||
matrix.setRotate(180);
|
|
||||||
matrix.postScale(-1, 1);
|
|
||||||
break;
|
|
||||||
case ExifInterface.ORIENTATION_TRANSPOSE:
|
|
||||||
matrix.setRotate(90);
|
|
||||||
matrix.postScale(-1, 1);
|
|
||||||
break;
|
|
||||||
case ExifInterface.ORIENTATION_ROTATE_90:
|
|
||||||
matrix.setRotate(90);
|
|
||||||
break;
|
|
||||||
case ExifInterface.ORIENTATION_TRANSVERSE:
|
|
||||||
matrix.setRotate(-90);
|
|
||||||
matrix.postScale(-1, 1);
|
|
||||||
break;
|
|
||||||
case ExifInterface.ORIENTATION_ROTATE_270:
|
|
||||||
matrix.setRotate(-90);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return bitmap;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
Bitmap bmRotated = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
|
|
||||||
bitmap.recycle();
|
|
||||||
return bmRotated;
|
|
||||||
} catch (OutOfMemoryError e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user