[轉:原文]
最近在處理將圖片保存到sqlite數據庫中問題,在網上搜了很久,得出圖片存數據庫中基本以BINARY 或bolb數據類型保存 ,這兩種數據類型保存都可以,相對而言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 中 數據格式:
- db.execSQL("Create table express ( _id INTEGER PRIMARY KEY AUTOINCREMENT,express_no varchar(100),express_name TEXT,express_img BLOB );");
2、bitmap 變為 Blob
- ContentValues values = new ContentValues();
- final ByteArrayOutputStream os = new ByteArrayOutputStream();
- bmp.compress(Bitmap.CompressFormat.PNG, 100, os);
- values.put("express_img", os.toByteArray());
- values.put("express_name","zf");
- values.put("express_no","zf");
- getContentResolver().insert("express", values);
3、從SQLite中讀取Bitmap
- byte[] in=cur.getBlob(cur.getColumnIndex("express_img"));
- bmpout=BitmapFactory.decodeByteArray(in,0,in.length);
顯示在ImageView上
- ImageView imageView = (ImageView) view.findViewById(R.id.img);
- ByteArrayInputStream stream = new ByteArrayInputStream(cur.getBlob(cur.getColumnIndex("express_img")));
- imageView.setImageDrawable(Drawable.createFromStream(stream, "img"));
總結:
inputStream: 作為數據緩存,數據寫如何供別的對象讀取,其方法為read();
outputStream:作為數據緩存,將來向別的對象寫內容!其方法write();
//這樣也可以對數據進行初始化,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
- private byte[] getIconData(Bitmap bitmap){
- int size = bitmap.getWidth()*bitmap.getHeight()*4;
- ByteArrayOutputStream out = new ByteArrayOutputStream(size);
- try {
- bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
- out.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- return out.toByteArray();
- }
獲取圖片:
- Bitmap getIconFromCursor(Cursor c, int iconIndex) {
- byte[] data = c.getBlob(iconIndex);
- try {
- return BitmapFactory.decodeByteArray(data, 0, data.length);
- } catch (Exception e) {
- return null;
- }
- }