Recently, the OCR character recognition API of Ali Cloud was used

Let’s take a look at the effect

I use the general type of text recognition, the specific implementation process is as follows:

1. BuyAli Cloud general type of text recognition

It is currently free for 0 yuan and can be used 500 times. After the purchase is successful, go to -> Console -> Cloud Marketplace to view the purchased API and copy its APPCODE.

2. According toOfficial API documentationSubmit a request

I used Retrofit to submit network requests, defining the following interface:

interface AliService{
        @POST("/api/predict/ocr_general")
        Call<HttpResult> getText(@Body RequestBody body,@Header("Authorization") String authorization);
    }
Copy the code

HTTPResult class: HTTPResult class: HTTPResult class: HTTPResult class: HTTPResult class:

public class HttpResult{
    private String request_id;
    private List<Bean> ret;
    private boolean success;
}
class Bean{
    private Rect rect;
    private String word;
    
    class Rect{
        private float angle;
        private float height;
        private float left;
        private float top;
        private floatwidth; }}Copy the code

Since the image is in Bitmap format, we have to base64 encode the image and request it.

public static String bitmapToBase64(Bitmap bitmap) {
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    bitmap.compress(Bitmap.CompressFormat.JPEG, 40, bos);// The 100 parameter indicates no compression
    byte[] bytes = bos.toByteArray();
    // The base64 code converted does not need to be prefixed. It must be NO_WRAP, indicating that there is no space.
    return Base64.encodeToString(bytes, Base64.NO_WRAP);
    // The base64 code to be converted must be prefixed with the NO_WRAP parameter, indicating that there is no space.
    //return "data:image/jpeg; base64," + Base64.encodeToString(bytes, Base64.NO_WRAP);
}

Copy the code

Construct the request body according to the request parameters in the official document:

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_pred icting_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) {
        // Parse and update the UI based on the returned JSON
        if(response.body().getRet()! =null){
            List<Bean> beans = response.body().getRet();
            for (Bean bean : beans)
                text += bean.getWord()+"\n";
            activity.runOnUiThread(new Runnable() {
                @Override
                public void run(a) { textView.setText(text); }}); }}@Override
    public void onFailure(Call<HttpResult> call, Throwable t) {
        Log.e(TAG, "onFailure: "+t.getMessage()); }});Copy the code

Above, is the core code to call ali Cloud OCR interface. If you’re not sure how to call the camera to take a picture and return it, read on.

3.Android calls the camera to take a picture and returns it

① Apply for permission in the AndroidManifest file.

    <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"/>
Copy the code

Declare FileProvide in application:

        <provider
            android:authorities="com.briana.aliocr.provider"// Own the package name
            android:name="androidx.core.content.FileProvider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_paths" />
        </provider>
Copy the code

Create a new XML file and name it file_paths.xml.


      
<resources>
    <paths>
        <external-path
            name="camera_photos"
            path="." />
<! - the path set to 'on behalf of the entire memory card Environment. External.getexternalstoragedirectory () + "/ path/" -- >
    </paths>
</resources>
Copy the code

② Change the following in MainActivity:

Before calling the camera to take photos, determine whether you have permission, no permission, to apply.

  
    private static final int PERMISSIONS_REQUEST_CODE = 1;

	private boolean hasPermission(a){
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) ! = PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) ! = PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(this,Manifest.permission.CAMERA) ! = PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this.new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.CAMERA}, PERMISSIONS_REQUEST_CODE);
            return false;
        }else {
            return true; }}Copy the code

Rewrite onRequestPermissionsResult method, see if request permissions results by the user, if passed, would call takephoto () method takes photos.

  @Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if (requestCode == PERMISSIONS_REQUEST_CODE) {
        if (grantResults.length > 0) {
            for (int grantResult : grantResults) {
                if (grantResult == PackageManager.PERMISSION_DENIED) {
                    return; } } takePhoto(); }}}Copy the code

Call the camera to take pictures and record the picture path:

private static final int CAMERA_REQUEST_CODE = 2;
File mFile;
Uri imageUri;
private void takePhoto(a){
    if(! hasPermission()) {return;
    }
    File path = new File(Environment.getExternalStorageDirectory(),"img");
    mFile = new File(path,System.currentTimeMillis()+".jpg");
    try {
        if(! path.exists()) path.mkdir();if(! mFile.exists()) mFile.createNewFile(); }catch (IOException e) {
        e.printStackTrace();
    }
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        String authority = getPackageName() + ".provider";
        imageUri = FileProvider.getUriForFile(this, authority, mFile);
    } else {
        imageUri = Uri.fromFile(mFile);
    }
    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    intent.putExtra(MediaStore.EXTRA_OUTPUT,imageUri);
    startActivityForResult(intent,CAMERA_REQUEST_CODE);
}
Copy the code

Rewrite the onActivityResult method, obtain the image according to the path, display it in imageView, and then call Ali’s interface for image text recognition.

@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == CAMERA_REQUEST_CODE) {
        Bitmap photo = BitmapFactory.decodeFile(mFile.getAbsolutePath());
        imageView.setImageBitmap(photo);
        AliOcr aliOcr = new AliOcr();
        aliOcr.getText(this,photo); }}Copy the code

Add click event listener to button, click Take photo:

button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) { takePhoto(); }});Copy the code

Finally, the github address and CSDN of Demo are attached for download

If it helps you, give it a thumbs up