2013-07-03 120 views
0

您好每個身體我堅持一個問題,如何保存圖像在我們的SQLite數據庫。圖像駐留在特定的網址,例如http://images.201bestbuy.com/images/small_137385013870957.jpg從服務器URL保存圖像在SQLite數據庫中

現在我想從這個URL保存圖像在我的sqlit數據庫沒有用戶交互。爲了解決這個問題,我用

public class ImageLoader { 

    MemoryCache memoryCache = new MemoryCache(); 
    FileCache fileCache; 
    private Map<ImageView, String> imageViews = Collections 
     .synchronizedMap(new WeakHashMap<ImageView, String>()); 
    ExecutorService executorService; 

    public ImageLoader(Context context) { 
     fileCache = new FileCache(context); 
     executorService = Executors.newFixedThreadPool(5); 
    } 

    final int stub_id = R.drawable.no_image; 

    public void DisplayImage(String url, ImageView imageView) { 
     imageViews.put(imageView, url); 
     Bitmap bitmap = memoryCache.get(url); 
     if (bitmap != null){ 
      imageView.setImageBitmap(bitmap); 
     } 
     else { 
      queuePhoto(url, imageView); 
      imageView.setImageResource(stub_id); 
     } 
    } 

    private void queuePhoto(String url, ImageView imageView) { 
     PhotoToLoad p = new PhotoToLoad(url, imageView); 
     executorService.submit(new PhotosLoader(p)); 
    } 

    private Bitmap getBitmap(String url) { 
     File f = fileCache.getFile(url); 

     // from SD cache 
     Bitmap b = decodeFile(f); 
     if (b != null) 
      return b; 

     // from web 
     try { 
      Bitmap bitmap = null; 
      URL imageUrl = new URL(url); 
      HttpURLConnection conn = (HttpURLConnection) imageUrl 
       .openConnection(); 
      conn.setConnectTimeout(30000); 
      conn.setReadTimeout(30000); 
      conn.setInstanceFollowRedirects(true); 
      InputStream is = conn.getInputStream(); 
      OutputStream os = new FileOutputStream(f); 
      Utils.CopyStream(is, os); 
      os.close(); 
      bitmap = decodeFile(f); 

      return bitmap; 
     } catch (Exception ex) { 
      ex.printStackTrace(); 
      return null; 
     } 
    } 

    // decodes image and scales it to reduce memory consumption 
    private Bitmap decodeFile(File f) { 
     try { 
      // decode image size 
      BitmapFactory.Options o = new BitmapFactory.Options(); 
      o.inJustDecodeBounds = true; 
      BitmapFactory.decodeStream(new FileInputStream(f), null, o); 
      // Find the correct scale value. It should be the power of 2. 
      final int REQUIRED_SIZE = 70; 
      int width_tmp = o.outWidth, height_tmp = o.outHeight; 
      int scale = 1; 
      while (true) { 
       if (width_tmp/2 < REQUIRED_SIZE 
        || height_tmp/2 < REQUIRED_SIZE) 
        break; 
       width_tmp /= 2; 
       height_tmp /= 2; 
       scale *= 2; 
      } 

      // decode with inSampleSize 
      BitmapFactory.Options o2 = new BitmapFactory.Options(); 
      o2.inSampleSize = scale; 
      return BitmapFactory.decodeStream(new FileInputStream(f), null, o2); 
     } catch (FileNotFoundException e) { 
    } 
    return null; 
} 

// Task for the queue 
private class PhotoToLoad { 
    public String url; 
    public ImageView imageView; 

    public PhotoToLoad(String u, ImageView i) { 
     url = u; 
     imageView = i; 
    } 
} 

class PhotosLoader implements Runnable { 
    PhotoToLoad photoToLoad; 

    PhotosLoader(PhotoToLoad photoToLoad) { 
     this.photoToLoad = photoToLoad; 
    } 

    @Override 
    public void run() { 
     if (imageViewReused(photoToLoad)) 
      return; 
     Bitmap bmp = getBitmap(photoToLoad.url); 
     memoryCache.put(photoToLoad.url, bmp); 
     if (imageViewReused(photoToLoad)) 
      return; 
     BitmapDisplayer bd = new BitmapDisplayer(bmp, photoToLoad); 
     Activity a = (Activity) photoToLoad.imageView.getContext(); 
     a.runOnUiThread(bd); 
    } 
} 

boolean imageViewReused(PhotoToLoad photoToLoad) { 
    String tag = imageViews.get(photoToLoad.imageView); 
    if (tag == null || !tag.equals(photoToLoad.url)) 
     return true; 
    return false; 
} 

// Used to display bitmap in the UI thread 
class BitmapDisplayer implements Runnable { 
    Bitmap bitmap; 
    PhotoToLoad photoToLoad; 

    public BitmapDisplayer(Bitmap b, PhotoToLoad p) { 
     bitmap = b; 
     photoToLoad = p; 
    } 

    public void run() { 
     if (imageViewReused(photoToLoad)) 
      return; 
     if (bitmap != null){ 
      photoToLoad.imageView.setImageBitmap(bitmap); 

     } 
     else 
      photoToLoad.imageView.setImageResource(stub_id); 
    } 
} 

public void clearCache() { 
    memoryCache.clear(); 
    fileCache.clear(); 
} 

}

現在問題是,當我使用

ContentValues userdetailValues = new ContentValues(); 
    userdetailValues.put("Key_ProductImage",imageView.setImageBitmap(bitmap)); 

當我使用這些代碼在SQLite數據庫保存圖像。它爲我顯示了一個錯誤。 Put()方法將兩個參數都視爲字符串,但setImageBitmap(bitmap)的返回類型爲void。如果我的方法完全錯誤,那麼請建議我解決此問題的正確方法。

+1

建議您將網址插入數據庫而不是圖片,因爲圖片會佔用更多空間。 – Raghunandan

+0

是的..我知道,但在我的應用程序,我已經做了這些事情 – DJhon

回答

1

將圖像放入數據庫是一種糟糕的做事方式 - 您膨脹數據庫並從中獲取數據,然後需要將數據轉換爲正確的格式。相反,將其存儲到磁盤並將其存儲在數據庫中的文件名。然後從磁盤加載它。

+0

我想他是懶加載圖像。我同意iamges可以緩存在SD卡上,並且可以將圖像的路徑存儲在數據庫中。 – Raghunandan

+0

@gabe ..感謝您的回覆 – DJhon

2

我覺得這是存儲圖像的不好方法,但提供了將圖像存儲到數據庫的答案。

您可以使用下面的代碼

public static byte[] getBytes(Bitmap bitmap) 
{ 
    ByteArrayOutputStream stream=new ByteArrayOutputStream(); 
    bitmap.compress(CompressFormat.JPEG,0, stream); 
    return stream.toByteArray(); 
} 

圖像位圖轉換爲字節,你可以按照如下插入到數據庫BLOB數據:

ContentValues cv=new ContentValues(); 
cv.put(data, image); 
return db.insert(TABLE_NAME, null, cv); 

這裏的圖像數據是BLOB類型插入時。

+0

感謝您的快速回復。遐我知道在數據庫中保存圖像不是很好的做法。但我必須在我的應用程序中做。我正在使用上面的代碼,但不適合我。 – DJhon

+1

在創建sqlite表格時,請確保您的圖像數據圖像類型爲BOLB。 –

相關問題