代码之家  ›  专栏  ›  技术社区  ›  pumo

如何使用JAVA将本地图像而不是URL发送到Microsoft Computer Vision API

  •  2
  • pumo  · 技术社区  · 7 年前

    问题是如何加载图像文件并将其作为对象传递给Microsoft Computer Vision API,Microsoft网站中的所有示例代码都是从url读取图像。

    // This sample uses the Apache HTTP client library(org.apache.httpcomponents:httpclient:4.2.4)
    // and the org.json library (org.json:json:20170516).
    package com.mparnisari.test;
    
    import java.awt.image.BufferedImage;
    import java.io.File;
    import java.net.URI;
    import java.nio.file.Files;
    import java.nio.file.Path;
    import java.nio.file.Paths;
    
    import javax.imageio.ImageIO;
    
    import org.apache.http.HttpEntity;
    import org.apache.http.HttpResponse;
    import org.apache.http.client.HttpClient;
    import org.apache.http.client.methods.HttpPost;
    import org.apache.http.entity.ContentType;
    import org.apache.http.entity.FileEntity;
    import org.apache.http.entity.StringEntity;
    import org.apache.http.client.utils.URIBuilder;
    import org.apache.http.impl.client.DefaultHttpClient;
    import org.apache.http.util.EntityUtils;
    import org.json.JSONObject;
    
    
    public class Main
    {    
        public static final String subscriptionKey = "MY-KEY-HERE";
    
        public static final String uriBase = 
            "https://westcentralus.api.cognitive.microsoft.com/vision/v1.0/analyze";
    
        public static void main(String[] args)
        {
            HttpClient httpclient = new DefaultHttpClient();
    
            try
            {
                URIBuilder builder = new URIBuilder(uriBase);
    
                builder.setParameter("visualFeatures", "Categories,Description,Color");
                builder.setParameter("language", "en");
    
                URI uri = builder.build();
                HttpPost request = new HttpPost(uri);
    
                request.setHeader("Content-Type", "application/json");
                request.setHeader("Ocp-Apim-Subscription-Key", subscriptionKey);
    
                // Request body.
                BufferedImage image = null;
                File f = null;
                f = new File("C:\\Coffee.jpg"); //image file path
                image = ImageIO.read(f);
    
                File file = new File("C:\\Coffee.jpg");
    
                FileEntity reqEntityF = 
                    new FileEntity(file, ContentType.APPLICATION_OCTET_STREAM);
    
                request.setEntity(reqEntityF);
    
                HttpResponse response = httpclient.execute(request);
                HttpEntity entity = response.getEntity();
    
                if (entity != null)
                {
                    // Format and display the JSON response.
                    String jsonString = EntityUtils.toString(entity);
                    JSONObject json = new JSONObject(jsonString);
                    System.out.println("REST Response:\n");
                    System.out.println(json.toString(2));
                }
            }
            catch (Exception e)
            {
                System.out.println(e.getMessage());
            }
        }
    }
    

    输出为:

    REST Response:
    
    {
      "code": "BadArgument",
      "requestId": "7ecf2198-1b7f-44d0-9cc2-e05e28791281",
      "message": "JSON format error."
    }
    

    与stackoverflow指南中的其他帖子一样使用 FileEntity 上载图像。但它不起作用。

    我认为这部分应该以某种方式重构,以读取图像而不是URL。

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

    让我知道解决此问题的最佳解决方案是什么,因为如果可以将图像从本地传递到API,那么最好使用for循环来分析图像集。

    3 回复  |  直到 7 年前
        1
  •  2
  •   Maria Ines Parnisari    7 年前

    @乔恩 说,你需要改变 content-type 标题。

    // Request headers.
    request.setHeader("Content-Type", "application/octet-stream");
    
    // Request body.
    File file = new File(imagePath);
    FileEntity reqEntity = new FileEntity(file);
    request.setEntity(reqEntity);
    
        2
  •  0
  •   pumo    7 年前

    改变

    request.setHeader("Content-Type", "application/json");
    

    收件人:

    request.setHeader("Content-Type", "application/octet-stream");
    

    而不是使用

    StringEntity reqEntity = new StringEntity(url)
    

    使用:

    FileEntity reqEntity = new FileEntity(image, ContentType.APPLICATION_OCTET_STREAM);
    

    更改后,只需将图像路径指定为文件

    File image = new File("D:\\coffee3.jpg"); //image file path
    

    Microsoft computer vision api将以Json的形式返回结果。

        3
  •  0
  •   Michael Haas    6 年前

    我的Android版本(Java)

    private static void doRequest(final String image){
        new AsyncTask<Void, Void, String>() {
            DataOutputStream request;
            HttpURLConnection connection;
            @Override
            protected String doInBackground(Void... voids) {
                try {
                    URL url = new URL(requestUrl);
                    boolean isUrl = image.contains("http");
                    openConnection(url);
                    setPostData(isUrl);
                    setBody(image, isUrl);
                    return getResponse();
                }catch (IOException e) {
                    e.printStackTrace();
                }
                return null;
            }
                private void openConnection(URL url) throws IOException {
                    connection = (HttpURLConnection) url.openConnection();
                }
                private void setPostData(boolean isUrl) throws ProtocolException {
                    connection.setRequestMethod("POST");
                    connection.setRequestProperty("details", "{string}");
                    connection.setRequestProperty("Host", "westeurope.api.cognitive.microsoft.com");
                    if(isUrl) {
                        connection.setRequestProperty("Content-Type", "application/json");
                    }
                    else {
                        connection.setRequestProperty("Content-Type", "application/octet-stream");
                    }
                    connection.setRequestProperty("Ocp-Apim-Subscription-Key", "yourKey");
                }
                private void setBody(String image, boolean isUrl) throws IOException {
                    request = new DataOutputStream(connection.getOutputStream());
                    if(isUrl){
                        request.writeBytes(urlBody(image));
                    }
                    else {
                        request.write(FileManager.getBytesFrom(image));
                    }
    
                }
                    private String urlBody(String image){
                        return  "{\"url\":\"" + image + "\"}";
                    }
                private String getResponse() throws IOException{
                    InputStream inputStream = connection.getInputStream();
                    String response = inputStream2String(inputStream);
                    return response;
                }
                    private String inputStream2String(InputStream inputStream) throws IOException{
                        BufferedReader bufferedReader = bufferResult(inputStream);
                        return resultString(bufferedReader).toString();
                    }
                        private StringBuilder resultString(BufferedReader bufferedReader) throws IOException {
                            StringBuilder stringBuilder = new StringBuilder();
                            String line;
                            while ((line = bufferedReader.readLine()) != null) {
                                stringBuilder.append(line);
                            }
                            return stringBuilder;
                        }
                        private BufferedReader bufferResult(InputStream inputStream){
                            InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
                            return new BufferedReader(inputStreamReader);
                        }
    
            @Override
            protected void onPostExecute(String result) {
                //...
            }
    
        }.execute();
    }