2010-08-20 3 views
5

Я кэширую файлы изображений как blob в базе данных SQLite. У меня есть аналогичное приложение на другой платформе, которое делает то же самое с теми же файлами изображений. Базы данных на обеих платформах сообщают о том же размере для тех же изображений. Поэтому я думаю, но не могу гарантировать, что данные изображения попадают в базу данных без изменений.Проблема с созданием Drawable из SQLite Blob

Но когда я пытаюсь создать Drawable, консоль печатает «DEBUG/skia (267): --- decoder-> decode false false».

Шаги:

  1. прочитать двоичный объект в массив байтов.

    байт [] b = новый байт [изображениеDataCursor.getInt (0)];

    b = imageDataCursor.getBlob (1);

  2. Создайте InputStream из массива байтов.

    ByteArrayInputStream = новый ByteArrayInputStream (b);

  3. Создайте Drawable из InputStream. (это то, что создает сообщение «декодера» выше)

    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 помог мне. Вот мой код, который загружает изображения (PNG и JPG) из Facebook, а затем сохраняет/извлекает данные из таблицы 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; 
} 

My writeImage выглядит так (см. Ниже).

Images.IMAGE ссылается на имя столбца BLOB в моей таблице. Главное, что вы действительно можете написать байт [] непосредственно в столбце BLOB базы данных. Я пишу время (utc), поэтому я могу очистить старые данные в соответствии с политиками api в Facebook для кэширования данных.

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

} 

Я использую поставщик контента для моей БД, но и для тех, кто не код вставки выглядит так, что вы можете использовать непосредственно в базу данных без поставщика. (Только FYI).

rowId = db.insert(IMAGES_TABLE, null, values); 
Смежные вопросы