如何将图像存储为Sqlite中的Blob和如何检索它?


75

我想将图像(来自URL)存储到sqlite数据库中。

为此,我使用:

db = new DataBase(getApplicationContext());
URL url = new URL("http://sree.cc/wp-content/uploads/schogini_team.png");
URLConnection ucon = url.openConnection();
InputStream is = ucon.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is,128);
ByteArrayBuffer barb= new ByteArrayBuffer(128);

int current = 0;
while ((current = bis.read()) != -1) {
    barb.append((byte) current);
}

ContentValues filedata= new ContentValues();

filedata.put(DataBase.IMG_SRC,barb.toByteArray());

db.insert(DataBase.Table_Img, null, filedata);

Insert()

public void insert(String tableImg, Object object,
        ContentValues dataToInsert) {
    // TODO Auto-generated method stub
    String sql = "INSERT INTO "+tableImg+" ("+ID+","+IMG_SRC+") " +
            "VALUES ('"+1+"','"+dataToInsert+"')";
    db.execSQL(sql);
}

对于图像检索:

Cursor cursor = db.selectDataToShow(DataBase.Table_Img, DataBase.IMG_SRC);

byte[] imageByteArray=cursor.getBlob(cursor.getColumnIndex(DataBase.IMG_SRC));      
cursor.close();

ByteArrayInputStream imageStream = new ByteArrayInputStream(imageByteArray);
Bitmap theImage = BitmapFactory.decodeStream(imageStream);

System.out.println(">>>>>>>>>>>>>>>>>>>>>> "+theImage);

所以我到了null

在我的数据库中,图像的值存储为: Image=[B@43e5ac48]


在获取数据库时,我不完全是byte [] .....有什么帮助吗?
Siten 2011年

Answers:


68

这是我用于我的应用程序的代码

此代码将从url获取图像并将其转换为字节数组

byte[] logoImage = getLogoImage(IMAGEURL);

private byte[] getLogoImage(String url){
     try {
             URL imageUrl = new URL(url);
             URLConnection ucon = imageUrl.openConnection();

             InputStream is = ucon.getInputStream();
             BufferedInputStream bis = new BufferedInputStream(is);

             ByteArrayBuffer baf = new ByteArrayBuffer(500);
             int current = 0;
             while ((current = bis.read()) != -1) {
                  baf.append((byte) current);
             }

             return baf.toByteArray();
     } catch (Exception e) {
          Log.d("ImageManager", "Error: " + e.toString());
     }
     return null;
}

要将图像保存到数据库,我使用了此代码。

 public void insertUser(){
        SQLiteDatabase db = dbHelper.getWritableDatabase();
        String delSql = "DELETE FROM ACCOUNTS";
        SQLiteStatement delStmt = db.compileStatement(delSql);
        delStmt.execute();

        String sql = "INSERT INTO ACCOUNTS (account_id,account_name,account_image) VALUES(?,?,?)";
        SQLiteStatement insertStmt = db.compileStatement(sql);
        insertStmt.clearBindings();
        insertStmt.bindString(1, Integer.toString(this.accId));
        insertStmt.bindString(2,this.accName);
        insertStmt.bindBlob(3, this.accImage);
        insertStmt.executeInsert();
        db.close();
}

为了找回图像,这是我使用的代码。

public Account getCurrentAccount() {
    SQLiteDatabase db = dbHelper.getWritableDatabase();
    String sql = "SELECT * FROM ACCOUNTS";
    Cursor cursor = db.rawQuery(sql, new String[] {});

    if(cursor.moveToFirst()){
        this.accId  = cursor.getInt(0);
        this.accName = cursor.getString(1);
        this.accImage = cursor.getBlob(2);
    }
    if (cursor != null && !cursor.isClosed()) {
        cursor.close();
    }
    db.close();
    if(cursor.getCount() == 0){
        return null;
    } else {
        return this;
    }
}

最后将此图像加载到imageview

logoImage.setImageBitmap(BitmapFactory.decodeByteArray( currentAccount.accImage, 
        0,currentAccount.accImage.length));

insertStmt.bindBlob(3,this.accImage); 用于在第一个代码块中插入图像,其中accImage是从getLogoImage方法返回的字节数组
blessenm 2011年

1
我在位图上为空。我得到了byte []的值
Siten 2011年

将网址转换为字节数组后,是否可以将字节数组设置为图像视图?如果您能够查看图像,那么。然后我们可以知道db操作中正在发生某些事情。否则,这是您从服务器访问映像的方式中的错误。
blessenm 2011年

1
@blessenm我正在做这样的事情。但是在sqlite中有更多图片/字节数组。.如何避免位图出现内存不足错误?
Mari_Yaguchi 2014年

游标null检查是毫无意义的:您已经在moveToFirst调用中使用了它。
RichieHH 2014年

24

