Android中怎么实现图片识别功能
                                            本篇文章为大家展示了Android中怎么实现图片识别功能,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。

创新互联专注为客户提供全方位的互联网综合服务,包含不限于网站制作、做网站、海东网络推广、小程序制作、海东网络营销、海东企业策划、海东品牌公关、搜索引擎seo、人物专访、企业宣传片、企业代运营等,从售前售中售后,我们都将竭诚为您服务,您的肯定,是我们最大的嘉奖;创新互联为所有大学生创业者提供海东建站搭建服务,24小时服务热线:13518219792,官方网址:www.cdcxhl.com
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 * 1000; // 超时时间 private static final String CHARSET = "utf-8"; // 设置编码 public MyTask(File f,SVDraw s,TextView tv){ this.file = f; this.surfaceView = s; this.tv = tv; } @Override protected void onPreExecute() { } //doInBackground方法内部执行后台任务,不可在此方法内修改UI @Override protected String doInBackground(String... params) { //调用文件上传方法 result_content = uploadFile(file,"http://13.76.211.62/"); return null; } //onProgressUpdate方法用于更新进度信息 @Override protected void onProgressUpdate(Integer... progresses) { } //onPostExecute方法用于在执行完后台任务后更新UI,显示结果 @Override protected void onPostExecute(String result) { //由于返回的是一个python的字典形式的字符串,用json来解析 JSONObject obj = null; List keys = new ArrayList (); List values = new ArrayList (); try { obj = new JSONObject(result_content); //json对象的Key的迭代器,用来遍历json Iterator it = obj.keys(); while (it.hasNext()) { String key = (String) it.next(); String value = obj.getString(key); keys.add(key); values.add(value); } } catch (JSONException e) { e.printStackTrace(); } //绘制图形 surfaceView.clearDraw(); surfaceView.drawLine(keys,values); tv.setText("搭配很赞哦"); } //onCancelled方法用于在取消执行中的任务时更改UI @Override protected void onCancelled() { } /** * 上传图片文件到服务器 * @param file * @param RequestURL * @return */ public static String uploadFile(File file, String RequestURL) { String result = null; String BOUNDARY = UUID.randomUUID().toString(); // 边界标识 随机生成 String PREFIX = "--", LINE_END = "\r\n"; String CONTENT_TYPE = "multipart/form-data"; // 内容类型 try { //创建URL连接,指明连接地址 URL url = new URL(RequestURL); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); //设置http请求的属性为POST conn.setReadTimeout(TIME_OUT); conn.setConnectTimeout(TIME_OUT); conn.setDoInput(true); // 允许输入流 conn.setDoOutput(true); // 允许输出流 conn.setUseCaches(false); // 不允许使用缓存 conn.setRequestMethod("POST"); // 请求方式 conn.setRequestProperty("Charset", CHARSET); // 设置编码 conn.setRequestProperty("connection", "keep-alive"); conn.setRequestProperty("Content-Type", CONTENT_TYPE + ";boundary=" + BOUNDARY); if (file != null) { /** * 当文件不为空,把文件包装并且上传 */ Log.i(TAG,"upload"); DataOutputStream dos = new DataOutputStream(conn.getOutputStream()); Log.e(TAG,"not null"); /** * 这里重点注意: name里面的值为服务端需要key 只有这个key 才可以得到对应的文件 * filename是文件的名字,包含后缀名的 比如:abc.png */ InputStream is = new FileInputStream(file); byte[] bytes = new byte[1024]; int len; while ((len = is.read(bytes)) != -1) { dos.write(bytes, 0, len); } is.close(); dos.flush(); Log.e(TAG,"sent"); /** * 获取响应码 200=成功 当响应成功,获取响应的流 */ int res = conn.getResponseCode(); Log.e(TAG, "response code:" + res); Log.e(TAG, "request success"); InputStream input = conn.getInputStream(); StringBuffer sb1 = new StringBuffer(); int ss; while ((ss = input.read()) != -1) { sb1.append((char) ss); } result = sb1.toString(); Log.e(TAG, "result : " + result); } } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return result; } } 
3、初始化界面、照相机,使得照相机能够实时预览,并实现拍照功能
 package com.hd.hd;
