Android 保存圖片到SQLite


[轉:原文]

最近在處理將圖片保存到sqlite數據庫中問題,在網上搜了很久,得出圖片存數據庫中基本以BINARY 或bolb數據類型保存 ,這兩種數據類型保存都可以,相對而言blob要合適一些,因為:


BLOB (binary large object),二進制大對象,是一個可以存儲二進制文件的容器。
在計算機中,BLOB常常是數據庫中用來存儲 二進制文件的字段類型。
BLOB是一個大文件,典型的BLOB是一張圖片或一個聲音文件,由於它們的尺寸,必須使用特殊的方式來處理(例如:上傳、下載或者存放到一個數據庫)。
 
大型對象
BLOB就是使用二進制保存數據。
如:保存位圖。

\SQLite3 支持的數據類型5種:Null,Integer,Real(浮點數),Text,BLOB(二進制對象)


BLOB 是二進制大對象(binary large object)的首字母縮寫,是在 SQL Server 中作為一個單一實體存儲的二進制數據集合。
BLOB 主要用於保存多媒體對象,比如圖像、視頻和聲音,但是它們還可以存儲程序,甚至是代碼片斷。
雖然 SQL Server 支持 BLOB,但不是所有數據都支持。 



Android數據庫中存取圖片通常使用兩種方式,一種是保存圖片所在路徑,二是將圖片以二進制的形式存儲(sqlite3支持BLOB數據類型)。對於兩種方法的使用,好像第二種方法不如第一種方法更受程序員歡迎,他們認為,在很多數據庫語言里,處理大字段都是不容易的,像圖片這樣的文件放在數據庫里會有問題:對數據庫的讀寫速度永遠趕不上文件系統的處理速度,使數據庫變得巨大;但也有很多人認為像圖片這樣的數據存放在數據庫中也有好處:易於備份,且備份速度絕對比備份文件快,比較容易數據遷移等等。其實這兩種方法都有優缺點,具體使用哪種方法要視情況而定。個人傾向於使用數據庫存取圖片,因為個人認為存到數據庫里的數據不會因外部數據的變化而丟失改變,比如你拍照獲得一張圖片,如果是將路徑存到數據庫,當這張照片被刪除之后,下次讀取數據庫就得不到想要的結果了。接下來詳細介紹數據庫存取圖片的方法:

1.從資源中獲取Bitmap對象

1     Resources res = getResources(); 2     Bitmap bmp = BitmapFactory.decodeResource(res, R.drawable.icon);

2.把圖片轉換成字節

public byte[] img(int id)
{
     ByteArrayOutputStream baos = new ByteArrayOutputStream();
     Bitmap bitmap = ((BitmapDrawable) getResources().getDrawable(id)).getBitmap();
     bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
     return baos.toByteArray();
}

3.在數據庫中插入圖片

//在數據庫創建時,圖片字段的數據類型存儲為 BLOB數據庫插入操作
public void onCreate(SQLiteDatabase db)

    String sql = "create table " + TB_NAME + " ( " + ID + " integer primary key , " + IMAGE + " BLOB ) ";
    db.execSQL(sql);



//將圖片一字節形式存儲數據庫讀取操作
public long insert(byte[] img) 

    SQLiteDatabase db = getWritableDatabase();
    ContentValues cv = new ContentValues();
    cv.put(IMAGE, img);
    long result = db.insert(TB_NAME, null, cv);
    return result;
}

4.獲取存入數據庫的圖片(Bitmap)

public Bitmap getBmp(int position) 
{
    SQLiteDatabase db = getReadableDatabase();
    Cursor cursor = select(TB_NAME);
    cursor.moveToPosition(position);
    byte[] in = cursor.getBlob(cursor.getColumnIndex(IMAGE));
    Bitmap bmpout = BitmapFactory.decodeByteArray(in, 0, in.length);
    return bmpout;
}

//imgView.setImageBitmap(bm);

5.轉換獲取的圖片(Bitmap)為Drawable

public Drawable chage_to_drawable(Bitmap bp)
{
    //因為BtimapDrawable是Drawable的子類,最終直接使用bd對象即可。
    Bitmap bm=bp; 
    BitmapDrawable bd= new BitmapDrawable(getResource(), bm); 
    return bd;
}

1、bitmap保存到SQLite 中 數據格式:    

Java代碼   收藏代碼
  1. db.execSQL("Create table express ( _id INTEGER PRIMARY KEY AUTOINCREMENT,express_no varchar(100),express_name TEXT,express_img BLOB );");  

 

2、bitmap 變為 Blob   

