2011-07-07 36 views
7

Tôi cần tải hình ảnh cùng với các dữ liệu khác (rất giống với email có đính kèm) đến máy chủ. Tôi cũng cần phải làm điều đó một cách đáng tin cậy để tôi có thể thử lại, vv về thất bại.Tải hình ảnh lên Android lên máy chủ theo cách hiệu quả nhất

Máy chủ là WCF REST server và tôi thực hiện rất nhiều liên lạc khác với nó (JSON) nhưng chỉ có yêu cầu mới này để tải lên hình ảnh.

Vì tôi sử dụng JSON để đăng dữ liệu lên máy chủ của mình - tôi sử dụng GSON trên Android để tuần tự hóa dữ liệu.

Dưới đây là cách tôi đã nhận nó thực hiện cho đến nay (mọi thứ khác hoạt động theo cách này nhưng tôi chỉ mới bắt đầu với hình ảnh)

  1. tài Lĩnh vực họat động điền (dữ liệu văn bản)
  2. tài khoản có một số hình ảnh (s) thông qua ý định của máy ảnh. Hiện tại tôi chỉ sử dụng 1 tệp cho hình ảnh
  3. Tôi chụp ảnh từ SDCard, tải/thay đổi kích thước - phân phối trên ImageView và lưu trữ theo byte []
  4. Người dùng gửi - Tôi lấy tất cả dữ liệu cùng với hình ảnh từ byte [] và đặt nó vào Java object
  5. Gọi GSON chuyển đổi và serialize đối tượng
  6. Lưu đối tượng vào SQLite
  7. AsyncTask trông trong SQLite cho các hồ sơ, mở ra con trỏ và nhận của văn bản
  8. AsyncTask tạo HttpConnection và viết dữ liệu văn bản đến máy chủ của tôi.
  9. THE END

Bây giờ đến vấn đề của tôi .. Rõ ràng trên # 3 - I "nổ" ram với mảng byte của tôi. Đôi khi tôi thậm chí cảm thấy Nexus S của tôi trở nên chậm chạp. Nhưng bằng cách làm điều đó - tôi tránh làm đầy thẻ SD hoặc thư mục ứng dụng với nhiều tệp. Tôi chụp ảnh và lấy nó. Hình ảnh tiếp theo sẽ ghi đè lên hình ảnh trước đó.

BướC# 5 IS chậm. Tôi đã không thử serializer tùy chỉnh trên GSON và thay vì serializing mảng byte thành một cái gì đó như [1, -100,123, -12] tôi có thể nhận được kích thước nhỏ hơn nhiều với Base64 nhưng vẫn còn. Nó sẽ chậm. Và tôi có thể có tối đa 20 hình ảnh ...

BướC# 6 không thành vấn đề. Nhưng với kích thước nhất định (tôi đã thử hình ảnh 300px), tôi bắt đầu gặp lỗi ở bước 7 trên OpenCursor

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 

Vì vậy, toàn bộ điều này không phải là thứ tôi thích. Lý tưởng nhất là tôi muốn tất cả dữ liệu được tải lên trong một phần duy nhất đến máy chủ.

Tôi đã nghĩ có thể lưu trữ hình ảnh được gắn dấu thời gian trên thẻ SD và chỉ lưu trữ tên của họ trong DB. Hơn tôi sẽ xử lý chúng ngay trước khi gửi đến máy chủ. Và khi thành công, tôi sẽ xóa những hình ảnh đó. Loại logic này sẽ làm cho lược đồ SQLite phức tạp hơn nhiều nhưng có lẽ không có cách nào tốt hơn ?!

Tôi đoán tôi đang tìm cách thực hành tốt nhất để xử lý hình ảnh.Làm thế nào để làm followin với tối thiểu sử dụng bộ nhớ/CPU:

  1. chụp hình
  2. hiển thị thumbnail
  3. Resize
  4. Gửi đến máy chủ

EDIT 1:

Hiện nay Tôi đang nghiên cứu khả năng tải lên toàn bộ shizang dưới dạng tin nhắn MIME nhiều phần. Điều đó sẽ yêu cầu thêm một số JAR vào gói Android của tôi. Ngoài ra tôi không chắc chắn làm thế nào hiệu quả sẽ được mã Apache để tải hình ảnh và gửi chúng (tôi đoán tốt hơn so với mã của tôi) http://okandroidletsgo.wordpress.com/2011/05/30/android-to-wcf-streaming-multi-part-binary-images/

Và tôi sẽ phải đối phó với phân tích tất cả điều này trên WCF bên vì không có cách để làm điều đó với built-on .NET framework.

http://antscode.blogspot.com/2009/11/parsing-multipart-form-data-in-wcf.html

XIN VUI LÒNG CHO TÔI NẾU BẠN ĐÃ XEM NÀY!

EDIT 2:

MIME là không tốt. Không có điểm vì nó serializes nhị phân sử dụng Base64 đó là điều tương tự ..

+1

Vì vậy, bạn đang lưu hình ảnh vào cơ sở dữ liệu? Điều đó sẽ bùng nổ kích thước cơ sở dữ liệu và người dùng của bạn sẽ phàn nàn rằng ứng dụng đang chiếm quá nhiều dung lượng trên bộ nhớ trong của điện thoại và sẽ yêu cầu hỗ trợ app2sd - tại sao không giữ hình ảnh trên thẻ sd? –

+0

@denis Tôi thấy rằng giới hạn kích thước con trỏ trên Android 1MB vì ​​vậy nó không chỉ là vấn đề với bộ nhớ trong mà còn tôi sẽ đạt đến giới hạn đó một cách dễ dàng chỉ bằng cách lưu loại dữ liệu này trong SQLite. Dường như sử dụng bộ nhớ ngoài chỉ là cách chính xác để xử lý các nội dung như vậy – katit

Trả lời

16

Không ai trả lời nhưng đây là những gì tôi đã tìm cách cứng:

Rule # 1: Khi giao dịch với những hình ảnh - tránh sử dụng đối tượng/bộ nhớ. Nghe có vẻ hiển nhiên nhưng không phải. Tôi figured rằng thay đổi kích thước hình ảnh đến 800x600 là OK. Bất cứ điều gì lớn hơn - bạn có thể xem xét chỉ để lại nó như là bởi vì nó có thể làm dòng http trên tập tin lớn hơn nhưng thật khó để làm việc với OOM ngoại lệ khi bạn tải hình ảnh vào bộ nhớ để xử lý

Quy tắc 2: Khi sử dụng GSON - sử dụng JsonWriter để điền luồng. Nếu không thì bộ nhớ sẽ phát nổ. Hơn là vượt qua luồng đó vào HttpClient. JsonWriter sẽ viết theo khối và dữ liệu sẽ được gửi khi nó xử lý.

Quy tắc 3: Xem quy tắc số 2. Nó sẽ làm việc OK cho nhiều hình ảnh nhỏ. Bằng cách này, GSON sẽ tuần tự hóa từng cái một và đưa vào luồng. Mỗi hình ảnh S be được nạp vào bộ nhớ int anyway.

Quy tắc 4: Đây có lẽ là giải pháp tốt nhất nhưng yêu cầu phối hợp nhiều hơn với máy chủ. Hình ảnh được gửi 1 bởi 1 trước khi tin nhắn được gửi đến máy chủ. Chúng được gửi dưới dạng luồng mà không cần bất kỳ mã hóa nào. Bằng cách này, chúng không cần phải được mã hóa base64 và chúng không phải được tải trong bộ nhớ trên thiết bị. Kích thước truyền cũng sẽ nhỏ hơn. Khi tất cả hình ảnh được gửi - đăng đối tượng thông tin chính và thu thập tất cả các gói cùng nhau trên máy chủ.

Rule # 5: Quên về lưu trữ BLOB trong SQLite

Bottom line:

  • Đó là rẻ hơn nhiều về mặt nguồn lực để gửi hình ảnh KHÔNG bất kỳ thay đổi kích thước. Thay đổi kích thước chỉ có ý nghĩa khi hình ảnh nhận được khoảng 800x600-ish
  • Gửi nhiều hình ảnh trong một gói duy nhất có ý nghĩa khi hình ảnh nhỏ như 600x400-ish
  • Ngay khi bạn cần tải lên tệp - hãy bắt đầu nghĩ luồng ở mọi nơi. KHÔNG tải công cụ vào bộ nhớ.
+0

Xin chào Katit, cảm ơn, âm thanh hợp lý. Có một đoạn trích nào đó cho thiết bị và phía máy chủ không? Tôi muốn tải hình ảnh lên máy chủ. Tôi đang sử dụng php ngay bây giờ. – Diego

Các vấn đề liên quan