2010-08-20 33 views
5

Tôi đang lưu vào bộ nhớ cache các tệp hình ảnh dưới dạng blob trong cơ sở dữ liệu SQLite. Tôi có một ứng dụng tương tự trên một nền tảng khác thực hiện điều tương tự với cùng một tệp hình ảnh. Cơ sở dữ liệu trên cả hai nền tảng báo cáo cùng một kích thước chính xác cho cùng một hình ảnh. Vì vậy, tôi nghĩ, nhưng không thể đảm bảo, rằng dữ liệu hình ảnh đang đi vào cơ sở dữ liệu còn nguyên vẹn.Sự cố khi tạo Bản vẽ từ một Bloite SQL

Nhưng khi tôi cố gắng tạo Bản vẽ, bảng điều khiển in ra "DEBUG/skia (267): --- decoder-> decode trả về false".

Các bước thực hiện:

  1. Đọc blob vào một mảng byte.

    byte [] b = byte mới [imageDataCursor.getInt (0)];

    b = imageDataCursor.getBlob (1);

  2. Tạo luồng đầu vào từ mảng byte.

    ByteArrayInputStream là = new ByteArrayInputStream (b);

  3. Tạo bản vẽ từ InputStream. (đây là điều tạo ra thông báo 'bộ giải mã' ở trên)

    Drw drawable = Drawable.createFromStream (is, "articleImage");

  4. Đặt ImageView.image thành Drawable.

    imgView.setImageDrawable (drw);

Cho đến nay, không có niềm vui. Bất kỳ đề xuất?

Trả lời

1

Tôi sẽ đăng giải pháp của mình để giúp bất kỳ ai có vấn đề tương tự.

Tôi đã thử kiểm tra mảng byte mà tôi đang đọc từ cơ sở dữ liệu bằng cách viết nó vào một tệp và sau đó xem tệp. Nó chỉ ra rằng các dữ liệu blob trong cơ sở dữ liệu là không hoàn thành - Tôi nhận được một vài dòng của hình ảnh, nhưng không phải là toàn bộ hình ảnh.

Giải pháp liên quan đến việc tạo BufferedInputStream và ByteArrayBuffer để đọc trong hình ảnh từ máy chủ từ xa. Mã này để nắm bắt một file ảnh từ một máy chủ từ xa và tạo ra một mảng byte để có thể viết nó vào một cơ sở dữ liệu SQLite trông như thế này:

   try { 
      HttpGet getMethod=new HttpGet(url); 
       HttpClient client=new DefaultHttpClient(); 
      HttpResponse response = client.execute(getMethod); 
      HttpEntity entity = response.getEntity(); 
      InputStream in = entity.getContent(); 
      BufferedInputStream bis = new BufferedInputStream(in); 
      ByteArrayBuffer baf = new ByteArrayBuffer(50); 
      int current = 0; 
      while ((current = bis.read()) != -1) { 
       baf.append((byte) current); 
      } 
      byte[] b = baf.toByteArray(); 
      database.updateArticleWithImageData(b, imageKey); 
     } 
     catch (Throwable t) { 
      android.util.Log.e("MyApp", "Exception fetching image file", t); 
     } 
0

Tôi đuổi theo cái đuôi của tôi xung quanh về vấn đề này cho khá trong một. Câu trả lời từ deSelby đã giúp tôi. Đây là mã của tôi tải xuống hình ảnh (PNG và JPG) từ Facebook, sau đó lưu trữ/truy xuất dữ liệu từ một bảng sqlite bằng cách sử dụng đường dẫn làm tham chiếu. Như bạn có thể thấy, nó thực sự cố gắng đọc hình ảnh từ bảng đầu tiên, nếu nó ở đó nó chỉ đơn giản là trả về nó, nếu không nó lấy nó từ Facebook, lưu nó trong cơ sở dữ liệu và sau đó trả về nó.

private static Drawable fetchPhoto(ContentResolver cr, int source, String path) { 
    Drawable image = null; 
    myDB mDb = myDB.getInstance(); 
    Cursor iCursor = mDb.fetchImage(cr, path); 
    if(iCursor != null && iCursor.moveToFirst()) {    
     byte[] bb = iCursor.getBlob(iCursor.getColumnIndex(Images.IMAGE)); 
     if(iCursor != null) iCursor.close(); 
     image = new BitmapDrawable(BitmapFactory.decodeByteArray(bb, 0, bb.length)); 
    } else { 
     if(iCursor != null) iCursor.close(); 
     //get image from path 
     try 
     { 
      InputStream is = (InputStream) new URL(path).getContent(); 
      BufferedInputStream bis = new BufferedInputStream(is); 
      ByteArrayBuffer baf = new ByteArrayBuffer(50); 
      int current = 0; 
      while ((current = bis.read()) != -1) { 
       baf.append((byte) current); 
      } 
      byte[] barray = baf.toByteArray(); 
      bis.close(); 
      is.close(); 
      /* write image to db */ 
      long id = mDb.writeImage(cr,source,path,barray); 
      image = new BitmapDrawable(BitmapFactory.decodeByteArray(barray, 0, barray.length));    
     }catch (Exception error) { 
      //System.out.println("Exc="+e); 
     } 
    } 
    return image; 
} 

Hình thức viết của tôi trông như thế này (xem bên dưới).

Images.IMAGE tham chiếu tên của cột BLOB trong bảng của tôi. Điểm chính ở đây thực sự là bạn có thể viết byte [] trực tiếp vào cột BLOB cơ sở dữ liệu. Tôi viết thời gian (utc) để tôi có thể xóa dữ liệu cũ theo chính sách api của Facebook về dữ liệu bộ nhớ đệm.

public long writeImage(ContentResolver contentResolver, int source, String path, byte[] image) { 

    Time now = new Time(); 
    now.setToNow(); 
    ContentValues initialValues = new ContentValues();  
    initialValues.put(Images.IMAGE, image); 
    initialValues.put(Images.SOURCE, source); 
    initialValues.put(Images.PATH, path); 
    initialValues.put(Images.UTC, now.toMillis(false)); 
    if(source == 0) initialValues.put(Images.DIRTY, 1); // sync user created images 

    Uri newUri = contentResolver.insert(Images.CONTENT_URI, initialValues); 
    String Id = newUri.getPathSegments().get(1); 
    return Long.parseLong(Id); 

} 

Tôi sử dụng nhà cung cấp nội dung cho db của tôi, nhưng đối với những người không chèn mã trông như thế này, bạn có thể sử dụng trực tiếp vào cơ sở dữ liệu của mình mà không cần nhà cung cấp. (Chỉ FYI).

rowId = db.insert(IMAGES_TABLE, null, values); 
Các vấn đề liên quan