Android   发布时间:2022-04-28  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了Android图片识别应用详解大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

最近由于参加一个小小的创意比赛,用安卓做了一个小小的图片识别应用,主要是通过拍照识别图片中的菜品,还有对象位置查找的东西。之前没有做过安卓,都是拼拼凑凑多篇博客完成的,我也把这个项目的一些过程分享一下。先把功能贴一下,其实就是点击拍照,将照片保存在本地,然后识别出图中的菜品,然后用红色方框圈出来,并显示菜品种类。采用最新的Camera2的API,的确是比Camera好用。

Android图片识别应用详解

Android图片识别应用详解

1、界面

我采用了一个SurfaceView用来显示摄像头的预览画面,重写了一个SurfaceView来进行红色方框还有菜品名字的绘制。图片一个ImageVIew,相当于拍照按钮的功能

 <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
  xmlns:android="http://scheR_182_11845@as.android.com/apk/res/android"
  xmlns:tools="http://scheR_182_11845@as.android.com/tools"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  tools:context="com.hd.hd.MainActivity">

  <SurfaceView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/surfaceView"
    android:layout_centerHorizontal="true"
    android:layout_centerVertical="true"/>

  <com.hd.hd.SVDraw
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/mySurfaceView"
    android:layout_centerHorizontal="true"
    android:layout_centerVertical="true"/>
  <LinearLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:layout_alignParentBottom="true"
    >
  <ImageView
    android:id="@+id/btngal"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:gravity="center_horizontal"
    android:layout_alignParentBottom="true"
    android:src="@drawable/s_8"
    android:layout_alignParentLeft="true"

     />

  <TextView
    android:id="@+id/textview"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:textColor="@color/white"
    android:textSize="20dp"
    android:layout_toRightOf="@id/btngal"
    android:layout_alignParentTop="true"

    />
  </LinearLayout>

</RelativeLayout>

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<String> keys,List<String> 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.@R_450_9363@ce("[","");
      v = v.@R_450_9363@ce("]","");
      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<String,Integer,String> {

  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<String> keys = new ArrayList<String>();
    List<String> values = new ArrayList<String>();
    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(); // 边界标识 @L_489_43@生成
    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,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.@R_751_10586@lCaptureResult;
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,@R_751_10586@lCaptureResult result) {}

        @Override
        public void onCaptureProgressed(CameraCaptureSession session,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,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();
    }
  }

  /**
   * 当发送权限请求用户响应时,回调该@L_618_80@
   * @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,mainHandler);
        } catch (CameraAccessException E) {
          e.printStackTrace();
        }
      } else {
        Toast.makeText(this,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

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://scheR_182_11845@as.android.com/apk/res/android"
  package="com.hd.hd">

  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
  <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
  <uses-permission android:name="android.permission.CAMERA"/>
  <uses-feature android:name="android.hardware.camera2.full" />
  <uses-permission android:name="android.permission.INTERNET" />

  <application
    android:allowBACkup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@String/app_name"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <activity android:name=".MainActivity">
      <intent-filter>
        <action android:name="android.intent.action.MAIN" />

        <category android:name="android.intent.category.LAUNCHER" />
      </intent-filter>
    </activity>
  </application>

</manifest>

今天代码分享到那么多,明天给大家分享一下Camera2的架构。有不懂的可以评论,一起讨论。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程小技巧。

大佬总结

以上是大佬教程为你收集整理的Android图片识别应用详解全部内容,希望文章能够帮你解决Android图片识别应用详解所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。
标签: