【问题标题】:Android post high res image running out of memoryAndroid发布高分辨率图像内存不足
【发布时间】:2012-05-08 04:26:48
【问题描述】:

各位开发者好。

我正忙着让 Android 从应用上传图片。
我也让它工作了(代码如下)。
但是当我发送大图像(10 兆像素)时,我的应用程序因内存不足异常而崩溃。
解决方案是使用压缩,但如果我想发送全尺寸图像怎么办?
我想也许有流的东西,但我不熟悉流。也许 urlconnection 可能会有所帮助,但我真的不知道。

我将文件名命名为 File[0 to 9999].jpg 带有图像日期的 post 值称为 Filedata 我为 post 值 dropboxid 提供了一个 UID

下面的代码有效,但我很想解决阻止我发送高分辨率图像的问题。

亲切的问候

try
{
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    bitmap.compress(CompressFormat.JPEG, 100, bos);
    byte[] data = bos.toByteArray();

    HttpPost postRequest = new HttpPost(URL_SEND);

    ByteArrayBody bab = new ByteArrayBody(data, "File" + pad(random.nextInt(9999) + 1) + ".jpg");
    MultipartEntity reqEntity = new multipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
    reqEntity.addPart("Filedata", bab);
    reqEntity.addPart("dropboxId", new StringBody(URLEncoder.encode(uid)));
    postRequest.setEntity(reqEntity);

    HttpResponse response = httpClient.execute(postRequest);
    BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), "UTF-8"));
    String sResponse;
    StringBuilder s = new StringBuilder();

    while((sResponse = reader.readLine()) != null)
    {
        s = s.append(sResponse);
    }

    if(d) Log.i(E, "Send response:\n" + s);
}
catch (Exception e)
{
    if(d) Log.e(E, "Error while sending: " + e.getMessage());
    return ERROR;
}

【问题讨论】:

    标签: java android image post upload


    【解决方案1】:

    当使用ByteArrayOutputStream 然后调用#toByteArray() 时,您实际上加倍 JPEG 使用的内存量。 ByteArrayOutputStream 使用编码的 JPEG 保存一个内部数组,当您调用 #toByteArray() 时,它会分配一个 new 数组并从内部缓冲区复制数据。

    考虑将大型位图编码为临时文件并使用FileOutputStreamFileInputStream 对图像进行编码和发送。

    如果没有“上传” - 你的应用程序“很好”地存活了我假设的内存中的巨大位图?

    编辑:FileBody

    File img = new File(this is where you put the path of your image)
    ContentBody cb = new FileBody(img, "File" + pad(random.nextInt(9999) + 1) + ".jpg", "image/jpg", null);
    MultipartEntity reqEntity = new multipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
    reqEntity.addPart("Filedata", cb);
    reqEntity.addPart("dropboxId", new StringBody(URLEncoder.encode(uid)));
    

    【讨论】:

    • 在我的应用程序中,我只存储对文件的引用。所以文件已经存储(在sd卡上)。只有当我开始上传时,我才会从中获取位图。我的主要问题是我不知道如何从该文件中获取输入流并将其转换为可以与我的实体一起发布的输出流。位图代码 bitmap = BitmapFactory.decodeFile(path);所以在这里我必须做类似 ByteArrayBody bab = fileinputstream(path)?
    • 那么.. 你为什么要获取位图?源文件是 PNG 并且 Web 服务器只接受 PNG?否则 - 只需上传您已有的文件 - 重新编码这样的 JPEG 可能只会在图像中引入更多古怪的伪影。 编辑:您导入了一些额外的 Apache 库对吗?在这种情况下,您应该拥有 FileBody 类。你能用那个吗
    • 我几乎可以发送任何我喜欢的文件类型。但我仍然不知道如何从文件中获取字节。但这个想法很好,所以我想我会去谷歌。或者,如果您有一个简单的示例,那就太好了。如果我发现什么我会发布它。感谢您的建议
    • 好吧,您可以实现自己的ContentBody,但只使用FileBody 而不是ByteArrayBody 应该适合您。
    猜你喜欢
    • 2013-09-09
    • 1970-01-01
    • 2015-04-03
    • 2014-10-03
    • 2015-10-20
    • 2012-05-28
    • 1970-01-01
    • 1970-01-01
    • 2012-01-29
    相关资源
    最近更新 更多