上一篇实现了语音播放的功能,接下来就开始实现相机及图像识别功能调用。

首先,画一个大致的流程图方便理解:

以下是对相机/选择相册进行实现。

(大家可以参考其它Android调用相机/选择相册的教程,不一定使用我的代码,只要获取好地址就可以。)

(主要步骤是启动相机-调用相机-保存图片(地址一定要保存好),在相册选择图片也亦然,知道步骤后实现就比较简单)

Button takePhoto =  findViewById(R.id.camerabutton);//拍照的按钮takePhoto.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                if(ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED){                    ActivityCompat.requestPermissions(MainActivity.this,new String[]{Manifest.permission.CAMERA},24);                }                File outputImage = new File(getExternalCacheDir(), "output_image.jpg");                try {                    if (outputImage.exists()) {                        outputImage.delete();                    }                    outputImage.createNewFile();                } catch (IOException e) {                    e.printStackTrace();                }                try {                    if (outputImage.exists()) {                        outputImage.delete();                    }                    outputImage.createNewFile();                } catch (IOException e) {                    e.printStackTrace();                }                //判断版本号                if (Build.VERSION.SDK_INT < 24) {                    imageUri = Uri.fromFile(outputImage);                } else {                    imageUri = FileProvider.getUriForFile(MainActivity.this, "com.MapScanner.MapScanner", outputImage);                }                // 启动相机程序                Log.d("TAG", "---------b"+outputImage.getAbsolutePath());                Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");;                intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);                startActivityForResult(intent, TAKE_PHOTO);            }        });

 

