通过 REST API 和 Java 使用计算机视觉功能Use Computer Vision features with the REST API and Java

本教程展示 Azure 认知服务计算机视觉 REST API 的功能。This tutorial shows the features of the Azure Cognitive Services Computer Vision REST API.

介绍一款 Java Swing 应用程序,它使用计算机视觉 REST API 执行光学符号识别 (OCR)、创建智能裁剪的缩略图,还检测、分类、标记和描述图像中的人脸等视觉特征。Explore a Java Swing application that uses the Computer Vision REST API to perform optical character recognition (OCR), create smart-cropped thumbnails, plus detect, categorize, tag, and describe visual features, including faces, in an image. 通过本示例可提交一个图像 URL 进行分析和处理。This example lets you submit an image URL for analysis or processing. 可以使用此开源示例作为模板在 Java 中生成自己的应用,以便使用计算机视觉 REST API。You can use this open source example as a template for building your own app in Java to use the Computer Vision REST API.

本教程介绍如何将计算机视觉用于以下领域:This tutorial will cover how to use Computer Vision to:

  • 分析图像Analyze an image
  • 标识图像中的自然或人工地标Identify a natural or artificial landmark in an image
  • 标识图像中的名人Identify a celebrity in an image
  • 根据图像创建高质量缩略图Create a quality thumbnail from an image
  • 读取图像中的印刷体文本Read printed text in an image
  • 读取图像中的手写文本Read handwritten text in an image

Java Swing 形式的应用程序已编写好,但尚无功能。The Java Swing form application has already been written but has no functionality. 在本教程中,请添加特定于计算机视觉 REST API 的代码,以便完成应用程序的功能。In this tutorial, you add the code specific to the Computer Vision REST API to complete the application's functionality.

先决条件Prerequisites

平台要求Platform requirements

本教程的内容已使用 NetBeans IDE 开发。This tutorial has been developed using the NetBeans IDE. 具体说来,是 Java SE 版本的 NetBeans,可在此处下载Specifically, the Java SE version of NetBeans, which you can download here.

订阅计算机视觉 API 并获取订阅密钥Subscribe to Computer Vision API and get a subscription key

创建示例之前,必须先订阅 Azure 认知服务中随附的计算机视觉 API。Before creating the example, you must subscribe to Computer Vision API which is part of Azure Cognitive Services. 有关订阅和密钥管理的详细信息,请参阅订阅For subscription and key management details, see Subscriptions. 主密钥和辅助密钥均适用于本教程。Both the primary and secondary keys are valid to use in this tutorial.

获取不完整的教程项目Acquire incomplete tutorial project

下载项目Download the project

  1. 转到认知服务 Java 计算机视觉教程存储库。Go to the Cognitive Services Java Computer Vision Tutorial repository.
  2. 单击“克隆或下载” 按钮。Click the Clone or download button.
  3. 单击“下载 ZIP”下载教程项目的 .zip 文件。Click Download ZIP to download a .zip file of the tutorial project.

不需解压缩 .zip 文件的内容,因为 NetBeans 从 .zip 文件导入项目。There is no need to extract the contents of the .zip file because NetBeans imports the project from the .zip file.

导入教程项目Import the tutorial project

将 cognitive-services-java-computer-vision-tutorial-master.zip 文件导入 NetBeans。Import the cognitive-services-java-computer-vision-tutorial-master.zip file into NetBeans.

  1. 在 NetBeans 中单击“文件” > “导入项目” > “从 ZIP...”。此时会显示“从 ZIP 导入项目”对话框。 In NetBeans, click File > Import Project > From ZIP.... The Import Project(s) from ZIP dialog box appears.
  2. 在“ZIP 文件:”字段中单击“浏览”按钮,找到 cognitive-services-java-computer-vision-tutorial-master.zip 文件,然后单击“打开”。 In the ZIP File: field, click the Browse button to locate the cognitive-services-java-computer-vision-tutorial-master.zip file, then click Open.
  3. 在“从 ZIP 导入项目”对话框中单击“导入”。 Click Import from the Import Project(s) from ZIP dialog box.
  4. 在“项目”面板中, 展开“ComputerVision” > “源包” > <>“默认包”In the Projects panel, expand ComputerVision > Source Packages > <default package>. 某些版本的 NetBeans 使用 src 而不是“源包” > <> “默认包”。Some versions of NetBeans use src instead of Source Packages > <default package>. 在这种情况下,请展开 src。In that case, expand src.
  5. 双击“MainFrame.java” 将文件加载到 NetBeans 编辑器中。Double-click MainFrame.java to load the file into the NetBeans editor. 此时会显示 MainFrame.java 文件的“设计”选项卡。The Design tab of the MainFrame.java file appears.
  6. 单击“源” 选项卡查看 Java 源代码。Click the Source tab to view the Java source code.

生成并运行教程项目Build and run the tutorial project

  1. 按 F6 生成并运行教程应用程序。 Press F6 to build and run the tutorial application.

    在教程应用程序中单击相应的选项卡,打开该功能的窗格。In the tutorial application, click a tab to bring up the pane for that feature. 按钮的方法为空,因此不执行任何操作。The buttons have empty methods, so they do nothing.

    窗口底部为字段“订阅密钥”和“订阅区域”。 At the bottom of the window are the fields Subscription Key and Subscription Region. 必须向这些字段填充有效的订阅密钥以及该订阅密钥的正确区域。These fields must be filled with a valid subscription key and the correct region for that subscription key.

  2. 退出教程应用程序。Exit the tutorial application.

向项目添加教程代码Add tutorial code to the project

