从 Android Studio 上传图像时出现 Watson Visual Recognition 错误 "Invalid image data. Supported formats are JPG, PNG, and GIF"

Watson Visual Recognition error "Invalid image data. Supported formats are JPG, PNG, and GIF" when uploading image from Android Studio

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

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

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

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

"description": "Invalid image data. Supported formats are JPG, PNG, and 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);
}

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
      }}
  );

这个 example 有一个 CameraHelper class 和实用方法来获取 Android 中图片的文件路径或 InputStream。

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