<provider
android:name=“android.support.v4.content.FileProvider”
android:authorities=“com.chaochaowu.facedetect.provider”
android:exported=“false”
android:grantUriPermissions=“true”>
<meta-data
android:name=“android.support.FILE_PROVIDER_PATHS”
android:resource=“@xml/file_paths” />
</provider>
拍照之後從文件中讀取照片,我們可以得到一個 BitMap 對象。這裏就有一個很大的坑,如果手機是三星的話,照片從文件裏讀出來,最後得到的照片會被旋轉 90°!!!,這個賊坑啊,調了我好久,以為是自己手機的故障,後來網上查了一下,也請教了一下前輩,原來三星的手機都有這個問題,所以說我們要對文件中取出來的照片進行一下處理。
/**
-
讀取圖片的旋轉的角度
-
@param path 圖片絕對路徑
-
@return 圖片的旋轉角度
*/
public static int getBitmapDegree(String path) {
int degree = 0;
try {
// 從指定路徑下讀取圖片,並獲取其EXIF信息
ExifInterface exifInterface = new ExifInterface(path);
// 獲取圖片的旋轉信息
int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL);
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
degree = 90;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
degree = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_270:
degree = 270;
break;
default:
degree = 0;
break;
}
} catch (IOException e) {
e.printStackTrace();
}
return degree;
}
/**
-
將圖片按照某個角度進行旋轉
-
@param bm 需要旋轉的圖片
-
@param degree 旋轉角度
-
@return 旋轉後的圖片
*/
public static Bitmap rotateBitmapByDegree(Bitmap bm, int degree) {
Bitmap returnBm = null;
// 根據旋轉角度,生成旋轉矩陣
Matrix matrix = new Matrix();
matrix.postRotate(degree);
try {
// 將原始圖片按照旋轉矩陣進行旋轉,並得到新的圖片
returnBm = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), bm.getHeight(), matrix, true);
} catch (OutOfMemoryError | Exception e) {
e.printStackTrace();
}
if (returnBm == null) {
returnBm = bm;
}
if (bm != returnBm) {
bm.recycle();
}
return returnBm;
}
封裝了兩個方法,依次調用可以解决三星手機照片的問題。兩個方法主要的工作就是,得到取出來的照片被旋轉的角度,然後再將角度旋轉回去,就可以得到原來的照片。因為並不是所有的手機在獲取照片時,照片都會被旋轉,所以得先判斷一下照片有沒有被旋轉,再决定是否需要將它旋轉調整。
行,這樣最後就獲得到了正確的 BitMap 照片,可以進行下一步了。
傳照片獲取數據
傳照片獲取數據,主要是運用了 Retrofit 和 RxJava 的封裝。請求的參數可以參考 Face++ 的官方文檔。
/**
-
retrofit 面部識別請求的網絡服務
-
@author chaochaowu
*/
public interface FaceppService {
/**
-
@param apikey
-
@param apiSecret
-
@param imageBase64
-
@param returnLandmark
-
@param returnAttributes
-
@return
*/
@POST(“facepp/v3/detect”)
@FormUrlEncoded
Observable<FaceppBean> getFaceInfo(@Field(“api_key”) String apikey,
@Field(“api_secret”) String apiSecret,
@Field(“image_base64”) String imageBase64,
@Field(“return_landmark”) int returnLandmark,
@Field(“return_attributes”) String returnAttributes);
}
照片需要進行 base64 轉碼後上傳至服務器,封裝了一個照片base64轉碼方法。
public static String base64(Bitmap bitmap){
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
byte[] bytes = baos.toByteArray();
return Base64.encodeToString(bytes, Base64.DEFAULT);
}
處理完成之後就可以進行網絡請求獲取數據。
@Override
public void getDetectResultFromServer(final Bitmap photo) {
String s = Utils.base64(photo);
faceppService.getFaceInfo(BuildConfig.API_KEY, BuildConfig.API_SECRET, s, 1, “gender,age,smiling,emotion,beauty”)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<FaceppBean>() {
@Override
public void onSubscribe(Disposable d) {
mView.showProgress();
}
@Override
public void onNext(FaceppBean faceppBean) {
handleDetectResult(photo,faceppBean);
}
@Override
public void onError(Throwable e) {
mView.hideProgress();
}
@Override
public void onComplete() {
mView.hideProgress();
}
});
}
Face++ 服務器會對我們上傳的照片進行處理,分析照片中的人臉信息,並以 json 形式返回,返回的數據將被放入我們定義的bean類中。
/**
-
面部識別結果的bean
-
@author chaochaowu
*/
public class FaceppBean {
/**
-
image_id : Dd2xUw9S/7yjr0oDHHSL/Q==
-
request_id : 1470472868,dacf2ff1-ea45-4842-9c07-6e8418cea78b
-
time_used : 752
-
faces : [{“landmark”:{“mouth_upper_lip_left_contour2”:{“y”:185,“x”:146},“contour_chin”:{“y”:231,“x”:137},“right_eye_pupil”:{“y”:146,“x”:205},“mouth_upper_lip_bottom”:{“y”:195,“x”:159}},“attributes”:{“gender”:{“value”:“Female”},“age”:{“value”:21},“glass”:{“value”:“None”},“headpose”:{“yaw_angle”:-26.625063,“pitch_angle”:12.921974,“roll_angle”:22.814377},“smile”:{“threshold”:30.1,“value”:2.566890001296997}},“face_rectangle”:{“width”:140,“top”:89,“left”:104,“height”:141},“face_token”:“ed319e807e039ae669a4d1af0922a0c8”}]
*/
最後
文章不易,如果大家喜歡這篇文章,或者對你有幫助希望大家多多點贊轉發關注哦。文章會持續更新的。絕對幹貨!!!
由於文章篇幅問題 查看詳細文章以及獲取學習筆記鏈接: GitHub
- Android進階學習全套手册
關於實戰,我想每一個做開發的都有話要說,對於小白而言,缺乏實戰經驗是通病,那麼除了在實際工作過程當中,我們如何去更了解實戰方面的內容呢?實際上,我們很有必要去看一些實戰相關的電子書。目前,我手頭上整理到的電子書還算比較全面,HTTP、自定義view、c++、MVP、Android源碼設計模式、Android開發藝術探索、Java並發編程的藝術、Android基於Glide的二次封裝、Android內存優化——常見內存泄露及優化方案、.Java編程思想 (第4版)等高級技術都囊括其中。
-
Android高級架構師進階知識體系圖
關於視頻這塊,我也是自己搜集了一些,都按照Android學習路線做了一個分類。按照Android學習路線一共有八個模塊,其中視頻都有對應,就是為了幫助大家系統的學習。接下來看一下導圖和對應系統視頻吧!!!
-
Android對標阿裏P7學習視頻
- BATJ大廠Android高頻面試題
這個題庫內容是比較多的,除了一些流行的熱門技術面試題,如Kotlin,數據庫,Java虛擬機面試題,數組,Framework ,混合跨平臺開發,等
版权声明
本文为[mb61c1dbbb44788]所创,转载请带上原文链接,感谢
https://cdmana.com/2022/01/202201150218513172.html