【问题标题】:Raw Image Data as POST param using AsyncHttpClient使用 AsyncHttpClient 作为 POST 参数的原始图像数据
【发布时间】:2012-10-18 01:05:52
【问题描述】:

我有一个简单的 PHP 服务,我正试图从一个 Android 应用程序中访问,我想通过一个 POST 参数传递一个原始图像。我有一个 PHP/curl 脚本工作,它执行以下操作:

$url = "http://myphp.php"
$imagefilepath = 'path_to_png_file.png';
$imagedata = file_get_contents($imagefilepath);
$data = array('imagedata' => $imagedata);
// a few other fields are set into $data, but not important

curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1); 
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.2) Gecko/20090729 Firefox/3.5.2 GTB5');
curl_exec($ch);

我想在我的 Android 应用程序中使用 AsyncHttpClient (http://loopj.com/android-async-http/) 在 Java 中模仿这个东西。

听起来很简单,我可以在 Java 中调用,但问题是我发送的数据在另一端无法识别为图像。但是,使用上面的 PHP/Curl 脚本,它在所有方面都可以正常工作。

这是我的 Java 代码,其中包含一些我尝试过的注释:

String photoFilePath = "path_to_my_photo_on_disk.jpg";

Bitmap bm = BitmapFactory.decodeFile(photoFilePath);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bm.compress(Bitmap.CompressFormat.JPEG, 50, baos);
byte[] byteArrayPhoto = baos.toByteArray();

AsyncHttpClient client = new AsyncHttpClient(context);
RequestParams params = new RequestParams();
try {
      // THINGS I HAVE TRIED (AND FAILED):
      //params.put("imagedata", new File(photoFilePath));
      //params.put("imagedata", new ByteArrayInputStream(byteArrayPhoto), "photo.jpg");                        
      //params.put("imagedata", new String(byteArrayPhoto));
      //params.put("imagedata", new String(byteArrayPhoto, "UTF-8"));
      //params.put("imagedata", fileToString(photoFilePath));
      //params.put("imagedata", new FileInputStream(new File(photoFilePath)), "photo.jpg", "image/jpeg");
} catch (Exception e) {
      e.printStackTrace();
}

client.post(context, myURL, params, new AsyncHttpResponseHandler() {
...override methods, onSuccess() is called...
}

// for reference, for the above-called method:
private String fileToString(String filename) throws IOException
    {
        BufferedReader reader = new BufferedReader(new FileReader(filename));
        StringBuilder builder = new StringBuilder();
        String line;

        // For every line in the file, append it to the string builder
        while((line = reader.readLine()) != null)
        {
            builder.append(line);
        }

        return builder.toString();
    }
  • 请注意,在上面的一些已注释掉的行/尝试中,POST 参数甚至无法将其传递到另一侧。

我还尝试了一些其他方法将文件放入字节数组,以及对文件进行编码(base64),但没有成功。无论出于何种原因,调用成功并传输了数据,但是每次我们尝试在服务器端打开图像时,它都已损坏和/或无法以 JPG 格式打开。我尝试过大大小小的图像文件。

我确实进行了研究并尝试了许多我找到的解决方案,但似乎没有任何效果。我确定我在这里遗漏了一些明显的东西,但是任何人都可以引导我朝着正确的方向前进吗?

任何帮助将不胜感激!

【问题讨论】:

  • 您确定从Bitmap 到jpg 的转换工作正常吗?我将问题分为两部分:1)确保转换正常,2)上传 jpg。尝试执行转换并将文件写入 sd 卡。还可以尝试上传已知正常的预先存在的 jpg。然后,您应该能够找出问题所在。
  • 感谢您的回复 - 是的,我确认位图 > jpg 通过将我的字节数组写入文件系统上的新文件中正常工作,然后确保我可以打开它(我可以)。我还直接从文件系统中提取了原始文件,并从我的 PHP/Curl 脚本中调用了该服务,它运行良好。所以问题似乎是它如何作为“原始数据”附加到请求中。我觉得我在这里遗漏了一些明显的东西 - 我尝试了两种不同的方式将字节数组附加为 POST 参数(参见原始帖子,中间的两个注释掉的),这两种方法都不起作用:(

标签: java android https


【解决方案1】:

这个问题的答案相当简单。事实证明,我确实需要对图像进行 base64 编码,因为它在发送到服务时会以某种方式损坏。我通过这段代码做到了这一点:

String encodedPhotoStr = Base64.encodeToString(byteArrayPhoto, Base64.DEFAULT);
params.put("imagedata", encodedPhotoStr);

但在 PHP 端添加一行以解码此数据至关重要,如下所示:

$raw_data_str = base64_decode($data_str_from_java)

这解决了问题,现在可以在发送后查看图像。因此,无论出于何种原因,将原始二进制/图像数据从 java 发送到 PHP 是行不通的(尽管 curl 脚本工作正常),我绝对必须以这种方式对其进行编码和解码才能使其从 Java 代码中工作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-06
    • 1970-01-01
    • 1970-01-01
    • 2017-12-19
    • 1970-01-01
    相关资源
    最近更新 更多