0

我已经为此绞尽脑汁了一段时间,如果有人对这个问题有一些洞察力可以帮助我,我将不胜感激!

我正在尝试使用来自 Android Studio 的 POST(通过使用相机拍照)将图像上传到 Watson 的 Visual Recognition API。

我已经设法 - 用相机拍照后保存图像 - 在应用程序上将其显示为位图图像

我正在尝试将文件上传到 Watson API,但我不断收到此错误

"description": "无效的图像数据。支持的格式有 JPG、PNG 和 GIF。"

如果有人能对我在这里做错的事情提供一些见解,我将不胜感激。提前致谢!

我现在正在使用 HttpUrlConnection 和 DataOutputStream 进行 POST,代码如下:

imgName 和 imgPath 都被正确识别,name="images_file" 是 Watson Visual Recognition API 请求 name 的方式

public void uploadImage(){
    HttpURLConnection conn = null;
    DataOutputStream dos = null;
    String lineEnd = "\r\n";
    String twoHyphens = "--";
    String boundary = "*****";
    int bytesRead, bytesAvailable, bufferSize;
    byte[] buffer;
    int maxBufferSize = 1 * 1024 * 1024;
    try{

        StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();

        StrictMode.setThreadPolicy(policy);

        URL url = new URL("https://gateway-a.watsonplatform.net/visual-recognition/api/v3/classify?api_key=APIKEY&version=2016-05-20");
        conn= (HttpURLConnection) url.openConnection();
        FileInputStream fileInputStream = new FileInputStream(file);
        conn.setDoInput(true);
        conn.setDoOutput(true);
        conn.setUseCaches(false);
        conn.setRequestMethod("POST");
        conn.setRequestProperty("Connection", "Keep-Alive");
        conn.setRequestProperty("ENCTYPE", "multipart/form-data");
        conn.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
        conn.setRequestProperty("images_file", imgPath);

        dos = new DataOutputStream(conn.getOutputStream());

        dos.writeBytes(twoHyphens + boundary + lineEnd);
        dos.writeBytes("Content-Disposition: form-data; name=\"images_file\"; filename = \"" + imgName + "\"" + lineEnd);
        dos.writeBytes(lineEnd);


        bytesAvailable = fileInputStream.available();
        bufferSize = Math.min(bytesAvailable, maxBufferSize);
        buffer = new byte[bufferSize];

        bytesRead = fileInputStream.read(buffer, 0, bufferSize);
        while (bytesRead > 0) {

            dos.write(buffer, 0, bufferSize);
            bytesAvailable = fileInputStream.available();
            bufferSize = Math.min(bytesAvailable, maxBufferSize);
            bytesRead = fileInputStream.read(buffer, 0, bufferSize);

        }

        // send multipart form data necesssary after file data...
        dos.writeBytes(lineEnd);
        dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);

        // Responses from the server (code and message)
        serverResponseCode = conn.getResponseCode();
        String serverResponseMessage = conn.getResponseMessage();

        Log.i("uploadFile", "HTTP Response is : "
                + serverResponseMessage + ": " + serverResponseCode);

        if(serverResponseCode == 200){

            BufferedReader br = new BufferedReader(new InputStreamReader((conn.getInputStream())));
            StringBuilder sb = new StringBuilder();
            String output;
            while ((output = br.readLine()) !=null) {
                sb.append(output);
            }
            Log.d("debugging", sb.toString());

            runOnUiThread(new Runnable() {
                public void run() {

                    String msg = "File Upload Completed.\n\n See uploaded file here : \n\n"
                            +" http://www.androidexample.com/media/uploads/"
                            +imgName;


                    Toast.makeText(getApplicationContext(), "File Upload Complete.",
                            Toast.LENGTH_SHORT).show();


                }
            });
        }

        //close the streams //
        fileInputStream.close();
        dos.flush();
        dos.close();

    } catch (MalformedURLException ex) {

        ex.printStackTrace();

        runOnUiThread(new Runnable() {
            public void run() {
                Toast.makeText(getApplicationContext(), "MalformedURLException",
                        Toast.LENGTH_SHORT).show();
            }
        });

        Log.e("Upload file to server", "error: " + ex.getMessage(), ex);
    } catch (Exception e) {

        e.printStackTrace();

        runOnUiThread(new Runnable() {
            public void run() {
                Toast.makeText(getApplicationContext(), "Got Exception : see logcat ",
                        Toast.LENGTH_SHORT).show();
            }
        });
        Log.e("Debugging", "Exception : "
                + e.getMessage(), e);
    }
    Log.d("Debugging", "responseCode:" + serverResponseCode);
}
4

2 回答 2

1

Visual Recognition 在 Java 中有一个 SDK(客户端库)。您只需将依赖项添加到您的build.gradle.

  compile 'com.ibm.watson.developer_cloud:java-sdk:3.2.0'

然后

VisualRecognition service = new VisualRecognition(VisualRecognition.VERSION_DATE_2016_05_20);
service.setApiKey("<api-key>");

ClassifyImagesOptions options = new ClassifyImagesOptions.Builder()
  .images(new File("car.png"))
  .build();

VisualClassification result = service.classify(options)
  .enqueue(new ServiceCallback<List<Dialog>>() {
      @Override
      public void onResponse(List<Dialog> response) {
        System.out.println(response);
      }

      @Override
      public void onFailure(Exception e) {
      // on failure
      }}
  );

这个例子有一个CameraHelper类,带有实用方法来获取 Android 中图片的文件路径或 InputStream。

于 2016-08-07T20:10:58.833 回答
0

要确保检查的另一件事是 imgName 实际上以其中一个扩展名结尾 - 否则系统当前不会接受它。

于 2016-08-08T23:59:25.420 回答