編輯:關於Android編程
我們點開案例可以看到眾多我們熟知的軟件都是使用的這個公司所提供的SDK
然後我們點擊開發者中心中的開發工具與sdk下載我們所需要的sdk
之後再點擊我的應用中的創建應用之後他會給我們兩個密鑰
要保存這兩個值我們在程序中要用到它們
我今天實現的是實現面部捕捉並且識別性別和年齡來看一下效果圖
閒話不多說我們來看看實現
1.工具類Constant用來存放密鑰
public class Constant { //設置兩個之前獲取的兩個常量 public static final String Key="2029451928755e97039b8138cfa8f8ca"; public static final String Secret="5RNoYATB9vqpA5kerpmo6bp2Aw9fxMl0"; }
import android.graphics.Bitmap; import com.facepp.error.FaceppParseException; import com.facepp.http.HttpRequests; import com.facepp.http.PostParameters; import org.json.JSONObject; import java.io.ByteArrayOutputStream; public class InternetDetect { public interface CallBack { void success(JSONObject jsonObject); void error(FaceppParseException exception); } public static void dectect(final Bitmap bitmap, final CallBack callBack) { //因為這裡要向網絡發送數據是耗時操作所以要在新線程中執行 new Thread(new Runnable() { @Override public void run() { /*1.設置請求 * 2.創建一個Bitmap * 3.創建字符數組流 * 4.將bitmap轉換為字符並傳入流中 * 5.新建字符數組接受流 * 6.創建發送數據包 * 7.創建接受數據包 * * */ try { HttpRequests httpRequests=new HttpRequests(Constant.Key,Constant.Secret,true,true); //從0,0點挖取整個視圖,後兩個參數是目標大小 Bitmap bitmapsmall = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight()); //這裡api要求傳入一個字節數組數據,因此要用字節數組輸出流 ByteArrayOutputStream stream=new ByteArrayOutputStream(); /*Bitmap.compress()方法可以用於將Bitmap-->byte[] 既將位圖的壓縮到指定的OutputStream。如果返回true, 位圖可以通過傳遞一個相應的InputStream BitmapFactory.decodeStream(重建) 第一個參數可設置JPEG或PNG格式,第二個參數是圖片質量,第三個參數是一個流信息*/ bitmapsmall.compress(Bitmap.CompressFormat.JPEG, 100, stream); byte[] arrays=stream.toByteArray(); //實現發送參數功能 PostParameters parameters=new PostParameters(); //發送數據 parameters.setImg(arrays); //服務器返回一個JSONObject的數據 JSONObject jsonObject=httpRequests.detectionDetect(parameters); System.out.println("jsonObject:"+jsonObject.toString()); if(callBack!=null) { //設置回調 callBack.success(jsonObject); } } catch (FaceppParseException e) { System.out.println("error"); e.printStackTrace(); if(callBack!=null) { callBack.error(e); } } } }).start(); } }
import android.content.Intent; import android.database.Cursor; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Paint; import android.net.Uri; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.provider.MediaStore; import android.support.v7.app.ActionBarActivity; import android.text.method.ScrollingMovementMethod; import android.view.View; import android.widget.Button; import android.widget.ImageView; import android.widget.TextView; import com.facepp.error.FaceppParseException; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; public class MainActivity extends ActionBarActivity implements View.OnClickListener { private static final int PICK_CODE =1; private ImageView myPhoto; private Button getImage; private Button detect; private TextView tip; private View mWaitting; private String ImagePath=null; private Paint mypaint; private Bitmap myBitmapImage; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mypaint=new Paint(); initViews(); initEvent(); } private void initViews() { myPhoto=(ImageView)findViewById(R.id.id_photo); getImage=(Button)findViewById(R.id.get_image); detect=(Button)findViewById(R.id.detect); tip=(TextView)findViewById(R.id.id_Tip); mWaitting=findViewById(R.id.id_waitting); tip.setMovementMethod(ScrollingMovementMethod.getInstance()); } private void initEvent() { getImage.setOnClickListener(this); detect.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.get_image: //獲取系統選擇圖片intent Intent intent=new Intent(Intent.ACTION_PICK); intent.setType("image/*"); //開啟選擇圖片功能響應碼為PICK_CODE startActivityForResult(intent,PICK_CODE); break; case R.id.detect: //顯示進度條圓形 mWaitting.setVisibility(View.VISIBLE); //這裡需要注意判斷用戶是否沒有選擇圖片直接點擊了detect按鈕 //否則會報一個空指針異常而造成程序崩潰 if(ImagePath!=null&&!ImagePath.trim().equals("")) { //如果不是直接點擊的圖片則壓縮當前選中的圖片 resizePhoto(); }else { //否則將默認的背景圖作為bitmap傳入 myBitmapImage=BitmapFactory.decodeResource(getResources(),R.drawable.test1); } //設置回調 InternetDetect.dectect(myBitmapImage, new InternetDetect.CallBack() { @Override public void success(JSONObject jsonObject) { Message message=Message.obtain(); message.what=MSG_SUCESS; message.obj=jsonObject; myhandler.sendMessage(message); } @Override public void error(FaceppParseException exception) { Message message=Message.obtain(); message.what=MSG_ERROR; message.obj=exception; myhandler.sendMessage(message); } }); break; } } //設置響應intent請求 @Override protected void onActivityResult(int requestCode, int resultCode, Intent intent) { super.onActivityResult(requestCode, resultCode, intent); if(requestCode==PICK_CODE) { if(intent!=null) { //獲取圖片路徑 //獲取所有圖片資源 Uri uri=intent.getData(); //設置指針獲得一個ContentResolver的實例 Cursor cursor=getContentResolver().query(uri,null,null,null,null); cursor.moveToFirst(); //返回索引項位置 int index=cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA); //返回索引項路徑 ImagePath=cursor.getString(index); cursor.close(); //這個jar包要求請求的圖片大小不得超過3m所以要進行一個壓縮圖片操作 resizePhoto(); myPhoto.setImageBitmap(myBitmapImage); tip.setText("Click Detect==>"); } } } private void resizePhoto() { //得到BitmapFactory的操作權 BitmapFactory.Options options = new BitmapFactory.Options(); // 如果設置為 true ,不獲取圖片,不分配內存,但會返回圖片的高寬度信息。 options.inJustDecodeBounds = true; BitmapFactory.decodeFile(ImagePath,options); //計算寬高要盡可能小於1024 double ratio=Math.max(options.outWidth*1.0d/1024f,options.outHeight*1.0d/1024f); //設置圖片縮放的倍數。假如設為 4 ,則寬和高都為原來的 1/4 ,則圖是原來的 1/16 。 options.inSampleSize=(int)Math.ceil(ratio); //我們這裡並想讓他顯示圖片所以這裡要置為false options.inJustDecodeBounds=false; //利用Options的這些值就可以高效的得到一幅縮略圖。 myBitmapImage=BitmapFactory.decodeFile(ImagePath,options); } private static final int MSG_SUCESS=11; private static final int MSG_ERROR=22; private Handler myhandler=new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what) { case MSG_SUCESS: //關閉緩沖條 mWaitting.setVisibility(View.GONE); //拿到新線程中返回的JSONObject數據 JSONObject rsobj= (JSONObject) msg.obj; //准備Bitmap,這裡會解析JSONObject傳回的數據 prepareBitmap(rsobj); //讓主線程的相框刷新 myPhoto.setImageBitmap(myBitmapImage); break; case MSG_ERROR: mWaitting.setVisibility(View.GONE); String errormsg= (String) msg.obj; break; } } }; private void prepareBitmap(JSONObject JS) { //新建一個Bitmap使用它作為Canvas操作的對象 Bitmap bitmap=Bitmap.createBitmap(myBitmapImage.getWidth(),myBitmapImage.getHeight(),myBitmapImage.getConfig()); //實例化一塊畫布 Canvas canvas=new Canvas(bitmap); //把原圖先畫到畫布上面 canvas.drawBitmap(myBitmapImage, 0, 0, null); //解析傳回的JSONObject數據 try { //JSONObject中包含著眾多JSONArray,但是我們這裡需要關鍵字為face的數組中的信息 JSONArray faces=JS.getJSONArray("face"); //獲取得到幾個人臉 int faceCount=faces.length(); //讓提示文本顯示人臉數 tip.setText("find"+faceCount); //下面對每一張人臉都進行單獨的信息繪制 for(int i=0;i布局文件比較簡單因此代碼我就不上傳了
這裡我用紅色字體標出我在實現的過程中遇到的問題希望大家可以避免:
1.在寫按鍵響應的時候要注意判斷用戶是否沒有選擇圖片而直接點擊了detect按鈕,這樣的話避免了獲取圖片時存在空指針異常的問題
2.上傳圖片時要保證圖片小於3M因此注意圖片的壓縮
3.氣泡處理有技巧,把它當作Textview更方便
4.在繪制氣泡的時候也要注意縮放不然的話當人臉很小的時候氣泡會占據整個圖片導致用戶體驗降低
希望對大家有所幫助,歡迎轉載但要標明出處,謝謝!
有什麼不足的地方可以留言給我我會盡快回復並改正!
本文實例講述了Android viewpager中動態添加view並實現偽無限循環的方法。分享給大家供大家參考,具體如下:viewpager的使用,大家都熟悉,它可以實現
本文實例分析了Android可循環顯示圖像的Android Gallery組件用法。分享給大家供大家參考,具體如下:Gallery組件主要用於橫向顯示圖像列表,不過按常規
謹以此文,記我在公司實習時,所接到的第一個正式的、真正有意義的任務——將公司即將發布的APK進行代碼混淆。什麼是代碼混淆混淆就是對發布出去的程序進
篇外話:先來說下今天的日期,今天是2015年02月18日也就是大年三十,大家都在歡歡喜喜的准備過大年,活動也各式各樣,搓麻將、打撲克、放煙花、准備看春晚,而我卻還在敲代碼