Image OCR

Updated at:

Recognize text in images using Content Moderation SDK for Java. Submit a synchronous OCR task with the scenes parameter set to ocr, then parse the response to extract the recognized text.

Use cases

  • Identity verification: Extract text from ID cards and passports to verify user identity during onboarding.

  • Content filtering: Detect inappropriate or prohibited text embedded in user-uploaded images.

  • Automated data entry: Parse structured text from receipts, forms, or labels to reduce manual input.

  • License plate recognition: Extract vehicle plate numbers from traffic or security camera images.

Prerequisites

Before you begin, ensure that you have:

  • Java dependencies installed. See Installation for the required Java version. Using a different version causes operation call failures.

  • (For local images or binary image streams) The Extension.Uploader utility class downloaded and imported into your project.

Important

Use a RAM user's AccessKey ID and AccessKey secret instead of your Alibaba Cloud account credentials. Store credentials in environment variables rather than hardcoding them in your source code.

Submit synchronous OCR tasks

ImageSyncScanRequest submits synchronous OCR tasks. Set the scenes parameter to ocr to recognize text in images.

Supported regions

Region ID

Location

cn-shanghai

China (Shanghai)

cn-beijing

China (Beijing)

cn-shenzhen

China (Shenzhen)

ap-southeast-1

Singapore