Java Swing 应用程序设置了六个选项卡。The Java Swing application is set up with six tabs. 每个选项卡展示计算机视觉的不同功能(分析、OCR 等)。Each tab demonstrates a different function of Computer Vision (analyze, OCR, and so on). 六个教程部分没有相互依赖关系,因此可以添加一个部分、六个部分全部添加,或者添加任意子集。The six tutorial sections do not have interdependencies, so you can add one section, all six sections, or any subset. 可以按任意顺序添加部分。You can add the sections in any order.

分析图像Analyze an image

计算机视觉的分析功能可扫描图像中超过 2,000 个可识别的对象、生物、风景和动作。The Analyze feature of Computer Vision scans an image for more than 2,000 recognizable objects, living things, scenery, and actions. 分析完成以后,分析功能会返回一个 JSON 对象,用描述性标记、颜色分析、标题等对图像进行描述。Once the analysis is complete, Analyze returns a JSON object that describes the image with descriptive tags, color analysis, captions, and more.

若要完成教程应用程序的分析功能,请执行以下步骤:To complete the Analyze feature of the tutorial application, perform the following steps:

为分析按钮添加事件处理程序代码Add the event handler code for the analyze button

analyzeImageButtonActionPerformed 事件处理程序方法会清除窗体,显示在 URL 中指定的图像,然后调用 AnalyzeImage 方法进行图像分析。The analyzeImageButtonActionPerformed event handler method clears the form, displays the image specified in the URL, then calls the AnalyzeImage method to analyze the image. 当 AnalyzeImage 返回时,该方法会在“响应”文本区域显示格式化的 JSON 响应, 从 JSONObject 提取第一个标题,然后显示该标题,以及该标题正确的置信水平。When AnalyzeImage returns, the method displays the formatted JSON response in the Response text area, extracts the first caption from the JSONObject, and displays the caption and the confidence level that the caption is correct.

复制以下代码并将其粘贴到 analyzeImageButtonActionPerformed 方法中。Copy and paste the following code into the analyzeImageButtonActionPerformed method.

Note

NetBeans 不允许粘贴到方法定义行 (private void) 或该方法的右大括号。NetBeans won't let you paste to the method definition line (private void) or to the closing curly brace of that method. 若要复制代码,请复制方法定义和右大括号之间的行,然后将其通过粘贴方式覆盖方法的内容。To copy the code, copy the lines between the method definition and the closing curly brace, and paste them over the contents of the method.

    private void analyzeImageButtonActionPerformed(java.awt.event.ActionEvent evt) {
        URL analyzeImageUrl;
        
        // Clear out the previous image, response, and caption, if any.
        analyzeImage.setIcon(new ImageIcon());
        analyzeCaptionLabel.setText("");
        analyzeResponseTextArea.setText("");
        
        // Display the image specified in the text box.
        try {
            analyzeImageUrl = new URL(analyzeImageUriTextBox.getText());
            BufferedImage bImage = ImageIO.read(analyzeImageUrl);
            scaleAndShowImage(bImage, analyzeImage);
        } catch(IOException e) {
            analyzeResponseTextArea.setText("Error loading Analyze image: " + e.getMessage());
            return;
        }
        
        // Analyze the image.
        JSONObject jsonObj = AnalyzeImage(analyzeImageUrl.toString());
        
        // A return of null indicates failure.
        if (jsonObj == null) {
            return;
        }
        
        // Format and display the JSON response.
        analyzeResponseTextArea.setText(jsonObj.toString(2));
                
        // Extract the text and confidence from the first caption in the description object.
        if (jsonObj.has("description") && jsonObj.getJSONObject("description").has("captions")) {

            JSONObject jsonCaption = jsonObj.getJSONObject("description").getJSONArray("captions").getJSONObject(0);
            
            if (jsonCaption.has("text") && jsonCaption.has("confidence")) {
                
                analyzeCaptionLabel.setText("Caption: " + jsonCaption.getString("text") + 
                        " (confidence: " + jsonCaption.getDouble("confidence") + ").");
            }
        }
    }

添加用于 REST API 调用的包装器Add the wrapper for the REST API call

AnalyzeImage 方法包装进行图像分析的 REST API 调用。The AnalyzeImage method wraps the REST API call to analyze an image. 该方法返回 JSONObject 对图像进行描述,或者在出错的情况下返回 null。The method returns a JSONObject describing the image, or null if there was an error.

复制 AnalyzeImage 方法并将其粘贴到 analyzeImageButtonActionPerformed 方法下方。Copy and paste the AnalyzeImage method to just underneath the analyzeImageButtonActionPerformed method.

    /**
     * Encapsulates the Microsoft Cognitive Services REST API call to analyze an image.
     * @param imageUrl: The string URL of the image to analyze.
     * @return: A JSONObject describing the image, or null if a runtime error occurs.
     */
    private JSONObject AnalyzeImage(String imageUrl) {
        try (CloseableHttpClient httpclient = HttpClientBuilder.create().build())
        {
            // Create the URI to access the REST API call for Analyze Image.
            String uriString = uriBasePreRegion + 
                    String.valueOf(subscriptionRegionComboBox.getSelectedItem()) + 
                    uriBasePostRegion + uriBaseAnalyze;
            URIBuilder builder = new URIBuilder(uriString);

            // Request parameters. All of them are optional.
            builder.setParameter("visualFeatures", "Categories,Description,Color,Adult");
            builder.setParameter("language", "en");

            // Prepare the URI for the REST API call.
            URI uri = builder.build();
            HttpPost request = new HttpPost(uri);

            // Request headers.
            request.setHeader("Content-Type", "application/json");
            request.setHeader("Ocp-Apim-Subscription-Key", subscriptionKeyTextField.getText());

            // Request body.
            StringEntity reqEntity = new StringEntity("{\"url\":\"" + imageUrl + "\"}");
            request.setEntity(reqEntity);

            // Execute the REST API call and get the response entity.
            HttpResponse response = httpclient.execute(request);
            HttpEntity entity = response.getEntity();

            // If we got a response, parse it and display it.
            if (entity != null)
            {
                // Return the JSONObject.
                String jsonString = EntityUtils.toString(entity);
                return new JSONObject(jsonString);
            } else {
                // No response. Return null.
                return null;
            }
        }
        catch (Exception e)
        {
            // Display error message.
            System.out.println(e.getMessage());
            return null;
        }
    }

