将计算机视觉功能与 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.

备注

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.

备注

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.

备注

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.

备注

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.

备注

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.

备注

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.