[转:原文]

最近在处理将图片保存到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. int size = bitmap.getWidth()*bitmap.getHeight()*4;
  3. ByteArrayOutputStream out = new ByteArrayOutputStream(size);
  4. try {
  5. bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
  6. out.close();
  7. } catch (IOException e) {
  8. e.printStackTrace();
  9. }
  10. return out.toByteArray();
  11. }

获取图片:

Java代码  
  1. Bitmap getIconFromCursor(Cursor c, int iconIndex) {
  2. byte[] data = c.getBlob(iconIndex);
  3. try {
  4. return BitmapFactory.decodeByteArray(data, 0, data.length);
  5. } catch (Exception e) {
  6. return null;
  7. }
  8. }

Android 保存图片到SQLite的更多相关文章

  1. Android 保存图片到SQLite,读出SQLite中的图片

    1.bitmap保存到SQLite 中 数据格式: db.execSQL("Create table express ( _id INTEGER PRIMARY KEY AUTOINCREM ...

  2. 七、Android学习第六天——SQLite与文件下载(转)

    (转自:http://wenku.baidu.com/view/af39b3164431b90d6c85c72f.html) 七.Android学习第六天——SQLite与文件下载 SQLite SQ ...

  3. [Android新手区] SQLite 操作详解--SQL语法

    该文章完全摘自转自:北大青鸟[Android新手区] SQLite 操作详解--SQL语法  :http://home.bdqn.cn/thread-49363-1-1.html SQLite库可以解 ...

  4. Android版本升级同时Sqlite数据库的升级及之前数据的保留

    http://www.cnblogs.com/wang340/archive/2013/05/06/3063135.html http://www.eoeandroid.com/forum.php?m ...

  5. Android中的SQLite使用学习

    Android中的SQLite使用学习 SQLite是非常流行的嵌入式关系型数据库,轻载, 速度快,而且是开源.在Android中,runtime提供SQLite,所以我们可以使用SQLite,而且是 ...

  6. Android开发之SQLite的使用方法

    前言 SQLite是一种轻量级的小型数据库,虽然比较小,但是功能相对比较完善,一些常见的数据库基本功能也具有,在现在的嵌入式系统中使用该数据库的比较多,因为它占用系统资源很少.Android系统中也不 ...

  7. Android数据库之SQLite数据库

    Android数据库之SQLite数据库 导出查看数据库文件 在android中,为某个应用程序创建的数据库,只有它可以访问,其它应用程序是不能访问的,数据库位于Android设备/data/data ...

  8. Android中使用sqlite笔记

    1.实现SQLiteHelper来在android中使用SQLite.代码如下,来自android官网. public class FeedReaderDbHelper extends SQLiteO ...

  9. Android开发之Sqlite的使用

    在Android中存储数据可以用文件.数据库.网络,其中文件和数据库是最常用的,数据库我们常用的就是Sqlite,它是一种经量级的.嵌入式的关系型数据库:在android中当需要操作SQLite数据库 ...

随机推荐

  1. IIS相关知识

    1.在web.config中,iis6使用<system.web>下配置项,iis7使用<system.webServer>下配置项 2.<httpHandlers> ...

  2. 用DateTime的ParseExact方法解析特殊的日期时间

    今天遇到一个特别的需求,需要从下面的字符串中转换成一个DateTime对象: [07-13 15:50:42] 主要问题是这个时间不是标准的时间,而是自定义的格式,即开头是月-日,然后是时间. 使用最 ...

  3. 我常用的grep命令

    查找包含某个字符的行并保存在文件 grep -rn 'test' ./*.sql >test.sql -r 是递归查找 -n 是显示行号 在当前目录下的.sql结尾的文件中查找包含 test 字 ...

  4. Delete,Update与LEFT Join

    UPDATE:UPDATE A SET ApproverID=NULL FROM [SH_MaterialApplyBuyBill] A LEFT JOIN [SH_MaterialApplyBuyB ...

  5. ACM/ICPC 之 Dinic算法(POJ2112)

    Optimal Milking //二分枚举最大距离的最小值+Floyd找到最短路+Dinic算法 //参考图论算法书,并对BFS构建层次网络算法进行改进 //Time:157Ms Memory:65 ...

  6. java学习笔记

    最近在学习JAVA,算得上入门,因为本身是C#程序员,所以也入门也比较快 先打开说一下环境安装吧 下载地址 http://www.oracle.com/technetwork/java/javase/ ...

  7. Nginx与Apache的比较

    Nginx与Apache的比较 Nginx相对于Apache的优点 轻量级.同样起web服务,比apache占用更少的资源和内存 抗并发.nginx处理请求是异步非阻塞,而apache则是阻塞型.在高 ...

  8. hdu 2594 Simpsons’ Hidden Talents

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2594 思路:将两个串连起来求一遍Next数组就行长度为两者之和,遍历时注意长度应该小于两个串中的最小值 ...

  9. RISC指令集的五个周期

    RISC指令集的五个周期 RISC(reduced instruction set computer,精简指令集计算机)简称为精简指令集.RISC把执行指令的精力主要放在了经常使用的指令上面.本文主要 ...

  10. 11g新特性-dba_users安全性的一些增强

    1.dba_user表的password(除了GLOBAL和EXTERNAL的密码)不再保存密码. 查询10g的dba_user表 SQL> select username,password f ...