运行 Analyze 函数Run the Analyze function

按 F6 运行应用程序。Press F6 to run the application. 在“订阅密钥”字段中填写订阅密钥,并验证确保“订阅区域中”使用的区域正确无误 。Put your subscription key into the Subscription Key field and verify that you are using the correct region in Subscription Region. 输入图像 URL 进行分析,然后单击“分析图像”按钮以分析图像并查看结果 。Enter a URL to an image to analyze, then click the Analyze Image button to analyze an image and see the result.

识别地标Recognize a landmark

计算机视觉的地标功能可以分析图像中是否存在自然的和人工的地标,例如山脉或著名建筑。The Landmark feature of Computer Vision analyzes an image for natural and artificial landmarks, such as mountains or famous buildings. 分析完以后,地标功能会返回一个 JSON 对象,其中标识了图像中发现的地标。Once the analysis is complete, Landmark returns a JSON object that identifies the landmarks found in the image.

若要完成教程应用程序的地标功能,请执行以下步骤:To complete the Landmark feature of the tutorial application, perform the following steps:

为表单按钮添加事件处理程序代码Add the event handler code for the form button

landmarkImageButtonActionPerformed 事件处理程序方法会清除窗体,显示在 URL 中指定的图像,然后调用 LandmarkImage 方法进行图像分析。The landmarkImageButtonActionPerformed event handler method clears the form, displays the image specified in the URL, then calls the LandmarkImage method to analyze the image. 当 LandmarkImage 返回时,该方法会在“响应”文本区域显示格式化的 JSON 响应, 然后从 JSONObject 提取第一个地标名称,并将其连同指示地标已正确标识的置信水平显示在窗口中。When LandmarkImage returns, the method displays the formatted JSON response in the Response text area, then extracts the first landmark name from the JSONObject and displays it on the window along with the confidence level that the landmark was identified correctly.

复制以下代码并将其粘贴到 landmarkImageButtonActionPerformed 方法中。Copy and paste the following code into the landmarkImageButtonActionPerformed method.

Note

NetBeans 不允许粘贴到方法定义行 (private void) 或该方法的右大括号。NetBeans won't let you paste to the method definition line (private void) or to the closing curly brace of that method. 若要复制代码,请复制方法定义和右大括号之间的行,然后将其通过粘贴方式覆盖方法的内容。To copy the code, copy the lines between the method definition and the closing curly brace, and paste them over the contents of the method.

    private void landmarkImageButtonActionPerformed(java.awt.event.ActionEvent evt) {
        URL landmarkImageUrl;
        
        // Clear out the previous image, response, and caption, if any.
        landmarkImage.setIcon(new ImageIcon());
        landmarkCaptionLabel.setText("");
        landmarkResponseTextArea.setText("");
        
        // Display the image specified in the text box.
        try {
            landmarkImageUrl = new URL(landmarkImageUriTextBox.getText());
            BufferedImage bImage = ImageIO.read(landmarkImageUrl);
            scaleAndShowImage(bImage, landmarkImage);
        } catch(IOException e) {
            landmarkResponseTextArea.setText("Error loading Landmark image: " + e.getMessage());
            return;
        }
        
        // Identify the landmark in the image.
        JSONObject jsonObj = LandmarkImage(landmarkImageUrl.toString());
        
        // A return of null indicates failure.
        if (jsonObj == null) {
            return;
        }
        
        // Format and display the JSON response.
        landmarkResponseTextArea.setText(jsonObj.toString(2));
                
        // Extract the text and confidence from the first caption in the description object.
        if (jsonObj.has("result") && jsonObj.getJSONObject("result").has("landmarks")) {

            JSONObject jsonCaption = jsonObj.getJSONObject("result").getJSONArray("landmarks").getJSONObject(0);
            
            if (jsonCaption.has("name") && jsonCaption.has("confidence")) {

                landmarkCaptionLabel.setText("Caption: " + jsonCaption.getString("name") + 
                        " (confidence: " + jsonCaption.getDouble("confidence") + ").");
            }
        }
    }

添加用于 REST API 调用的包装器Add the wrapper for the REST API call

LandmarkImage 方法包装进行图像分析的 REST API 调用。The LandmarkImage method wraps the REST API call to analyze an image. 该方法返回 JSONObject 对图像中找到的地标进行描述,或者在出错的情况下返回 null。The method returns a JSONObject describing the landmarks found in the image, or null if there was an error.

