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

时间:2018-03-24 10:41:05

标签: java api image-processing microsoft-cognitive

问题是如何加载图像文件并将其作为对象传递给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 个答案:

答案 0 :(得分:1)

正如 @Jon 所说,您需要更改while True: schedule = make_today_or_tomorrow_schedule() for event in schedule: while datetime.now() < event: sleep(event - datetime.now()) execute_my_function 标题。

public class ComboBoxDemo extends JFrame implements ActionListener{

private String[] str = {"One", "Two", "Three", "Four"};
private String[] d = {"1", "2", "3", "4"};
private JPanel panel;
private JButton button;
private JComboBox cb, cb1;
private int count = 0;

public ComboBoxDemo() { 
    panel = new JPanel();
    button = new JButton("Click");
    setTitle("Demo");
    panel.setLayout(new FlowLayout());
    cb = new JComboBox<String>(str); 
    cb1 = new JComboBox<String>(d);
    panel.add(cb);
    panel.add(cb1);
    panel.add(button);
    getContentPane().add(panel);
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    setSize(200,200);
    setVisible(true);   
}
public static void main(String[] args) {
    new ComboBoxDemo();
}

@Override
public void actionPerformed(ActionEvent e) {
    if(e.getSource() == button) {
        count = count*2;
        System.out.println(count);
    }
    if(e.getSource() == cb) {
        count++;
        System.out.println(count);
    }
    if(e.getSource() == cb1) {
        count--;
        System.out.println(count);
    }
    }
}

答案 1 :(得分:0)

更改

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计算机视觉api将结果发送回Json。

答案 2 :(得分:0)

我的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();
}