文章目录

  • 前言
  • 一、准备工作
  • 二、使用步骤
  • 1.引入库
  • 2.分析接口
  • 三、动态选取图片
  • 1. 拍照上传图片
  • 2. 拍照上传图片
  • 总结



前言

提示:这里可以添加本文要记录的大概内容:
例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。


提示:以下是本篇文章正文内容,下面案例可供参考

一、准备工作

这里采用的是阿里云的印刷文字识别,至于为什么选择因为阿里对开发者友好
首先购买识别接口地址如下: 个人开发的话买0.01元的就行了

购买后进入管控中心得到AppCode如图:

Android 形状识别 基于安卓的图像识别_安卓


注意:购买界面有接口文档说明,如果看不太懂那么请往下看

现在可以愉快的进行代码开发了

二、使用步骤

1.引入库

为了方便实现这里采用Retrofit进行网络编程

implementation ‘com.squareup.retrofit2:retrofit:2.7.1’
implementation ‘com.squareup.retrofit2:converter-gson:2.7.1’
implementation ‘com.squareup.okhttp3:okhttp:4.8.1’

Android所需权限声明:

<uses-permission android:name="android.permission.INTERNET"/>
    <!--调用相机拍照并返回图片-->
    <uses-permission android:name="android.permission.CAMERA"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

2.分析接口

这里是阿里接口文档如图:

Android 形状识别 基于安卓的图像识别_android_02


这里image参数需要传入图片二进制数据的base64编码/图片url

那么我们知道了地址和参数和需求,开始请求!

代码如下(示例):

Bitmap对象压缩转码,从这个方法处理后得到了图片的转码我们就可以直接传入接口了

public static String bitmapToBase64(Bitmap bitmap) {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();   //输出流

        //参数一:压缩图片的格式  参数二:压缩量100表示不压缩  参数三: 新建的输入流对象
        bitmap.compress(Bitmap.CompressFormat.JPEG, 40, bos);

        byte[] bytes = bos.toByteArray();
        //转换来的base64码不需要加前缀,必须是NO_WRAP参数,表示没有空格。
        return Base64.encodeToString(bytes, Base64.NO_WRAP);
        //转换来的base64码需要需要加前缀,必须是NO_WRAP参数,表示没有空格。
        //return "data:image/jpeg;base64," + Base64.encodeToString(bytes, Base64.NO_WRAP);
        //如果成功压缩到指定的流,则为true  反之。。
    }

接口处理:

要解析哪个图片就传入它

private void loadImage(ImageView image) {
        BitmapDrawable drawable = (BitmapDrawable) image.getDrawable();
        Bitmap bitmap = drawable.getBitmap();
        String APPCODE = "你的APPCODE";
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("https://tysbgpu.market.alicloudapi.com")
                .addConverterFactory(GsonConverterFactory.create())
                .build();

        AliService aliService = retrofit.create(AliService.class);

        String body = "{\"image\":\""+bitmapToBase64(bitmap)+"\"," +
                "\"configure\":{\"min_size\":16,\"output_prob\":false,\"output_keypoints\":false,\"skip_detection\":false,\"without_predicting_direction\":false}}";

        RequestBody requestBody = RequestBody.create(okhttp3.MediaType.parse("application/json;charset=UTF-8"), body);
        Call<HttpResult> call = aliService.getText(requestBody, "APPCODE " + APPCODE);
        call.enqueue(new Callback<HttpResult>() {
            @Override
            public void onResponse(Call<HttpResult> call, Response<HttpResult> response) {
                //根据返回的json解析出来并更新UI

                HttpResult httpResult = response.body();
                StringBuffer stringBuffer = new StringBuffer();

                for (Bean item:
                     httpResult.getRet()) {
                    stringBuffer.append(item.getWord());
                }

                Toast.makeText(ImageShowActivity.this, ""+stringBuffer.toString(), Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onFailure(Call<HttpResult> call, Throwable t) {
                Toast.makeText(ImageShowActivity.this, ""+t.getMessage(), Toast.LENGTH_SHORT).show();
            }
        });
    }

注:Bean是我根据官方文档里请求成功返回的参数用Gson插件转出来的dataclass

传入一张写有诗文的图片

Android 形状识别 基于安卓的图像识别_安卓_03

结果则会把这张图的诗句完美导出!

三、动态选取图片

1. 拍照上传图片

因为我用的是Android6.0以上版本所以要先申请权限
在给入口Activity页面里进行权限申请:

if (!checkisPermissionCAMERA())
            ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.CAMERA,Manifest.permission.WRITE_EXTERNAL_STORAGE}, CAMERA);
private boolean checkisPermissionCAMERA() {
        return
                ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED &&
                        ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED;

    }

运行App后点击同意权限就ok了

  • 核心代码开始:-------------------------------------------------------------------------

这里我用的是FileProvider不懂的 看这里

先给FileProvider声明数据源 AndroidManifest.xml文件下内添加如下声明

<provider
    android:name="android.support.v4.content.FileProvider"
    android:authorities="app的包名.fileProvider"
    android:grantUriPermissions="true"
    android:exported="false">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/file_paths" />
</provider>

创建file_paths文件资源配置
将目录切换到project 依次打开app->main->res 新建一个xml包 ->新建file_paths.xml

file_paths.xml配置如下:

Android 形状识别 基于安卓的图像识别_android_04


path:需要临时授权访问的路径(.代表所有路径)

name:就是你给这个访问路径起个名字

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path
        name="camera_photos"
        path="."/>      
</paths>

完成配置后发现没有爆红了那么我们就可以在代码中使用FileProvider了

private int PHOTO_REQUEST_CAREMA = 1  ; //拍照
    private int RESULT_LOAD_IMAGE = 2;  //图库


private void openCamera() throws IOException {
        File file = new File(getFilePath());
        String fileName = System.currentTimeMillis() + ".jpg";
        File picture = new File(file, fileName);
        if (!picture.exists()) picture.createNewFile();
        imagePath = picture.getAbsolutePath();
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, FileProvider.getUriForFile(this, "com.xy.youxianghaoche.fileprovider", picture));
        startActivityForResult(intent, PHOTO_REQUEST_CAREMA);
    }
private String getFilePath() {
        String absolutePath = getExternalFilesDir(Environment.MEDIA_MOUNTED).getAbsolutePath();
        File file = new File(absolutePath);
        if (!file.exists())file.mkdirs();
        return absolutePath;
    }

调用这个方法就可以调用相机了,但是还差了拍照后的图片显示
重写回调方法

@Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == PHOTO_REQUEST_CAREMA){  //相机回调
            Bitmap bitmap = BitmapFactory.decodeFile(imagePath);
            imageViewshow.setImageBitmap(bitmap);
        }if (requestCode == RESULT_LOAD_IMAGE){	//图库回调
            Uri uri = data.getData();
            imageViewshow.setImageURI(uri);
        }
    }

这里先忽略图库回调下面会讲到
之后我们的照相机拍下的照片就可以展示在ImageView控件里了

2. 拍照上传图片

图库选择就更简单了,代码如下:
private void openGallery() {
        Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
        intent.setType("image/*");
        startActivityForResult(intent, RESULT_LOAD_IMAGE);
    }

回到之前照相机的回调进行声明

@Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == PHOTO_REQUEST_CAREMA){
            Bitmap bitmap = BitmapFactory.decodeFile(imagePath);
            imageViewshow.setImageBitmap(bitmap);
        }if (requestCode == RESULT_LOAD_IMAGE){
            Uri uri = data.getData();
            imageViewshow.setImageURI(uri);
        }
    }

总结

需要源码的下面评论