复制 LandmarkImage 方法并将其粘贴到 landmarkImageButtonActionPerformed 方法下方。Copy and paste the LandmarkImage method to just underneath the landmarkImageButtonActionPerformed method.

     /**
     * Encapsulates the Microsoft Cognitive Services REST API call to identify a landmark in an image.
     * @param imageUrl: The string URL of the image to process.
     * @return: A JSONObject describing the image, or null if a runtime error occurs.
     */
    private JSONObject LandmarkImage(String imageUrl) {
        try (CloseableHttpClient httpclient = HttpClientBuilder.create().build())
        {
            // Create the URI to access the REST API call to identify a Landmark in an image.
            String uriString = uriBasePreRegion + 
                    String.valueOf(subscriptionRegionComboBox.getSelectedItem()) + 
                    uriBasePostRegion + uriBaseLandmark;
            URIBuilder builder = new URIBuilder(uriString);

            // Request parameters. All of them are optional.
            builder.setParameter("visualFeatures", "Categories,Description,Color");
            builder.setParameter("language", "en");

            // Prepare the URI for the REST API call.
            URI uri = builder.build();
            HttpPost request = new HttpPost(uri);

            // Request headers.
            request.setHeader("Content-Type", "application/json");
            request.setHeader("Ocp-Apim-Subscription-Key", subscriptionKeyTextField.getText());

            // Request body.
            StringEntity reqEntity = new StringEntity("{\"url\":\"" + imageUrl + "\"}");
            request.setEntity(reqEntity);

            // Execute the REST API call and get the response entity.
            HttpResponse response = httpclient.execute(request);
            HttpEntity entity = response.getEntity();

            // If we got a response, parse it and display it.
            if (entity != null)
            {
                // Return the JSONObject.
                String jsonString = EntityUtils.toString(entity);
                return new JSONObject(jsonString);
            } else {
                // No response. Return null.
                return null;
            }
        }
        catch (Exception e)
        {
            // Display error message.
            System.out.println(e.getMessage());
            return null;
        }
    }

运行 landmark 函数Run the landmark function

按 F6 运行应用程序。Press F6 to run the application. 在“订阅密钥”字段中填写订阅密钥,并验证确保“订阅区域中”使用的区域正确无误 。Put your subscription key into the Subscription Key field and verify that you are using the correct region in Subscription Region. 单击“地标”选项卡,输入地标图像的 URL,然后单击“分析图像”按钮对图像进行分析并查看结果。 Click the Landmark tab, enter a URL to an image of a landmark, then click the Analyze Image button to analyze an image and see the result.

识别名人Recognize celebrities

计算机视觉的名人功能分析图像中是否存在名人。The Celebrities feature of Computer Vision analyzes an image for famous people. 分析完以后,名人功能会返回一个 JSON 对象,其中标识了图像中发现的名人。Once the analysis is complete, Celebrities returns a JSON object that identifies the Celebrities found in the image.

若要完成教程应用程序的名人功能,请执行以下步骤:To complete the Celebrities feature of the tutorial application, perform the following steps:

为名人按钮添加事件处理程序代码Add the event handler code for the celebrities button

celebritiesImageButtonActionPerformed 事件处理程序方法会清除窗体,显示在 URL 中指定的图像,然后调用 CelebritiesImage 方法进行图像分析。The celebritiesImageButtonActionPerformed event handler method clears the form, displays the image specified in the URL, then calls the CelebritiesImage method to analyze the image. 当 CelebritiesImage 返回时,该方法会在“响应”文本区域显示格式化的 JSON 响应, 然后从 JSONObject 提取第一个名人名称,并将该名称连同指示名人已正确标识的置信水平显示在窗口中。When CelebritiesImage returns, the method displays the formatted JSON response in the Response text area, then extracts the first celebrity name from the JSONObject and displays the name on the window along with the confidence level that the celebrity was identified correctly.

复制以下代码并将其粘贴到 celebritiesImageButtonActionPerformed 方法中。Copy and paste the following code into the celebritiesImageButtonActionPerformed method.

Note

NetBeans 不允许粘贴到方法定义行 (private void) 或该方法的右大括号。NetBeans won't let you paste to the method definition line (private void) or to the closing curly brace of that method. 若要复制代码,请复制方法定义和右大括号之间的行,然后将其通过粘贴方式覆盖方法的内容。To copy the code, copy the lines between the method definition and the closing curly brace, and paste them over the contents of the method.

    private void celebritiesImageButtonActionPerformed(java.awt.event.ActionEvent evt) {
        URL celebritiesImageUrl;
        
        // Clear out the previous image, response, and caption, if any.
        celebritiesImage.setIcon(new ImageIcon());
        celebritiesCaptionLabel.setText("");
        celebritiesResponseTextArea.setText("");
        
        // Display the image specified in the text box.
        try {
            celebritiesImageUrl = new URL(celebritiesImageUriTextBox.getText());
            BufferedImage bImage = ImageIO.read(celebritiesImageUrl);
            scaleAndShowImage(bImage, celebritiesImage);
        } catch(IOException e) {
            celebritiesResponseTextArea.setText("Error loading Celebrity image: " + e.getMessage());
            return;
        }
        
        // Identify the celebrities in the image.
        JSONObject jsonObj = CelebritiesImage(celebritiesImageUrl.toString());
        
        // A return of null indicates failure.
        if (jsonObj == null) {
            return;
        }
        
        // Format and display the JSON response.
        celebritiesResponseTextArea.setText(jsonObj.toString(2));
                
        // Extract the text and confidence from the first caption in the description object.
        if (jsonObj.has("result") && jsonObj.getJSONObject("result").has("celebrities")) {

            JSONObject jsonCaption = jsonObj.getJSONObject("result").getJSONArray("celebrities").getJSONObject(0);
            
            if (jsonCaption.has("name") && jsonCaption.has("confidence")) {

                celebritiesCaptionLabel.setText("Caption: " + jsonCaption.getString("name") + 
                        " (confidence: " + jsonCaption.getDouble("confidence") + ").");
            }
        }
    }

添加用于 REST API 调用的包装器Add the wrapper for the REST API call

CelebritiesImage 方法包装进行图像分析的 REST API 调用。The CelebritiesImage method wraps the REST API call to analyze an image. 该方法返回 JSONObject 对图像中找到的名人进行描述,或者在出错的情况下返回 null。The method returns a JSONObject describing the celebrities found in the image, or null if there was an error.