import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.ImageFormat;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCaptureSession;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CameraManager;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.CaptureResult;
import android.hardware.camera2.TotalCaptureResult;
import android.media.Image;
import android.media.ImageReader;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.HandlerThread;
import android.support.annotation.NonNull;
import android.support.annotation.RequiresApi;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.util.SparseIntArray;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.Arrays;
public class MainActivity extends AppCompatActivity{
  private static final SparseIntArray ORIENTATIONS = new SparseIntArray();
  private String TAG = "MainActivity";
  ///为了使照片竖直显示
  static {
    ORIENTATIONS.append(Surface.ROTATION_0, 90);
    ORIENTATIONS.append(Surface.ROTATION_90, 0);
    ORIENTATIONS.append(Surface.ROTATION_180, 270);
    ORIENTATIONS.append(Surface.ROTATION_270, 180);
  }
  private SurfaceView mSurfaceView;
  private SurfaceHolder mSurfaceHolder;
  private CameraManager mCameraManager;//摄像头管理器
  private Handler childHandler, mainHandler;
  private String mCameraID;//摄像头Id 0 为后 1 为前
  private ImageReader mImageReader;
  private CameraCaptureSession mCameraCaptureSession;
  private CameraDevice mCameraDevice;
  private SVDraw hSurfaceView;
  private MyTask myTask;
  private CaptureRequest.Builder captureRequestBuilder;
  private TextView tv;
  private final int DRAW_ORDER = 10;
  private Handler myHandler;
  private ImageView imageView;
  private String dir = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Healthy_d/";
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    //此步骤非常重要,安卓不用自动帮你创建文件夹来保存拍照的照片
    File dirFirstFolder = new File(dir);//方法二:通过变量文件来获取需要创建的文件夹名字
    if(!dirFirstFolder.exists())
    { //如果该文件夹不存在,则进行创建
      dirFirstFolder.mkdirs();//创建文件夹
    }
    //Android 6后有些敏感的权限不能随意分配,必须向用户发送请求赋予
    //这里请求用户赋予拍照,读写内存卡,连接网络的权限,其实只有拍照权限需要向用户请求,但是有备无患吧
    if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
      Log.e(TAG,ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)+"");
      ActivityCompat.requestPermissions(MainActivity.this,
          new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
          43);
    }
    if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
      ActivityCompat.requestPermissions(MainActivity.this,
          new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
          44);
    }
    if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.INTERNET) != PackageManager.PERMISSION_GRANTED) {
      ActivityCompat.requestPermissions(MainActivity.this,
          new String[]{Manifest.permission.INTERNET},
          45);
    }
    initVIew();
  }
  /**
   * 初始化视图
   */
  private void initVIew() {
    HandlerThread handlerThread = new HandlerThread("Camera2");
    handlerThread.start();
    childHandler = new Handler(handlerThread.getLooper());
    //mSurfaceView
    mSurfaceView = (SurfaceView) findViewById(R.id.surfaceView);
    hSurfaceView = (SVDraw) findViewById(R.id.mySurfaceView);
    imageView = (ImageView) findViewById(R.id.btngal);
    tv = (TextView)findViewById(R.id.textview);
    //设置ImageView监听器,点击图片,拍照
    imageView.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View v) {
        Toast.makeText(MainActivity.this, "正在识别,请稍等", Toast.LENGTH_LONG).show();
        if (mCameraDevice == null) return;
        // 创建拍照需要的CaptureRequest.Builder
        try {
          captureRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
          // 将imageReader的surface作为CaptureRequest.Builder的目标
          captureRequestBuilder.addTarget(mImageReader.getSurface());
          // 自动对焦
          captureRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
          // 自动曝光
          captureRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);
          // 获取手机方向
          int rotation = getWindowManager().getDefaultDisplay().getRotation();
          // 根据设备方向计算设置照片的方向
          captureRequestBuilder.set(CaptureRequest.JPEG_ORIENTATION, ORIENTATIONS.get(rotation));
          //拍照
          CaptureRequest mCaptureRequest = captureRequestBuilder.build();
          mCameraCaptureSession.capture(mCaptureRequest, mSessionCaptureCallback, childHandler);
        } catch (CameraAccessException e) {
          e.printStackTrace();
        }
      }
    });
    mSurfaceHolder = mSurfaceView.getHolder();
    mSurfaceHolder.setKeepScreenOn(true);
    // mSurfaceView添加回调
    mSurfaceHolder.addCallback(new SurfaceHolder.Callback() {
      @Override
      public void surfaceCreated(SurfaceHolder holder) { //SurfaceView创建
        // 初始化Camera
        initCamera2();
      }
      @Override
      public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
      }
      @Override
      public void surfaceDestroyed(SurfaceHolder holder) { //SurfaceView销毁
        // 释放Camera资源
        if (null != mCameraDevice) {
          mCameraDevice.close();
          mCameraDevice = null;
        }
      }
    });
  }
  //拍照时,可以对照片进行操作,这里可以不写,因为我没对其进行操作
  private CameraCaptureSession.CaptureCallback mSessionCaptureCallback =
      new CameraCaptureSession.CaptureCallback() {
        @Override
        public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request,
                        TotalCaptureResult result) {}
        @Override
        public void onCaptureProgressed(CameraCaptureSession session, CaptureRequest request,
                        CaptureResult partialResult){}};
  /**
   * 初始化Camera2
   */
  @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
  private void initCamera2() {
    HandlerThread handlerThread = new HandlerThread("Camera2");
    handlerThread.start();
    childHandler = new Handler(handlerThread.getLooper());
    mainHandler = new Handler(getMainLooper());
    mCameraID = "" + CameraCharacteristics.LENS_FACING_FRONT;//后摄像头
    mImageReader = ImageReader.newInstance(mSurfaceView.getWidth(), mSurfaceView.getHeight(), ImageFormat.JPEG,1);
    mImageReader.setOnImageAvailableListener(new ImageReader.OnImageAvailableListener() { //可以在这里处理拍照得到的临时照片 例如,写入本地
      @Override
      public void onImageAvailable(ImageReader reader) {
        Image image = reader.acquireNextImage();
        ByteBuffer buffer = image.getPlanes()[0].getBuffer();
        byte[] bytes = new byte[buffer.remaining()];
        buffer.get(bytes);//由缓冲区存入字节数组
        Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
        String fileName = "test";
        File file = new File(dir + fileName + ".jpg");
        String state = Environment.getExternalStorageState();
        //如果状态不是mounted,无法读写
        if (!state.equals(Environment.MEDIA_MOUNTED)) {
          return;
        }
        FileOutputStream out = null;
        try {
          out = new FileOutputStream(file);
          bitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);//转化为jpeg图片
          out.flush();
          out.close();
          image.close();//一定要记得关,否则会出现程序崩溃
        } catch (FileNotFoundException e) {
          e.printStackTrace();
        } catch (IOException e) {
          e.printStackTrace();
        }
        new MyTask(file,hSurfaceView,tv).execute();
      }
    }, mainHandler);
    //获取摄像头管理
    mCameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
    try {
      if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(this,
            new String[]{Manifest.permission.CAMERA},
            42);
      }
      //打开摄像头
      mCameraManager.openCamera(mCameraID, stateCallback, mainHandler);
    } catch (CameraAccessException e) {
      e.printStackTrace();
    }
  }
  /**
   * 当发送权限请求用户响应时,回调该函数
   * @param requestCode
   * @param permissions
   * @param grantResults
   */
  @Override
  public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    if (requestCode == 42) {
      Toast.makeText(this, "CAMERA PERMISSION GRANTED", Toast.LENGTH_SHORT).show();
      if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
        //申请成功,可以拍照
        Log.i(TAG,"apply camera success");
        CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
        try {
          if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
            Toast.makeText(this, "CAMERA PERMISSION DENIED", Toast.LENGTH_SHORT).show();
          }
          mCameraManager.openCamera(mCameraID, stateCallback, mainHandler);
        } catch (CameraAccessException e) {
          e.printStackTrace();
        }
      } else {
        Toast.makeText(this, "CAMERA PERMISSION DENIED", Toast.LENGTH_SHORT).show();
      }
      return;
    }
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
  }
  /**
   * 摄像头创建监听
   */
  private CameraDevice.StateCallback stateCallback = new CameraDevice.StateCallback() {
    @Override
    public void onOpened(CameraDevice camera) {//打开摄像头
      mCameraDevice = camera;
      //开启预览
      takePreview();
    }
    @Override
    public void onDisconnected(CameraDevice camera) {//关闭摄像头
      if (null != mCameraDevice) {
        mCameraDevice.close();
        mCameraDevice = null;
      }
    }
    @Override
    public void onError(CameraDevice camera, int error) {//发生错误
      Toast.makeText(MainActivity.this, "摄像头开启失败", Toast.LENGTH_SHORT).show();
    }
  };
  /**
   * 开始预览
   */
  private void takePreview() {
    try {
      // 创建预览需要的CaptureRequest.Builder
      final CaptureRequest.Builder previewRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
      // 将SurfaceView的surface作为CaptureRequest.Builder的目标
      previewRequestBuilder.addTarget(mSurfaceHolder.getSurface());
//      previewRequestBuilder.addTarget(mImageReader.getSurface());
      // 创建CameraCaptureSession,该对象负责管理处理预览请求和拍照请求
      mCameraDevice.createCaptureSession(Arrays.asList(mSurfaceHolder.getSurface(), mImageReader.getSurface()), new CameraCaptureSession.StateCallback() // ③
      {
        @Override
        public void onConfigured(CameraCaptureSession cameraCaptureSession) {
          if (null == mCameraDevice) return;
          // 当摄像头已经准备好时,开始显示预览
          mCameraCaptureSession = cameraCaptureSession;
          try {
            // 自动对焦
            previewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
            // 打开闪光灯
            previewRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);
            // 显示预览
            CaptureRequest previewRequest = previewRequestBuilder.build();
            mCameraCaptureSession.setRepeatingRequest(previewRequest, null, childHandler);
          } catch (CameraAccessException e) {
            e.printStackTrace();
          }
        }
        @Override
        public void onConfigureFailed(CameraCaptureSession cameraCaptureSession) {
          Toast.makeText(MainActivity.this, "配置失败", Toast.LENGTH_SHORT).show();
        }
      }, childHandler);
    } catch (CameraAccessException e) {
      e.printStackTrace();
    }
  }
}4、AndroidManifest.xml
上述内容就是Android中怎么实现图片识别功能,你们学到知识或技能了吗?如果还想学到更多技能或者丰富自己的知识储备,欢迎关注创新互联行业资讯频道。
当前文章:Android中怎么实现图片识别功能
文章出自:http://www.scyingshan.cn/article/igjdhi.html

 建站
建站
 咨询
咨询 售后
售后
 建站咨询
建站咨询 
 