2010-08-20 94 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);