复制 CelebritiesImage 方法并将其粘贴到 celebritiesImageButtonActionPerformed 方法下方。Copy and paste the CelebritiesImage method to just underneath the celebritiesImageButtonActionPerformed method.

     /**
     * Encapsulates the Microsoft Cognitive Services REST API call to identify celebrities in an image.
     * @param imageUrl: The string URL of the image to process.
     * @return: A JSONObject describing the image, or null if a runtime error occurs.
     */
    private JSONObject CelebritiesImage(String imageUrl) {
        try (CloseableHttpClient httpclient = HttpClientBuilder.create().build())
        {
            // Create the URI to access the REST API call to identify celebrities in an image.
            String uriString = uriBasePreRegion + 
                    String.valueOf(subscriptionRegionComboBox.getSelectedItem()) + 
                    uriBasePostRegion + uriBaseCelebrities;
            URIBuilder builder = new URIBuilder(uriString);

            // Request parameters. All of them are optional.
            builder.setParameter("visualFeatures", "Categories,Description,Color");
            builder.setParameter("language", "en");

            // Prepare the URI for the REST API call.
            URI uri = builder.build();
            HttpPost request = new HttpPost(uri);

            // Request headers.
            request.setHeader("Content-Type", "application/json");
            request.setHeader("Ocp-Apim-Subscription-Key", subscriptionKeyTextField.getText());

            // Request body.
            StringEntity reqEntity = new StringEntity("{\"url\":\"" + imageUrl + "\"}");
            request.setEntity(reqEntity);

            // Execute the REST API call and get the response entity.
            HttpResponse response = httpclient.execute(request);
            HttpEntity entity = response.getEntity();

            // If we got a response, parse it and display it.
            if (entity != null)
            {
                // Return the JSONObject.
                String jsonString = EntityUtils.toString(entity);
                return new JSONObject(jsonString);
            } else {
                // No response. Return null.
                return null;
            }
        }
        catch (Exception e)
        {
            // Display error message.
            System.out.println(e.getMessage());
            return null;
        }
    }

运行 celebrities 函数Run the celebrities function

按 F6 运行应用程序。Press F6 to run the application. 在“订阅密钥”字段中填写订阅密钥,并验证确保“订阅区域中”使用的区域正确无误 。Put your subscription key into the Subscription Key field and verify that you are using the correct region in Subscription Region. 单击“名人”选项卡,输入名人图像的 URL,然后单击“分析图像”按钮对图像进行分析并查看结果。 Click the Celebrities tab, enter a URL to an image of a celebrity, then click the Analyze Image button to analyze an image and see the result.

以智能方式生成缩略图Intelligently generate a thumbnail

计算机视觉的缩略图功能根据图像生成缩略图。The Thumbnail feature of Computer Vision generates a thumbnail from an image. 缩略图功能可以使用智能裁剪功能 来标识图像中的感兴趣区域,使缩略图聚焦在该区域,目的是生成更美的缩略图。By using the Smart Crop feature, the Thumbnail feature will identify the area of interest in an image and center the thumbnail on this area, to generate more aesthetically pleasing thumbnail images.

若要完成教程应用程序的缩略图功能,请执行以下步骤:To complete the Thumbnail feature of the tutorial application, perform the following steps:

为缩略图按钮添加事件处理程序代码Add the event handler code for the thumbnail button

thumbnailImageButtonActionPerformed 事件处理程序方法会清除窗体,显示在 URL 中指定的图像,然后调用 getThumbnailImage 方法创建缩略图。The thumbnailImageButtonActionPerformed event handler method clears the form, displays the image specified in the URL, then calls the getThumbnailImage method to create the thumbnail. 当 getThumbnailImage 返回时,该方法显示生成的缩略图。When getThumbnailImage returns, the method displays the generated thumbnail.

复制以下代码并将其粘贴到 thumbnailImageButtonActionPerformed 方法中。Copy and paste the following code into the thumbnailImageButtonActionPerformed method.

Note

NetBeans 不允许将内容粘贴到方法定义行 (private void) 或该方法的右大括号处。NetBeans won't let you paste to the method definition line (private void) or to the closing curly brace of that method. 若要复制代码,请复制方法定义和右大括号之间的行,然后将其通过粘贴方式覆盖方法的内容。To copy the code, copy the lines between the method definition and the closing curly brace, and paste them over the contents of the method.

    private void thumbnailImageButtonActionPerformed(java.awt.event.ActionEvent evt) {
        URL thumbnailImageUrl;
        JSONObject jsonError[] = new JSONObject[1];
        
        // Clear out the previous image, response, and thumbnail, if any.
        thumbnailSourceImage.setIcon(new ImageIcon());
        thumbnailResponseTextArea.setText("");
        thumbnailImage.setIcon(new ImageIcon());

        // Display the image specified in the text box.
        try {
            thumbnailImageUrl = new URL(thumbnailImageUriTextBox.getText());
            BufferedImage bImage = ImageIO.read(thumbnailImageUrl);
            scaleAndShowImage(bImage, thumbnailSourceImage);
        } catch(IOException e) {
            thumbnailResponseTextArea.setText("Error loading image to thumbnail: " + e.getMessage());
            return;
        }
        
        // Get the thumbnail for the image.
        BufferedImage thumbnail = getThumbnailImage(thumbnailImageUrl.toString(), jsonError);
        
        // A non-null value indicates error.
        if (jsonError[0] != null) {
            // Format and display the JSON error.
            thumbnailResponseTextArea.setText(jsonError[0].toString(2));
            return;
        }
        
        // Display the thumbnail.
        if (thumbnail != null) {
            scaleAndShowImage(thumbnail, thumbnailImage);
        }
    }

