як зберігати зображення як BLOB в Sqlite і як його отримати?


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]


при отриманні db я отримав не зовсім байт [] ..... будь-яка допомога?
Сітен

Відповіді:


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;
}

Для збереження зображення в db я використав цей код.

 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;
    }
}

Нарешті, щоб завантажити це зображення до перегляду зображень

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

insertStmt.bindBlob (3, this.accImage); використовується для вставки зображення, де accImage - це байтовий масив, повернутий із методу getLogoImage, у перший блок коду
blessenm

1
я отримав нульове значення в растровому зображенні. я отримав значення байта []
Сітен,

Чи можете ви встановити байтовий масив для перегляду зображення відразу після перетворення URL-адреси в байтовий масив. Якщо ви можете переглянути зображення, тоді. Тоді ми можемо знати, що в db-операціях щось йде не так. В іншому випадку це помилка у способі доступу до зображення із сервера.
blessenm

1
@blessenm Я роблю щось подібне. Але з більшою кількістю зображень / байтового масиву в sqlite .. Як я можу уникнути растрової помилки, що втрачає пам’ять?
Mari_Yaguchi

Нульова перевірка курсору безглузда: ви вже використовували його з викликом moveToFirst.
RichieHH

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);";

вставити такі значення,

спочатку перетворити зображення у байти []

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);
}

перетворити байт [] у зображення

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

Я думаю, що цей вміст може вирішити вашу проблему


спочатку перевірте, чи ви отримали байт [] з курсору чи ні, використовуючи змінну
imageByteArray.length

перевірити довжину байта [], тобто фото.довжина. Якщо значення більше нуля, то, безумовно, ви отримаєте правильний растровий малюнок. Якщо довжина дорівнює нулю, перевірте запит ur.
Balaji.K

"System.out.println (" >>>>>>>>>>> "+ imageByteArray.length);" що друкує
Balaji.K

чому bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos); ?? А як щодо того, що я не хочу стискати своє зображення?
Мірко

знайшов свою відповідь тут stackoverflow.com/questions/10191871/…
Мірко

1

Вставте ()

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

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

Сподіваюся, це допоможе вам.


0

для іонного проекту

    var imgURI = "";
    var imgBBDD = ""; // sqllite для збереження в

    функція takepicture () {
                варіанти змінної = {
                    якість: 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 = "дані: image / jpeg; base64," + imageData;
                    imgBBDD = imageData;
                }, функція (помилка) {
                    // Сталася помилка. Показати повідомлення користувачеві
                });
            }

А тепер ми помістили imgBBDD в SqlLite

     function saveImage = function (theId, theimage) {
      var insertQuery = "ВСТАВИТИ В ЗОБРАЖЕННЯ (id, image) VALUES (" + theId + ", '" + theimage + "');"
      console.log ('>>>>>>>');
      DDBB.SelectQuery (insertQuery)
                    . then (функція (результат) {
                        console.log ("Зображення збережено");
                    })
                    .catch (функція (помилка) 
                     {
                        deferred.resolve (err);
                        повернути cb (помилка);
                    });
    }

Сторона сервера (php)

        $ request = file_get_contents ("php: // input"); // отримує вихідні дані
        $ dades = json_decode ($ request, true); // істина для повернення як масиву


    if ($ dades == "") {
            $ масив = масив ();
            $ array ['error'] = -1;
            $ array ['descError'] = "Помилка при отриманні файлу";
            $ array ['logError'] = '';
            echo json_encode (масив $);
            вихід;
        }
        // відправити зображення знову клієнту
        заголовок ('Тип вмісту: 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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.