How it works

  1. Initialize a client with your region and credentials.

  2. Build an ImageSyncScanRequest with scenes set to ["ocr"] and one task object per image.

  3. Call doAction() to submit the request synchronously.

  4. Parse the response: check the top-level code, iterate over data, and for each task result check suggestion and scene.

  • Detect an image using its URL

    import com.alibaba.fastjson.JSON;
    import com.alibaba.fastjson.JSONArray;
    import com.alibaba.fastjson.JSONObject;
    import com.aliyuncs.DefaultAcsClient;
    import com.aliyuncs.IAcsClient;
    import com.aliyuncs.exceptions.ClientException;
    import com.aliyuncs.exceptions.ServerException;
    import com.aliyuncs.green.model.v20180509.ImageSyncScanRequest;
    import com.aliyuncs.http.FormatType;
    import com.aliyuncs.http.HttpResponse;
    import com.aliyuncs.http.MethodType;
    import com.aliyuncs.http.ProtocolType;
    import com.aliyuncs.profile.DefaultProfile;
    import com.aliyuncs.profile.IClientProfile;
    
    import java.util.*;
    
    public class Main {
    
        public static void main(String[] args) throws Exception {
            /**
             * An Alibaba Cloud account AccessKey has full permissions on all APIs. We recommend that you use a Resource Access Management (RAM) user to make API calls or perform O&M. 
             * Common methods to obtain environment variables:
             * Method 1:
             *     Obtain the AccessKey ID of the RAM user: System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID");
             *     Obtain the AccessKey secret of the RAM user: System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET");
             * Method 2:
             *     Obtain the AccessKey ID of the RAM user: System.getProperty("ALIBABA_CLOUD_ACCESS_KEY_ID");
             *     Obtain the AccessKey secret of the RAM user: System.getProperty("ALIBABA_CLOUD_ACCESS_KEY_SECRET");
             */
            DefaultProfile profile = DefaultProfile.getProfile(
                    "cn-shanghai",
                    "Obtain the AccessKey ID of a RAM user from an environment variable",
                    "Obtain the AccessKey secret of a RAM user from an environment variable");
            DefaultProfile.addEndpoint("cn-shanghai", "Green", "green.cn-shanghai.aliyuncs.com");
            IAcsClient client = new DefaultAcsClient(profile);
    
            ImageSyncScanRequest imageSyncScanRequest = new ImageSyncScanRequest();
            // Specify the response format.
            imageSyncScanRequest.setAcceptFormat(FormatType.JSON);
            // Specify the request method.
            imageSyncScanRequest.setMethod(MethodType.POST);
            imageSyncScanRequest.setEncoding("utf-8");
            // HTTP and HTTPS are supported.
            imageSyncScanRequest.setProtocol(ProtocolType.HTTP);
    
            JSONObject httpBody = new JSONObject();
            /**
             * Set the detection scenario.
             * ocr: specifies OCR for images and text, and OCR for cards and IDs.
             */
            httpBody.put("scenes", Arrays.asList("ocr"));
    
            /**
             * Set the images to detect. One image corresponds to one detection task.
             * If you detect multiple images at the same time, the processing time is determined by the last image that is processed.
             * The average response time for batch detection is typically longer than that for a single-task detection. The more images you submit in a batch, the more likely the response time increases.
             * The sample code shows how to detect a single image. To detect multiple images in a batch, create multiple tasks.
             */
            JSONObject task = new JSONObject();
            task.put("dataId", UUID.randomUUID().toString());
    
            // Set the image URL.
            task.put("url", "https://example.com/xxx.jpg");
            task.put("time", new Date());
            httpBody.put("tasks", Arrays.asList(task));
    
            // If you use OCR for cards and IDs, set the card or ID type.
            JSONObject cardExtras = new JSONObject();
            // Recognize the front of an ID card.
            cardExtras.put("card", "id-card-front");
            // The back of the ID card.
            //cardExtras.put("card", "id-card-back");
            httpBody.put("extras", cardExtras);
            imageSyncScanRequest.setHttpContent(org.apache.commons.codec.binary.StringUtils.getBytesUtf8(httpBody.toJSONString()), "UTF-8", FormatType.JSON);
            /**
             * Set the timeout period. The server-side end-to-end processing timeout is 10 seconds. Set the timeout period accordingly.
             * If the ReadTimeout value you set is less than the server-side processing time, a read timeout exception occurs in the program.
             */
            imageSyncScanRequest.setConnectTimeout(3000);
            imageSyncScanRequest.setReadTimeout(10000);
            HttpResponse httpResponse = null;
            try {
                httpResponse = client.doAction(imageSyncScanRequest);
            } catch (ServerException e) {
                e.printStackTrace();
            } catch (ClientException e) {
                e.printStackTrace();
            } catch (Exception e){
                e.printStackTrace();
            }
    
            // The server receives the request, completes the processing, and returns the result.
            if(httpResponse != null && httpResponse.isSuccess()){
                JSONObject scrResponse = JSON.parseObject(org.apache.commons.codec.binary.StringUtils.newStringUtf8(httpResponse.getHttpContent()));
                System.out.println(JSON.toJSONString(scrResponse));
                int requestCode = scrResponse.getIntValue("code");
                // The detection result for each image.
                JSONArray taskResults = scrResponse.getJSONArray("data");
                if (200 == requestCode) {
                    for (Object taskResult : taskResults) {
                        // The processing result for a single image.
                        int taskCode = ((JSONObject)taskResult).getIntValue("code");
                        // The processing result of the image for the specified detection scenario. If you specify multiple scenarios, the results for each scenario are returned.
                        JSONArray sceneResults = ((JSONObject)taskResult).getJSONArray("results");
                        if(200 == taskCode){
                            for (Object sceneResult : sceneResults) {
                                String scene = ((JSONObject)sceneResult).getString("scene");
                                String suggestion = ((JSONObject)sceneResult).getString("suggestion");
                                //do something
                                // The recognized ID card information.
                                if("review" .equals(suggestion) && "ocr".equals(scene)){
                                    JSONObject idCardInfo =  ((JSONObject) sceneResult).getJSONObject("idCardInfo");
                                    System.out.println(idCardInfo.toJSONString());
                                }
                            }
                        }else{
                            // The processing of a single image failed. Analyze the cause based on the specific situation.
                            System.out.println("task process fail. task response:" + JSON.toJSONString(taskResult));
                         }
                    }
                } else {
                    /**
                     * This indicates that the entire image scan request failed. Analyze the cause based on the specific situation.
                     */
                    System.out.println("the whole image scan request failed. response:" + JSON.toJSONString(scrResponse));
                 }
            }
        }
    }
  • Detect a local image file

    import com.alibaba.fastjson.JSON;
    import com.alibaba.fastjson.JSONArray;
    import com.alibaba.fastjson.JSONObject;
    import com.aliyuncs.DefaultAcsClient;
    import com.aliyuncs.IAcsClient;
    import com.aliyuncs.exceptions.ClientException;
    import com.aliyuncs.exceptions.ServerException;
    import com.aliyuncs.green.extension.uploader.ClientUploader;
    import com.aliyuncs.green.model.v20180509.ImageSyncScanRequest;
    import com.aliyuncs.http.FormatType;
    import com.aliyuncs.http.HttpResponse;
    import com.aliyuncs.http.MethodType;
    import com.aliyuncs.http.ProtocolType;
    import com.aliyuncs.profile.DefaultProfile;
    import com.aliyuncs.profile.IClientProfile;
    
    import java.util.*;
    
    public class Main {
    
        public static void main(String[] args) throws Exception {
    /**
             * An Alibaba Cloud account AccessKey has full permissions on all APIs. We recommend that you use a RAM user to make API calls or perform O&M. 
             * Common methods to obtain environment variables:
             * Method 1:
             *     Obtain the AccessKey ID of the RAM user: System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID");
             *     Obtain the AccessKey secret of the RAM user: System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET");
             * Method 2:
             *     Obtain the AccessKey ID of the RAM user: System.getProperty("ALIBABA_CLOUD_ACCESS_KEY_ID");
             *     Obtain the AccessKey secret of the RAM user: System.getProperty("ALIBABA_CLOUD_ACCESS_KEY_SECRET");
             */
            DefaultProfile profile = DefaultProfile.getProfile(
                    "cn-shanghai",
                    "Obtain the AccessKey ID of a RAM user from an environment variable",
                    "Obtain the AccessKey secret of a RAM user from an environment variable");
            DefaultProfile.addEndpoint("cn-shanghai", "Green", "green.cn-shanghai.aliyuncs.com");
            IAcsClient client = new DefaultAcsClient(profile);
    
            ImageSyncScanRequest imageSyncScanRequest = new ImageSyncScanRequest();
            // Specify the response format.
            imageSyncScanRequest.setAcceptFormat(FormatType.JSON);
            // Specify the request method.
            imageSyncScanRequest.setMethod(MethodType.POST);
            imageSyncScanRequest.setEncoding("utf-8");
            // HTTP and HTTPS are supported.
            imageSyncScanRequest.setProtocol(ProtocolType.HTTP);
    
            JSONObject httpBody = new JSONObject();
            /**
             * Set the detection scenario.
             * ocr: specifies OCR for images and text, and OCR for cards and IDs.
             */
            httpBody.put("scenes", Arrays.asList("ocr"));
    
            /**
             * Set the images to detect. One image corresponds to one detection task.
             * If you detect multiple images at the same time, the processing time is determined by the last image that is processed.
             * The average response time for batch detection is typically longer than that for a single-task detection. The more images you submit in a batch, the more likely the response time increases.
             * The sample code shows how to detect a single image. To detect multiple images in a batch, create multiple tasks.
             * Detecting a local image requires an additional step to upload the file compared to using an image URL from the internet. After the upload, use the returned URL for detection.
             */
            ClientUploader clientUploader = ClientUploader.getImageClientUploader(profile, false);
            String url = null;
            try{
                url = clientUploader.uploadFile("/Users/test/Pictures/idfront-data-1536747400633.jpg");
            }catch (Exception e){
                System.out.println("upload file to server fail."); 
            }
            JSONObject task = new JSONObject();
            task.put("dataId", UUID.randomUUID().toString());
            task.put("url", url);
            task.put("time", new Date());
            httpBody.put("tasks", Arrays.asList(task));
    
            // When you use OCR for cards and IDs, set the type of card or ID to recognize.
            JSONObject cardExtras = new JSONObject();
            // The front of the ID card.
            cardExtras.put("card", "id-card-front");
            // The back of the ID card.
            //cardExtras.put("card", "id-card-back");
            httpBody.put("extras", cardExtras);
    
            imageSyncScanRequest.setHttpContent(org.apache.commons.codec.binary.StringUtils.getBytesUtf8(httpBody.toJSONString()), "UTF-8", FormatType.JSON);
            /**
             * Set the timeout period. The server-side end-to-end processing timeout is 10 seconds. Set the timeout period accordingly.
             * If the ReadTimeout value you set is less than the server-side processing time, a read timeout exception occurs in the program.
             */
            imageSyncScanRequest.setConnectTimeout(3000);
            imageSyncScanRequest.setReadTimeout(10000);
            HttpResponse httpResponse = null;
            try {
                httpResponse = client.doAction(imageSyncScanRequest);
            } catch (ServerException e) {
                e.printStackTrace();
            } catch (ClientException e) {
                e.printStackTrace();
            } catch (Exception e){
                e.printStackTrace();
            }
    
            // The server receives the request, completes the processing, and returns the result.
            if(httpResponse != null && httpResponse.isSuccess()){
                JSONObject scrResponse = JSON.parseObject(org.apache.commons.codec.binary.StringUtils.newStringUtf8(httpResponse.getHttpContent()));
                System.out.println(JSON.toJSONString(scrResponse));
                int requestCode = scrResponse.getIntValue("code");
                // The detection result for each image.
                JSONArray taskResults = scrResponse.getJSONArray("data");
                if (200 == requestCode) {
                    for (Object taskResult : taskResults) {
                        // The processing result for a single image.
                        int taskCode = ((JSONObject)taskResult).getIntValue("code");
                        // The processing result of the image for the specified detection scenario. If you specify multiple scenarios, the results for each scenario are returned.
                        JSONArray sceneResults = ((JSONObject)taskResult).getJSONArray("results");
                        if(200 == taskCode){
                            for (Object sceneResult : sceneResults) {
                                String scene = ((JSONObject)sceneResult).getString("scene");
                                String suggestion = ((JSONObject)sceneResult).getString("suggestion");
                                //do something
                                // The recognized card or ID information.
                                if("review" .equals(suggestion) && "ocr".equals(scene)){
                                    JSONObject idCardInfo =  ((JSONObject) sceneResult).getJSONObject("idCardInfo");
                                    System.out.println(idCardInfo.toJSONString());
                                }
                            }
                        }else{
                            // The processing of a single image failed. Analyze the cause based on the specific situation.
                            System.out.println("task process fail. task response:" + JSON.toJSONString(taskResult));
                        }
                    }
                } else {
                    /**
                     * This indicates that the entire image scan request failed. Analyze the cause based on the specific situation.
                     */
                    System.out.println("the whole image scan request failed. response:" + JSON.toJSONString(scrResponse));
                }
            }
        }
    }
  • Detect an image using its binary data

    import com.alibaba.fastjson.JSON;
    import com.alibaba.fastjson.JSONArray;
    import com.alibaba.fastjson.JSONObject;
    import com.aliyuncs.DefaultAcsClient;
    import com.aliyuncs.IAcsClient;
    import com.aliyuncs.exceptions.ClientException;
    import com.aliyuncs.exceptions.ServerException;
    import com.aliyuncs.green.extension.uploader.ClientUploader;
    import com.aliyuncs.green.model.v20180509.ImageSyncScanRequest;
    import com.aliyuncs.http.FormatType;
    import com.aliyuncs.http.HttpResponse;
    import com.aliyuncs.http.MethodType;
    import com.aliyuncs.http.ProtocolType;
    import com.aliyuncs.profile.DefaultProfile;
    import com.aliyuncs.profile.IClientProfile;
    import org.apache.commons.io.FileUtils;
    
    import java.io.File;
    import java.util.*;
    
    public class Main {
    
        public static void main(String[] args) throws Exception {
           /**
             * An Alibaba Cloud account AccessKey has full permissions on all APIs. We recommend that you use a RAM user to make API calls or perform O&M. 
             * Common methods to obtain environment variables:
             * Method 1:
             *     Obtain the AccessKey ID of the RAM user: System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID");
             *     Obtain the AccessKey secret of the RAM user: System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET");
             * Method 2:
             *     Obtain the AccessKey ID of the RAM user: System.getProperty("ALIBABA_CLOUD_ACCESS_KEY_ID");
             *     Obtain the AccessKey secret of the RAM user: System.getProperty("ALIBABA_CLOUD_ACCESS_KEY_SECRET");
             */
            DefaultProfile profile = DefaultProfile.getProfile(
                    "cn-shanghai",
                    "Obtain the AccessKey ID of a RAM user from an environment variable",
                    "Obtain the AccessKey secret of a RAM user from an environment variable");
            DefaultProfile.addEndpoint("cn-shanghai", "Green", "green.cn-shanghai.aliyuncs.com");
            IAcsClient client = new DefaultAcsClient(profile);
    
            ImageSyncScanRequest imageSyncScanRequest = new ImageSyncScanRequest();
            // Specify the response format.
            imageSyncScanRequest.setAcceptFormat(FormatType.JSON);
            // Specify the request method.
            imageSyncScanRequest.setMethod(MethodType.POST);
            imageSyncScanRequest.setEncoding("utf-8");
            // HTTP and HTTPS are supported.
            imageSyncScanRequest.setProtocol(ProtocolType.HTTP);
    
            JSONObject httpBody = new JSONObject();
            /**
             * Set the detection scenario.
             * ocr: specifies OCR for images and text, and OCR for cards and IDs.
             */
            httpBody.put("scenes", Arrays.asList("ocr"));
            /**
             * Set the images to detect. One image corresponds to one detection task.
             * If you detect multiple images at the same time, the processing time is determined by the last image that is processed.
             * The average response time for batch detection is typically longer than that for a single-task detection. The more images you submit in a batch, the more likely the response time increases.
             * The sample code shows how to detect a single image. To detect multiple images in a batch, create multiple tasks.
             * Detecting image binary data requires an additional step to upload the data compared to using an image URL from the internet. After the upload, use the returned URL for detection.
             */
            ClientUploader clientUploader = ClientUploader.getImageClientUploader(profile, false);
            byte[] imageBytes = null;
            String url = null;
            try{
                // Read a local file as binary data for an input example. In practice, replace this with your image binary data.
                imageBytes = FileUtils.readFileToByteArray(new File("/Users/01fb4ab6420b5f34623e13b82b51ef87.jpg"));
                // Upload to the server.
                url = clientUploader.uploadBytes(imageBytes);
            }catch (Exception e){
                System.out.println(("upload file to server fail."));
            }
    
            JSONObject task = new JSONObject();
            task.put("dataId", UUID.randomUUID().toString());
            task.put("url", url);
            task.put("time", new Date());
            httpBody.put("tasks", Arrays.asList(task));
    
            // When you use OCR for cards and IDs, set the type of card or ID to recognize.
            JSONObject cardExtras = new JSONObject();
            // The front of the ID card.
            cardExtras.put("card", "id-card-front");
            // The back of the ID card.
            //cardExtras.put("card", "id-card-back");
            httpBody.put("extras", cardExtras);
            imageSyncScanRequest.setHttpContent(org.apache.commons.codec.binary.StringUtils.getBytesUtf8(httpBody.toJSONString()), "UTF-8", FormatType.JSON);
            /**
             * Set the timeout period. The server-side end-to-end processing timeout is 10 seconds. Set the timeout period accordingly.
             * If the ReadTimeout value you set is less than the server-side processing time, a read timeout exception occurs in the program.
             */
            imageSyncScanRequest.setConnectTimeout(3000);
            imageSyncScanRequest.setReadTimeout(10000);
            HttpResponse httpResponse = null;
            try {
                httpResponse = client.doAction(imageSyncScanRequest);
            } catch (ServerException e) {
                e.printStackTrace();
            } catch (ClientException e) {
                e.printStackTrace();
            } catch (Exception e){
                e.printStackTrace();
            }
    
            // The server receives the request, completes the processing, and returns the result.
            if(httpResponse != null && httpResponse.isSuccess()){
                JSONObject scrResponse = JSON.parseObject(org.apache.commons.codec.binary.StringUtils.newStringUtf8(httpResponse.getHttpContent()));
                System.out.println(JSON.toJSONString(scrResponse));
                int requestCode = scrResponse.getIntValue("code");
                // The detection result for each image.
                JSONArray taskResults = scrResponse.getJSONArray("data");
                if (200 == requestCode) {
                    for (Object taskResult : taskResults) {
                        // The processing result for a single image.
                        int taskCode = ((JSONObject)taskResult).getIntValue("code");
                        // The processing result of the image for the specified detection scenario. If you specify multiple scenarios, the results for each scenario are returned.
                        JSONArray sceneResults = ((JSONObject)taskResult).getJSONArray("results");
                        if(200 == taskCode){
                            for (Object sceneResult : sceneResults) {
                                String scene = ((JSONObject)sceneResult).getString("scene");
                                String suggestion = ((JSONObject)sceneResult).getString("suggestion");
                                //do something
                                // The recognized card or ID information.
                                if("review" .equals(suggestion) && "ocr".equals(scene)){
                                    JSONObject idCardInfo =  ((JSONObject) sceneResult).getJSONObject("idCardInfo");
                                    System.out.println(idCardInfo.toJSONString());
                                }
                            }
                        }else{
                            // The processing of a single image failed. Analyze the cause based on the specific situation.
                            System.out.println("task process fail. task response:" + JSON.toJSONString(taskResult));
                        }
                    }
                } else {
                    /**
                     * This indicates that the entire image scan request failed. Analyze the cause based on the specific situation.
                     */
                    System.out.println("the whole image scan request failed. response:" + JSON.toJSONString(scrResponse));
                }
            }
        }
    }