添加用于 REST API 调用的包装器Add the wrapper for the REST API call

getThumbnailImage 方法包装进行图像分析的 REST API 调用。The getThumbnailImage method wraps the REST API call to analyze an image. 该方法返回 BufferedImage,其中包含缩略图,或者在出错的情况下返回 null。 The method returns a BufferedImage that contains the thumbnail, or null if there was an error. 错误消息会返回到 jsonError 字符串数组的第一个元素中。The error message will be returned in the first element of the jsonError string array.

复制以下 getThumbnailImage 方法并将其粘贴到 thumbnailImageButtonActionPerformed 方法下方。Copy and paste the following getThumbnailImage method to just underneath the thumbnailImageButtonActionPerformed method.

     /**
     * Encapsulates the Microsoft Cognitive Services REST API call to create a thumbnail for an image.
     * @param imageUrl: The string URL of the image to process.
     * @return: A BufferedImage containing the thumbnail, or null if a runtime error occurs. In the case
     * of an error, the error message will be returned in the first element of the jsonError string array.
     */
    private BufferedImage getThumbnailImage(String imageUrl, JSONObject[] jsonError) {
        try (CloseableHttpClient httpclient = HttpClientBuilder.create().build())
        {
            // Create the URI to access the REST API call to identify celebrities in an image.
            String uriString = uriBasePreRegion + 
                    String.valueOf(subscriptionRegionComboBox.getSelectedItem()) + 
                    uriBasePostRegion + uriBaseThumbnail;
            URIBuilder uriBuilder = new URIBuilder(uriString);

            // Request parameters.
            uriBuilder.setParameter("width", "100");
            uriBuilder.setParameter("height", "150");
            uriBuilder.setParameter("smartCropping", "true");

            // Prepare the URI for the REST API call.
            URI uri = uriBuilder.build();
            HttpPost request = new HttpPost(uri);

            // Request headers.
            request.setHeader("Content-Type", "application/json");
            request.setHeader("Ocp-Apim-Subscription-Key", subscriptionKeyTextField.getText());

            // Request body.
            StringEntity requestEntity = new StringEntity("{\"url\":\"" + imageUrl + "\"}");
            request.setEntity(requestEntity);

            // Execute the REST API call and get the response entity.
            HttpResponse response = httpclient.execute(request);
            HttpEntity entity = response.getEntity();

            // Check for success.
            if (response.getStatusLine().getStatusCode() == 200)
            {
                // Return the thumbnail.
                return ImageIO.read(entity.getContent());
            }
            else
            {
                // Format and display the JSON error message.
                String jsonString = EntityUtils.toString(entity);
                jsonError[0] = new JSONObject(jsonString);
                return null;
            }
        }
        catch (Exception e)
        {
            String errorMessage = e.getMessage();
            System.out.println(errorMessage);
            jsonError[0] = new JSONObject(errorMessage);
            return null;
        }
    }

运行 thumbnail 函数Run the thumbnail function

按 F6 运行应用程序。Press F6 to run the application. 在“订阅密钥”字段中填写订阅密钥,并验证确保“订阅区域中”使用的区域正确无误 。Put your subscription key into the Subscription Key field and verify that you are using the correct region in Subscription Region. 单击“缩略图”选项卡,输入图像的 URL,然后单击“生成缩略图”按钮对图像进行分析并查看结果。 Click the Thumbnail tab, enter a URL to an image, then click the Generate Thumbnail button to analyze an image and see the result.

读取印刷体文本 (OCR)Read printed text (OCR)

计算机视觉的光学字符识别 (OCR) 功能分析图像中是否有印刷体文本。The Optical Character Recognition (OCR) feature of Computer Vision analyzes an image of printed text. 分析完以后,OCR 会返回一个 JSON 对象,其中包含图像中的文本和文本位置。After the analysis is complete, OCR returns a JSON object that contains the text and the location of the text in the image.

若要完成教程应用程序的 OCR 功能,请执行以下步骤:To complete the OCR feature of the tutorial application, perform the following steps:

为 OCR 按钮添加事件处理程序代码Add the event handler code for the OCR button

ocrImageButtonActionPerformed 事件处理程序方法会清除窗体,显示在 URL 中指定的图像,然后调用 OcrImage 方法进行图像分析。The ocrImageButtonActionPerformed event handler method clears the form, displays the image specified in the URL, then calls the OcrImage method to analyze the image. 当 OcrImage 返回时,该方法会在“响应”文本区域以格式化 JSON 的方式显示检测到的文本。 When OcrImage returns, the method displays the detected text as formatted JSON in the Response text area.

复制以下代码并将其粘贴到 ocrImageButtonActionPerformed 方法中。Copy and paste the following code into the ocrImageButtonActionPerformed method.

Note

NetBeans 不允许粘贴到方法定义行 (private void) 或该方法的右大括号。NetBeans won't let you paste to the method definition line (private void) or to the closing curly brace of that method. 若要复制代码,请复制方法定义和右大括号之间的行,然后将其通过粘贴方式覆盖方法的内容。To copy the code, copy the lines between the method definition and the closing curly brace, and paste them over the contents of the method.

    private void ocrImageButtonActionPerformed(java.awt.event.ActionEvent evt) {
        URL ocrImageUrl;
        
        // Clear out the previous image, response, and caption, if any.
        ocrImage.setIcon(new ImageIcon());
        ocrResponseTextArea.setText("");
        
        // Display the image specified in the text box.
        try {
            ocrImageUrl = new URL(ocrImageUriTextBox.getText());
            BufferedImage bImage = ImageIO.read(ocrImageUrl);
            scaleAndShowImage(bImage, ocrImage);
        } catch(IOException e) {
            ocrResponseTextArea.setText("Error loading OCR image: " + e.getMessage());
            return;
        }
        
        // Read the text in the image.
        JSONObject jsonObj = OcrImage(ocrImageUrl.toString());
        
        // A return of null indicates failure.
        if (jsonObj == null) {
            return;
        }
        
        // Format and display the JSON response.
        ocrResponseTextArea.setText(jsonObj.toString(2));
    }

