Android以最高效的方式将图片上传到服务器

Android以最高效的方式将图片上传到服务器,android,android-image,android-imageview,Android,Android Image,Android Imageview,我需要将图像和其他数据(非常类似于带有附件的电子邮件)一起发送到服务器。我还需要以可靠的方式进行操作,以便在失败时重试等 服务器是WCF REST服务器,我用它进行了很多其他通信(JSON),但我刚刚得到了上传图像的新要求 因为我使用JSON将数据发布到服务器,所以我在Android端使用GSON来序列化数据 以下是迄今为止我是如何实现它的(其他一切都是这样,但我只是从图像开始) 用户填写活动字段(文本数据) 用户通过相机拍摄一些照片。目前我只使用一个文件的图片 我从SD卡上拍照,加载/调整其大

我需要将图像和其他数据(非常类似于带有附件的电子邮件)一起发送到服务器。我还需要以可靠的方式进行操作,以便在失败时重试等

服务器是WCF REST服务器,我用它进行了很多其他通信(JSON),但我刚刚得到了上传图像的新要求

因为我使用JSON将数据发布到服务器,所以我在Android端使用GSON来序列化数据

以下是迄今为止我是如何实现它的(其他一切都是这样,但我只是从图像开始)

  • 用户填写活动字段(文本数据)
  • 用户通过相机拍摄一些照片。目前我只使用一个文件的图片
  • 我从SD卡上拍照,加载/调整其大小-在ImageView上显示并存储在字节[]
  • 用户提交-我从字节[]获取所有数据和图像,并将其放入Java对象中
  • 调用GSON转换器并序列化对象
  • 将对象保存到SQLite中
  • AsyncTask在SQLite中查找记录,打开游标并获取文本
  • AsyncTask创建HttpConnection并将文本数据发布到我的服务器
  • 结局
  • 现在来谈谈我的问题。。 显然在#3上,我用字节数组“爆炸”ram。有时我甚至觉得我的Nexus S变得迟钝。但通过这样做,我避免了用很多文件填充SD卡或应用程序文件夹。我拍了一张照片,然后抓住它。下一张图片将覆盖上一张

    第五步很慢。我没有在GSON上尝试自定义序列化程序,而是将字节数组序列化为类似于[1,-100123,-12]的内容,我可以使用Base64获得更小的大小,但仍然可以。这将是缓慢的。我最多可以有20张照片

    第六步没问题。但在一定的大小下(我尝试了300px图像),我在OpenCursor的第7步中开始出现错误

    07-06 20:28:47.113: ERROR/CursorWindow(16292): need to grow: mSize = 1048576, size = 925630, freeSpace() = 402958, numRows = 2
    07-06 20:28:47.113: ERROR/CursorWindow(16292): not growing since there are already 2 row(s), max size 1048576
    07-06 20:28:47.113: ERROR/Cursor(16292): Failed allocating 925630 bytes for text/blob at 1,1
    
    所以,这整件事不是我喜欢的。理想情况下,我希望所有数据都以单件形式上传到服务器

    我在想,也许可以在SD卡上存储带有时间戳的图像,并在DB中只存储它们的名称。然后我会在发送到服务器之前处理它们。一旦成功,我会删除这些图片。这种逻辑将使SQLite模式更加复杂,但也许没有更好的方法

    我想我在寻找处理图像的最佳实践。如何以最小的内存/CPU使用率执行以下操作:

  • 拍照
  • 显示缩略图
  • 调整大小
  • 发送到服务器
  • 编辑1:

    目前我正在研究将整个西藏作为多部分MIME信息上传的可能性。这需要在我的Android软件包中添加一些JAR。此外,我不确定Apache代码加载图像并发送图像的效果如何(我想比我的代码更好)

    我必须在WCF端解析所有这些,因为在.NET框架上构建是无法做到的

    如果你试过这个,请告诉我

    编辑2:


    默剧不行。没有任何意义,因为它使用Base64序列化二进制,这是同一件事。

    没有人回答,但以下是我费尽周折得出的结论:

    规则1:处理图像时,避免使用对象/内存。听起来很明显,但事实并非如此。我认为将图像大小调整为800x600是可以的。任何更大的东西-你可以考虑只留下它,因为它可能在大文件上做HTTP流,但是当你把图像加载到内存中去处理< /P>时,很难用OOM异常工作。 规则#2:当使用GSON时-使用JsonWriter填充流。否则,内存将爆炸。然后将该流传递到HttpClient。JsonWriter将分块写入,数据将在处理过程中发送

    规则3:见规则2。它可以用于多个小图像。这样,GSON将逐个序列化它们,并将其馈送到流中。无论如何,每个图像都将加载到内存中

    规则4:这可能是最好的解决方案,但需要与服务器进行更多的协调。在消息发送到服务器之前由1发送的图像。它们以流的形式发送,没有任何编码。这样,它们就不必进行base64编码,也不必加载到设备的内存中。传输的大小也将更小。发送所有图像时-在服务器上发布主要信息对象并收集所有包

    规则5:忘记在SQLite中存储BLOB

    底线:

    • 就资源而言,发送图像而不调整大小要便宜得多。只有当图像大小达到800x600左右时,调整大小才有意义
    • 当图像变小(如600x400英寸)时,在单个包中发送多个图像是有意义的
    • 一旦你需要上传文件,就开始到处思考。不要将内容加载到内存中
    那么您正在将图片保存到数据库中?这会使数据库的大小爆炸,你的用户会抱怨该应用程序占用了手机内部存储空间太多,并且会要求app2sd支持——为什么不将图像保留在sd卡上?@denis我发现Android 1MB上的光标大小有限制,所以这不仅是内部存储的问题,而且我也会达到该限制只需将此类数据保存在SQLite中即可轻松完成。看来使用外部存储是处理这些东西的唯一正确方法。谢谢,听起来很合理。是否存在设备和服务器端的代码片段?我想上传图像到服务器。我现在正在使用php。