@Override    protected void onActivityResult(int requestCode, int resultCode, Intent data) {        Log.d("TAG", "---------d----"+requestCode+"----"+resultCode+"----"+data);        //成功的时候requestCode:1   resultCode:1 失败的时候requestCode:1   resultCode:0        switch (requestCode) {            case 1:                try {// 将拍摄的照片显示出来                    Date date=new Date(System.currentTimeMillis());                    SimpleDateFormat dateFormat=new SimpleDateFormat("yyyyMMddHHmmss");                    String fileName=dateFormat.format(date)+".jpeg";                    String name=Environment.getExternalStorageDirectory().getPath()+"/DCIM/Camera/"+fileName ;                    File file = new File(name);                    FileOutputStream out;                    Matrix matrix = new Matrix();                    matrix.setRotate(90);                    Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(imageUri));                    bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(),bitmap.getHeight(), matrix, true);                    picture.setImageBitmap(bitmap);                    try{                        out = new FileOutputStream(file);                        // 格式为 JPEG,照相机拍出的图片为JPEG格式的,PNG格式的不能显示在相册中                        if(bitmap.compress(Bitmap.CompressFormat.JPEG, 90, out))                        {                            out.flush();                            out.close();                            MediaStore.Images.Media.insertImage(this.getContentResolver(), file.getAbsolutePath(), name, null);                        }                    }                    catch (FileNotFoundException e)                    {                        e.printStackTrace();                    }                    catch (IOException e)                    {                        e.printStackTrace();                    }                    path=name;                    Log.d("TAG", "imagePath====== " + imageUri);                } catch (Exception e) {                    e.printStackTrace();                }                break;            case 2:                // 判断手机系统版本号                if (Build.VERSION.SDK_INT >= 19) {                    // 4.4及以上系统使用这个方法处理图片                    handleImageOnKitKat(data);                } else {                    // 4.4以下系统使用这个方法处理图片                    handleImageBeforeKitKat(data);                }                break;            default:                break;        }    }

对于选取相册中的图片。

Button choosePicture = findViewById(R.id.picturebutton);        choosePicture.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {                    ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 2);                }                Intent intent = new Intent("android.intent.action.GET_CONTENT");                intent.setType("image/*");                startActivityForResult(intent, CHOOSE_PHOTO);            }        });

 HandleImage的处理

   @TargetApi(19)    private void handleImageOnKitKat(Intent data) {        String imagePath = null;        Uri uri = data.getData();        Log.d("TAG", "handleImageOnKitKat: uri is " + uri);        if (DocumentsContract.isDocumentUri(this, uri)) {            // 如果是document类型的Uri,则通过document id处理            String docId = DocumentsContract.getDocumentId(uri);            if("com.android.providers.media.documents".equals(uri.getAuthority())) {                String id = docId.split(":")[1]; // 解析出数字格式的id                String selection = MediaStore.Images.Media._ID + "=" + id;                imagePath = getImagePath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, selection);            }            else if ("com.android.providers.downloads.documents".equals(uri.getAuthority())) {                Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(docId));                imagePath = getImagePath(contentUri, null);            }        }        else if ("content".equalsIgnoreCase(uri.getScheme())) {            // 如果是content类型的Uri,则使用普通方式处理            imagePath = getImagePath(uri, null);        }        else if ("file".equalsIgnoreCase(uri.getScheme())) {            // 如果是file类型的Uri,直接获取图片路径即可            imagePath = uri.getPath();        }        displayImage(imagePath); // 根据图片路径显示图片    }    private void handleImageBeforeKitKat(Intent data) {        Uri uri = data.getData();        String imagePath = getImagePath(uri, null);        displayImage(imagePath);    }    private String getImagePath(Uri uri, String selection) {        String path = null;        // 通过Uri和selection来获取真实的图片路径        Cursor cursor = getContentResolver().query(uri, null, selection, null, null);        if (cursor != null) {            if (cursor.moveToFirst()) {                path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));            }            cursor.close();        }        return path;    }    private void displayImage(String imagePath) {        path=imagePath;        if (imagePath != null) {            Bitmap bitmap = BitmapFactory.decodeFile(imagePath);            picture.setImageBitmap(bitmap);        }        else {            Toast.makeText(this, "failed to get image", Toast.LENGTH_SHORT).show();        }    }

(权限的声明在上一篇已经设置好,这里就不重复设置了) 

相机设置完毕后,就是实现图像识别调用的功能,因为我们实现的是四个识别,其实界面都是一样,只是方法调用里面只需要修改,所以我们在跳转页面的时候,给它一个标志位,只需要修改调用的内容和把处理返回来数据内容作修改即可。

看图的话直观一点:(两个不同识别是使用同一个界面,只是调用的接口不一样,其他功能可以复用)

 上代码:

首先是ViewActivity下,跳转到MainActivity回传选择的是哪一个识别。

(只截取了ViewActivity跳转部分代码,ViewActivity在介绍界面的时候再做细讲。)

public void myClick(View v)    {        //btncommon   btnanimal  btnplant  btnplace        String name="";        switch(v.getId())        {            case R.id.btncommon:                name="btncommon";                break;            case R.id.btnanimal:                name="btnanimal";                break;            case R.id.btnplant:                name="btnplant";                break;            case R.id.btnplace:                name="btnplace";                break;        }Intent i = new Intent(ViewActivity.this, MainActivity.class);        i.putExtra("myChoose",name);        startActivity(i);}

 

跳转到MainActivity中获取name。(这里是把标题修改了)

Intent i=getIntent();//页面选择        final String youChoose=i.getStringExtra("myChoose");        switch (youChoose){            case "btncommon":                setTitle("通用识别");                break;            case "btnanimal":                setTitle("动物识别");                break;            case "btnplant":                setTitle("植物识别");                break;            case "btnplace":                setTitle("地标识别");                break;        }

 接下来截取通用识别代码部分讲解。

当我们把图片选择好/调用拍照后,点击识别按钮,就开始调用 通用识别 进行工作。

首先图像识别申请信息必不可少

//图像识别申请信息    String APP_ID="你的百度id";    String API_KEY="你的百度KEY";    String SECRET_KEY="你的百度SECRET_KEY";    String path="";//存地址
  Button takePhoto =  findViewById(R.id.camerabutton);        Button choosePicture = findViewById(R.id.picturebutton);        Button chooseOk=findViewById(R.id.okbutton);//按钮的定义按照自己的需求

 chooseok点击进行处理

chooseOk.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                if (path!="") {                    Toast.makeText(getApplicationContext(),"正在识别...请稍等",Toast.LENGTH_LONG).show();                    new Thread(){                        public void run(){                            //线程处理                            AipImageClassify client = new AipImageClassify(APP_ID, API_KEY, SECRET_KEY);                            HashMap options = new HashMap();                            options.put("baike_num", "4");                            String image = path;                            switch (youChoose){                                case "btncommon":                                    res = client.advancedGeneral(image, options);//通用                                    try {                                        JSONArray jsonArray = res.getJSONArray("result");//返回JsonArray                                        for(int i=0;i

我们可以看到不同识别的调用在于

res = client.advancedGeneral(image, options);//通用

这一句话里面,如果我是动物识别调用就是

res = client.animalDetect(image, options);//动物

所以在switch里面,只需要修改client.xxx函数,还有对返回的数据

res.getJSONObject

进行处理显示,即可达到效果。(不同的识别调用返回的数据格式不一样,需要分开处理,详情阅读 视觉技术 图像识别 API文档 可查阅有关返回的格式信息)

我们还发现,我们在Android6.0版本测试中,ui在此线程中更新的话会报错(UI线程不安全),为解决这个问题,我们通过用Handler方式更新UI。

private  Handler handler=new Handler(){        public  void handleMessage(android.os.Message msg){//获取消息携带的属性值            int what = msg.what;            System.out.println("-what--->>" + what);            switch (what)            {                case 1:                    Mytype.setText("类型:   "+save_type);                    Myname.setText("名称:   "+save_name);                    mShowText.setText(Speck_TEXT);                    break;                case 2:                    Mytype.setText("类型:   无");                    Myname.setText("名称:   无");                    mShowText.setText("类型无法识别,请尝试重新拍照或按类型进行识别。");                    break;                 default:break;            }        };    };

 

结合上一节和这一节,语音播放和拍照/选择图片/图像识别功能局可以成功实现。(核心功能就已经实现)

下一节的话,就介绍界面的设计/启动程序动画。 

更多相关文章

  1. Android(安卓)View从源码的角度分析事件的注册和接收
  2. 2016年腾讯android开发工程师面试题目
  3. 在 Android(安卓)中使用 JNI 的总结
  4. [Android] 图像处理整合之处理ColorMatrix和Intend传递路径显示
  5. Android中实现native服务利用binder与应用通信
  6. Android(安卓)studio 小白使用Android(安卓)studio 2.3.1遇到的
  7. Android实现拍照或从相册中获取图片并且显示圆形图片
  8. Android(安卓)Activity 与Service进行数据交互详解
  9. Android(安卓)显示图片的时候设置转换动画

随机推荐

  1. 解读ExpandableListView源码样式
  2. 初探 Ubuntu下android NDK
  3. 在 actionbar中使用 searchview
  4. Android Studio点击按钮更换背景图片
  5. Android 常用权限
  6. android相关
  7. android scroller类的使用
  8. 安卓横屏设置:
  9. android中ImageView、ImageButton、Butto
  10. Android 设置隐式意图