在DBAdaper中,即数据库帮助程序类中,声明表是这样的

 private static final String USERDETAILS=
    "create table userdetails(usersno integer primary key autoincrement,userid text not null ,username text not null,password text not null,photo BLOB,visibility text not null);";

插入这样的值,

首先将图像转换为byte []

ByteArrayOutputStream baos = new ByteArrayOutputStream();  
Bitmap bitmap = ((BitmapDrawable)getResources().getDrawable(R.drawable.common)).getBitmap();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);   
byte[] photo = baos.toByteArray(); 
db.insertUserDetails(value1,value2, value3, photo,value2);

在DEadaper类中

 public long insertUserDetails(String uname,String userid, String pass, byte[] photo,String visibility) 
{
    ContentValues initialValues = new ContentValues();
    initialValues.put("username", uname);
    initialValues.put("userid",userid);
    initialValues.put("password", pass);
    initialValues.put("photo",photo);
    initialValues.put("visibility",visibility);
    return db.insert("userdetails", null, initialValues);
}

检索图像如下

Cursor cur=your query;
while(cur.moveToNext())
{
     byte[] photo=cur.getBlob(index of blob cloumn);
}

将byte []转换为图像

ByteArrayInputStream imageStream = new ByteArrayInputStream(photo);
Bitmap theImage= BitmapFactory.decodeStream(imageStream);

我认为此内容可能会解决您的问题


首先使用imageByteArray.length变量检查是否从游标中检索了byte []
Balaji.K 2011年

检查byte []的长度,即photo.lenght。如果该值大于零,那么您肯定会获得正确的位图。如果长度为零,则检查您的查询。
Balaji.K 2011年

“ System.out.println(” >>>>>>>>>>>“ + imageByteArray.length);” 它打印的内容
Balaji.K 2011年

为什么bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos); ?? 我不想压缩图像怎么办?
Mirko 2012年


1

在insert()中

public void insert(String tableImg, Object object,
        ContentValues dataToInsert) {

   db.insert(tablename, null, dataToInsert);
}

希望对您有帮助。


0

用于离子项目

    var imgURI =“”;
    var imgBBDD =“”; // sqllite保存到

    函数takepicture(){
                var options = {
                    质量:75,
                    destinationType:Camera.DestinationType.DATA_URL,
                    sourceType:Camera.PictureSourceType.CAMERA,
                    allowEdit:true,
                    encodingType:Camera.EncodingType.JPEG,
                    targetWidth:300,
                    targetHeight:300,
                    popoverOptions:CameraPopoverOptions,
                    saveToPhotoAlbum:否
                };

                $ cordovaCamera.getPicture(options).then(function(imageData){
                    imgURI =“ data:image / jpeg; base64,” + imageData;
                    imgBBDD = imageData;
                },函数(错误){
                    // 发生错误。向用户显示消息
                });
            }

现在我们将imgBBDD放入SqlLite

     函数saveImage =函数(theId,theimage){
      var insertQuery =“将图像插入图像(id,图像)VALUES(” + theId +“,'” + theimage +“');”
      console.log('>>>>>>>');
      DDBB.SelectQuery(insertQuery)
                    .then(function(result){
                        console.log(“已保存图片”);
                    })
                    .catch(函数(错误) 
                     {
                        deferred.resolve(err);
                        返回cb(err);
                    });
    }

服务器端(php)

        $ request = file_get_contents(“ php:// input”); //获取原始数据
        $ dades = json_decode($ request,true); //返回为数组时为true


    if($ dades ==“”){
            $ array = array();
            $ array ['error'] = -1;
            $ array ['descError'] =“获取文件时出错”;
            $ array ['logError'] ='';
            回声json_encode($ array);
            出口;
        }
        //再次将图片发送给客户端
        header('Content-Type:image / jpeg');
        回声'';


0
byte[] byteArray = rs.getBytes("columnname");  

Bitmap bm = BitmapFactory.decodeByteArray(byteArray, 0 ,byteArray.length);

-1

您可能还想对base64进行编码和解码

    function uncompress(str:String):ByteArray {
            import mx.utils.Base64Decoder;
            var dec:Base64Decoder = new Base64Decoder();
            dec.decode(str);
            var newByteArr:ByteArray=dec.toByteArray();        
            return newByteArr;
        }


    // Compress a ByteArray into a Base64 String.
    function compress(bytes:ByteArray):String { 
        import mx.utils.Base64Decoder; //Transform String in a ByteArray.
        import mx.utils.Base64Encoder; //Transform ByteArray in a readable string.
        var enc:Base64Encoder = new Base64Encoder();    
        enc.encodeBytes(bytes);
        return enc.drain().split("\n").join("");
    }

当您可以存储字节数组时,没有充分的理由使用base64,因为这只会增加所需的存储(并浪费不必要的时间编码)。编码的Base64几乎不可读。
Sveinung Kval Bakken
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.