添加用于 REST API 调用的包装器Add the wrapper for the REST API call

OcrImage 方法包装进行图像分析的 REST API 调用。The OcrImage method wraps the REST API call to analyze an image. 该方法返回从调用返回的 JSON 数据的 JSONObject,或者在出现错误的情况下返回 null。 The method returns a JSONObject of the JSON data returned from the call, or null if there was an error.

复制以下 OcrImage 方法并将其粘贴到 ocrImageButtonActionPerformed 方法下方。Copy and paste the following OcrImage method to just underneath the ocrImageButtonActionPerformed method.

     /**
     * Encapsulates the Microsoft Cognitive Services REST API call to read text in an image.
     * @param imageUrl: The string URL of the image to process.
     * @return: A JSONObject describing the image, or null if a runtime error occurs.
     */
    private JSONObject OcrImage(String imageUrl) {
        try (CloseableHttpClient httpclient = HttpClientBuilder.create().build())
        {
            // Create the URI to access the REST API call to read text in an image.
            String uriString = uriBasePreRegion + 
                    String.valueOf(subscriptionRegionComboBox.getSelectedItem()) + 
                    uriBasePostRegion + uriBaseOcr;
            URIBuilder uriBuilder = new URIBuilder(uriString);

            // Request parameters.
            uriBuilder.setParameter("language", "unk");
            uriBuilder.setParameter("detectOrientation ", "true");

            // Prepare the URI for the REST API call.
            URI uri = uriBuilder.build();
            HttpPost request = new HttpPost(uri);

            // Request headers.
            request.setHeader("Content-Type", "application/json");
            request.setHeader("Ocp-Apim-Subscription-Key", subscriptionKeyTextField.getText());

            // Request body.
            StringEntity reqEntity = new StringEntity("{\"url\":\"" + imageUrl + "\"}");
            request.setEntity(reqEntity);

            // Execute the REST API call and get the response entity.
            HttpResponse response = httpclient.execute(request);
            HttpEntity entity = response.getEntity();

            // If we got a response, parse it and display it.
            if (entity != null)
            {
                // Return the JSONObject.
                String jsonString = EntityUtils.toString(entity);
                return new JSONObject(jsonString);
            } else {
                // No response. Return null.
                return null;
            }
        }
        catch (Exception e)
        {
            // Display error message.
            System.out.println(e.getMessage());
            return null;
        }
    }

运行 OCR 函数Run the OCR function

按 F6 运行应用程序。Press F6 to run the application. 在“订阅密钥”字段中填写订阅密钥,并验证确保“订阅区域中”使用的区域正确无误 。Put your subscription key into the Subscription Key field and verify that you are using the correct region in Subscription Region. 单击“OCR”选项卡,输入印刷体文本图像的 URL,然后单击“读取图像”按钮对图像进行分析并查看结果。 Click the OCR tab, enter a URL to an image of printed text, then click the Read Image button to analyze an image and see the result.

读取手写文本(手写识别)Read handwritten text (handwriting recognition)

计算机视觉的手写体识别功能可分析图像中的手写文本。The Handwriting Recognition feature of Computer Vision analyzes an image of handwritten text. 分析完以后,手写识别功能会返回一个 JSON 对象,其中包含图像中的文本和文本位置。After the analysis is complete, Handwriting Recognition returns a JSON object that contains the text and the location of the text in the image.

若要完成教程应用程序的手写识别功能,请执行以下步骤:To complete the Handwriting Recognition feature of the tutorial application, perform the following steps:

为手写按钮添加事件处理程序代码Add the event handler code for the handwriting button

handwritingImageButtonActionPerformed 事件处理程序方法会清除窗体,显示在 URL 中指定的图像,然后调用 HandwritingImage 方法进行图像分析。The handwritingImageButtonActionPerformed event handler method clears the form, displays the image specified in the URL, then calls the HandwritingImage method to analyze the image. 当 HandwritingImage 返回时,该方法会在“响应”文本区域以格式化 JSON 的方式显示检测到的文本。 When HandwritingImage returns, the method displays the detected text as formatted JSON in the Response text area.

复制以下代码并将其粘贴到 handwritingImageButtonActionPerformed 方法中。Copy and paste the following code into the handwritingImageButtonActionPerformed method.

Note

NetBeans 不允许粘贴到方法定义行 (private void) 或该方法的右大括号。NetBeans won't let you paste to the method definition line (private void) or to the closing curly brace of that method. 若要复制代码,请复制方法定义和右大括号之间的行,然后将其通过粘贴方式覆盖方法的内容。To copy the code, copy the lines between the method definition and the closing curly brace, and paste them over the contents of the method.

    private void handwritingImageButtonActionPerformed(java.awt.event.ActionEvent evt) {
        URL handwritingImageUrl;
        
        // Clear out the previous image, response, and caption, if any.
        handwritingImage.setIcon(new ImageIcon());
        handwritingResponseTextArea.setText("");
        
        // Display the image specified in the text box.
        try {
            handwritingImageUrl = new URL(handwritingImageUriTextBox.getText());
            BufferedImage bImage = ImageIO.read(handwritingImageUrl);
            scaleAndShowImage(bImage, handwritingImage);
        } catch(IOException e) {
            handwritingResponseTextArea.setText("Error loading Handwriting image: " + e.getMessage());
            return;
        }
        
        // Read the text in the image.
        JSONObject jsonObj = HandwritingImage(handwritingImageUrl.toString());
        
        // A return of null indicates failure.
        if (jsonObj == null) {
            return;
        }
        
        // Format and display the JSON response.
        handwritingResponseTextArea.setText(jsonObj.toString(2));
    }