Java代碼   收藏代碼
  1. ContentValues values = new ContentValues();  
  2. final ByteArrayOutputStream os = new ByteArrayOutputStream();   
  3. bmp.compress(Bitmap.CompressFormat.PNG, 100, os);    
  4. values.put("express_img", os.toByteArray());  
  5. values.put("express_name","zf");  
  6. values.put("express_no","zf");  
  7. getContentResolver().insert("express", values);  

 

 3、從SQLite中讀取Bitmap    

Java代碼   收藏代碼
  1. byte[] in=cur.getBlob(cur.getColumnIndex("express_img"));  
  2. bmpout=BitmapFactory.decodeByteArray(in,0,in.length);  

 顯示在ImageView上

Java代碼   收藏代碼
  1. ImageView imageView = (ImageView) view.findViewById(R.id.img);   
  2. ByteArrayInputStream stream = new ByteArrayInputStream(cur.getBlob(cur.getColumnIndex("express_img")));   
  3. imageView.setImageDrawable(Drawable.createFromStream(stream, "img"));   

 

總結:

inputStream:  作為數據緩存,數據寫如何供別的對象讀取,其方法為read();

outputStream:作為數據緩存,將來向別的對象寫內容!其方法write();

Java代碼   收藏代碼
  1. byte[] in=cur.getBlob(cur.getColumnIndex(MyUser.User.BITMAP_VALUES));  

 //這樣也可以對數據進行初始化,byte是基本類型,不需要之前進行長度定義。






一般只保存圖片的路徑,沒有直接把圖片保存進去,我以前也有試過想放圖片到SQlite數據庫,后來圖片才放幾張就不能放了。 sqlite數據庫到達一定大的情況下就不能往里面加數據
比如說你把image.jpg放在sdcard的images目錄下,那你就在數據庫存/sdcard/images/image.jpg   ( 我是直接存圖片名字,然后調用的時候再補上圖片的路徑!代碼如下private String MUSIC_PATH = new String("/sdcard/feiyang/voice/"); 然后根據需要寫上所要的圖片名稱。

使用SQLite數據庫中的blob類型來存儲,可以參考下面兩個網址: 如何使用blob類型存儲mp3文件:http://doc.chinaunix.net/android/200903/164048.shtml android操作sqlite3的blob字段:http://marshal.easymorse.com/archives/2342

1、bitmap保存到SQLite 中 數據格式:

     db.execSQL("Create table " + TABLE_NAME + "( _id INTEGER PRIMARY KEY AUTOINCREMENT,USER_AGE  INTEGER,USER_NAME TEXT,BITMAP_VALUES BLOB );");

2、bitmap 變為 Blob

    ContentValues values = new ContentValues();

    final ByteArrayOutputStream os = new ByteArrayOutputStream(); 

    bmp.compress(Bitmap.CompressFormat.PNG, 100, os);  

    values.put(MyUser.User.BITMAP_VALUES, os.toByteArray());

    values.put(MyUser.User.USER_NAME,"icon");

    values.put(MyUser.User.USER_AGE,50);

    getContentResolver().insert(MyUser.User.CONTENT_URI, values);

3、從SQLite中讀取Bitmap

     byte[] in=cur.getBlob(cur.getColumnIndex(MyUser.User.BITMAP_VALUES));

     bmpout=BitmapFactory.decodeByteArray(in,0,in.length);

總結:

inputStream:  作為數據緩存,數據寫如何供別的對象讀取,其方法為read();

outputStream:作為數據緩存,將來向別的對象寫內容!其方法write();

byte[] in=cur.getBlob(cur.getColumnIndex(MyUser.User.BITMAP_VALUES));//這樣也可以對數據進行初始化,byte是基本類型,不需要之前進行長度定義



存儲圖片:bitmap

Java代碼   收藏代碼
  1. private byte[] getIconData(Bitmap bitmap){  
  2.   
  3. int size = bitmap.getWidth()*bitmap.getHeight()*4;  
  4.   
  5. ByteArrayOutputStream out = new ByteArrayOutputStream(size);  
  6.   
  7. try {  
  8.   
  9. bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);  
  10.   
  11. out.close();  
  12.   
  13. catch (IOException e) {  
  14.   
  15. e.printStackTrace();  
  16.   
  17. }  
  18.   
  19. return out.toByteArray();  
  20.   
  21. }  

獲取圖片:

Java代碼   收藏代碼
  1. Bitmap getIconFromCursor(Cursor c, int iconIndex) {  
  2.   
  3.         byte[] data = c.getBlob(iconIndex);  
  4.   
  5.         try {  
  6.   
  7.             return BitmapFactory.decodeByteArray(data, 0, data.length);  
  8.   
  9.         } catch (Exception e) {  
  10.   
  11.             return null;  
  12.   
  13.         }  
  14.   
  15.     }  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM