2010-08-20 90 views
5

我將圖像文件作爲blob存儲在SQLite數據庫中。我在另一個平臺上有類似的應用程序,它使用相同的圖像文件做同樣的事情。兩個平臺上的數據庫報告相同圖像的大小完全相同。所以我認爲,但不能保證圖像數據完好無損地進入數據庫。從SQLite Blob創建繪圖的問題

但是,當我嘗試創建一個Drawable時,控制檯打印出「DEBUG/skia(267):--- decoder-> decode returned false」。

的步驟是:

  1. 閱讀團塊到字節數組。

    byte [] b = new byte [imageDataCursor.getInt(0)];

    b = imageDataCursor.getBlob(1);

  2. 從字節數組中創建一個InputStream。

    ByteArrayInputStream is = new ByteArrayInputStream(b);

  3. 從InputStream創建Drawable。 (這是上面創建'解碼器'消息的原因)

    Drawable drw = Drawable.createFromStream(is,「articleImage」);

  4. 將ImageView.image設置爲Drawable。

    imgView.setImageDrawable(drw);

到目前爲止,沒有快樂。有什麼建議麼?

回答

1

我會發布我的解決方案,以幫助任何有類似問題的人。

我試着測試我正在從數據庫讀取的字節數組,通過將它寫入文件然後查看文件。事實證明,數據庫中的blob數據不完整 - 我得到了幾行圖像,但不是整個圖像。

該解決方案涉及創建一個BufferedInputStream和一個ByteArrayBuffer從遠程服務器讀取圖像。該代碼捕獲從遠程服務器上的圖像文件,並創建一個字節數組,能夠將其寫入到一個SQLite數據庫看起來是這樣的:

   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

我身邊追逐我的尾巴在這個相當長的一段時間。 deSelby的回答幫助了我。這是我從Facebook下載圖像(PNG和JPG)的代碼,然後使用該路徑作爲參考,從sqlite表中存儲/檢索數據。你可以看到,它實際上首先嚐試從表中讀取圖像,如果它在那裏只是返回它,否則它從Facebook獲取它,將它存儲在數據庫中,然後返回它。

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; 
} 

我writeImage看起來像這樣(見下文)。

Images.IMAGE引用我表中的BLOB列的名稱。 這裏的要點是,您可以直接將byte []寫入數據庫BLOB列。 我寫的時間(utc),所以我可以根據Facebook api策略緩存數據清除舊數據。

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); 

} 

我使用的是內容供應商對於我的數據庫,但對於那些誰不插入代碼看起來是這樣,你可以直接使用到數據庫沒有一個供應商。 (僅供參考)。

rowId = db.insert(IMAGES_TABLE, null, values);