最近由于参加一个小小的创意比赛,用安卓做了一个小小的图片识别应用,主要是通过拍照识别图片中的菜品,还有对象位置查找的东西。之前没有做过安卓,都是拼拼凑凑多篇博客完成的,我也把这个项目的一些过程分享一下。先把功能贴一下,其实就是点击拍照,将照片保存在本地,然后识别出图中的菜品,然后用红色方框圈出来,并显示菜品种类。采用最新的Camera2的API,的确是比Camera好用。
1、界面
我采用了一个SurfaceView用来显示摄像头的预览画面,重写了一个SurfaceView来进行红色方框还有菜品名字的绘制。图片是一个ImageVIew,相当于拍照按钮的功能。
SVDraw,,继承SurfaceView,用于绘制红色方框
package com.hd.hd;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff;
import android.util.AttributeSet;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import java.util.List;
/*定义一个画矩形框的类*/
public class SVDraw extends SurfaceView implements SurfaceHolder.Callback{
protected SurfaceHolder sh;
private int mWidth;
private int mHeight;
public SVDraw(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
sh = getHolder();
sh.addCallback(this);
sh.setFormat(PixelFormat.TRANSPARENT);
setZOrderOnTop(true);
}
public void surfaceChanged(SurfaceHolder arg0, int arg1, int w, int h) {
// TODO Auto-generated method stub
}
public void surfaceCreated(SurfaceHolder sh) {
// TODO Auto-generated method stub
mWidth = this.getWidth();
mHeight = this.getHeight();
}
public void surfaceDestroyed(SurfaceHolder arg0) {
// TODO Auto-generated method stub
}
void clearDraw()
{
Canvas canvas = sh.lockCanvas();
canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
sh.unlockCanvasAndPost(canvas);
}
public void drawLine(List
keys, List
values)
{
Canvas canvas = sh.lockCanvas();
canvas.drawColor(Color.TRANSPARENT);
Paint p = new Paint();
p.setAntiAlias(true);
p.setColor(Color.RED);
p.setStrokeWidth(6);
p.setStyle(Paint.Style.STROKE);//设置空心
p.setTextSize(160);
Paint p1 = new Paint();
p1.setColor(Color.WHITE);
p1.setTextSize(80);
for(int i = 0;i < keys.size();i++){
String v = values.get(i);
v = v.replace("[","");
v = v.replace("]","");
String[] value = v.split(",");
canvas.drawRect(mWidth - Integer.parseInt(value[3]), Integer.parseInt(value[0]), mHeight - Integer.parseInt(value[1]), Integer.parseInt(value[2]), p);// 正方形
canvas.drawText(keys.get(i), mWidth - Integer.parseInt(value[3]), Integer.parseInt(value[0])-5, p1);
}
sh.unlockCanvasAndPost(canvas);
}
}
2、上传图片到服务器,我没有采用JSon的格式,而是直接将图片文件转化为字节数组,发送给服务器。使用一个异步任务,完成后,直接在onPostExcute()方法里绘制。
package com.hd.hd;
import android.os.AsyncTask;
import android.util.Log;
import android.widget.TextView;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.UUID;
/**
* Created by asus on 2017/8/13.
*/
public class MyTask extends AsyncTask
{
private static String TAG = "MainActivity";
private File file; //需要发送的图片
private String result_content; //服务器返回的结果
private SVDraw surfaceView; //需要绘制的surfaceview
private TextView tv; //显示文字
private static final int TIME_OUT = 10 * 10