添加用于 REST API 调用的包装器Add the wrapper for the REST API call

HandwritingImage 方法包装两个进行图像分析所需的 REST API 调用。The HandwritingImage method wraps the two REST API calls needed to analyze an image. 由于手写识别很耗时,因此使用一个两步过程。Because handwriting recognition is a time consuming process, a two step process is used. 第一个调用提交需处理的图像;第二个调用检索处理完成时检测到的文本。The first call submits the image for processing; the second call retrieves the detected text when the processing is complete.

检索文本后, HandwritingImage 方法返回 JSONObject 对文本和文本位置进行说明,或者在出错的情况下返回 null。 After the text is retrieved, the HandwritingImage method returns a JSONObject describing the text and the locations of the text, or null if there was an error.

复制以下 HandwritingImage 方法并将其粘贴到 handwritingImageButtonActionPerformed 方法下方。Copy and paste the following HandwritingImage method to just underneath the handwritingImageButtonActionPerformed method.

     /**
     * Encapsulates the Microsoft Cognitive Services REST API call to read handwritten text in an image.
     * @param imageUrl: The string URL of the image to process.
     * @return: A JSONObject describing the image, or null if a runtime error occurs.
     */
    private JSONObject HandwritingImage(String imageUrl) {
        try (CloseableHttpClient textClient = HttpClientBuilder.create().build();
             CloseableHttpClient resultClient = HttpClientBuilder.create().build())
        {
            // Create the URI to access the REST API call to read text in an image.
            String uriString = uriBasePreRegion + 
                    String.valueOf(subscriptionRegionComboBox.getSelectedItem()) + 
                    uriBasePostRegion + uriBaseHandwriting;
            URIBuilder uriBuilder = new URIBuilder(uriString);
            
            // Request parameters.
            uriBuilder.setParameter("handwriting", "true");

            // Prepare the URI for the REST API call.
            URI uri = uriBuilder.build();
            HttpPost request = new HttpPost(uri);

            // Request headers.
            request.setHeader("Content-Type", "application/json");
            request.setHeader("Ocp-Apim-Subscription-Key", subscriptionKeyTextField.getText());

            // Request body.
            StringEntity reqEntity = new StringEntity("{\"url\":\"" + imageUrl + "\"}");
            request.setEntity(reqEntity);

            // Execute the REST API call and get the response.
            HttpResponse textResponse = textClient.execute(request);
            
            // Check for success.
            if (textResponse.getStatusLine().getStatusCode() != 202) {
                // An error occurred. Return the JSON error message.
                HttpEntity entity = textResponse.getEntity();
                String jsonString = EntityUtils.toString(entity);
                return new JSONObject(jsonString);
            }
            
            String operationLocation = null;

            // The 'Operation-Location' in the response contains the URI to retrieve the recognized text.
            Header[] responseHeaders = textResponse.getAllHeaders();
            for(Header header : responseHeaders) {
                if(header.getName().equals("Operation-Location"))
                {
                    // This string is the URI where you can get the text recognition operation result.
                    operationLocation = header.getValue();
                    break;
                }
            }
            
            // NOTE: The response may not be immediately available. Handwriting recognition is an
            // async operation that can take a variable amount of time depending on the length
            // of the text you want to recognize. You may need to wait or retry this operation.
            //
            // This example checks once per second for ten seconds.
            
            JSONObject responseObj = null;
            int i = 0;
            do {
                // Wait one second.
                Thread.sleep(1000);
                
                // Check to see if the operation completed.
                HttpGet resultRequest = new HttpGet(operationLocation);
                resultRequest.setHeader("Ocp-Apim-Subscription-Key", subscriptionKeyTextField.getText());
                HttpResponse resultResponse = resultClient.execute(resultRequest);
                HttpEntity responseEntity = resultResponse.getEntity();
                if (responseEntity != null)
                {
                    // Get the JSON response.
                    String jsonString = EntityUtils.toString(responseEntity);
                    responseObj = new JSONObject(jsonString);
                }
            }
            while (i < 10 && responseObj != null &&
                    !responseObj.getString("status").equalsIgnoreCase("Succeeded"));
            
            // If the operation completed, return the JSON object.
            if (responseObj != null) {
                return responseObj;
            } else {
                // Return null for timeout error.
                System.out.println("Timeout error.");
                return null;
            }
        }
        catch (Exception e)
        {
            // Display error message.
            System.out.println(e.getMessage());
            return null;
        }
    }

运行 handwriting 函数Run the handwriting function

若要运行应用程序,请按 F6。To run the application, press F6. 在“订阅密钥”字段中填写订阅密钥,并验证确保“订阅区域中”使用的区域正确无误 。Put your subscription key into the Subscription Key field and verify that you are using the correct region in Subscription Region. 单击“读取手写文本”选项卡,输入手写文本图像的 URL,然后单击“读取图像”按钮以分析图像并查看结果 。Click the Read Handwritten Text tab, enter a URL to an image of handwritten text, then click the Read Image button to analyze an image and see the result.

后续步骤Next steps

在本指南中,已使用计算机视觉 REST API 和 Java 来测试了许多可用的图像分析功能。In this guide, you used the Computer Vision REST API with Java to test many of the available image analysis features. 接下来,请参阅参考文档以了解有关所涉及 API 的更多信息。Next, see the reference documentation to learn more about the APIs involved.