Request parameters

Parameter

Type

Description

scenes

Array

Moderation scenario. Set to ["ocr"] for text recognition.

dataId

String

Unique task identifier. Use UUID.randomUUID().toString() to generate one.

url

String

Publicly accessible URL of the image to moderate.

Response structure

The response is a JSON object with the following top-level fields:

Field

Type

Description

code

Integer

Request status code. 200 indicates success.

data

Array

Array of task results, one per submitted image.

Each element in data contains:

Field

Type

Description

code

Integer

Task status code. 200 indicates the image was processed successfully.

results

Array

Array of scene results.

Each element in results contains:

Field

Type

Description

scene

String

Moderation scenario. Returns ocr for OCR tasks.

suggestion

String

Moderation result. Valid values: pass, review, block.

idCardInfo

Object

Recognized text from the image. Returned when suggestion is review and scene is ocr.

Usage notes

  • One task per image: Create a separate task object for each image. Submitting multiple images in one request extends the total response time — the server processes all images before returning results.

  • Timeouts: Set the read timeout to at least 10,000 ms (10 seconds). The server may take up to 10 seconds to process a single image moderation request.

  • Local images: To submit a local image or a binary image stream, download and import the Extension.Uploader utility class before submitting the request.

  • Credentials: Load your AccessKey ID and AccessKey secret from environment variables (ALIBABA_CLOUD_ACCESS_KEY_ID and ALIBABA_CLOUD_ACCESS_KEY_SECRET) to avoid exposing credentials in your code.

What's next

  • Installation — Set up the Content Moderation SDK for Java.