Wie speichere ich ein Bild als Blob in Sqlite und wie rufe ich es ab?


74

Ich möchte ein Bild (von der URL) in einer SQLite-Datenbank speichern.

Dafür benutze ich:

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

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

Zum Abrufen von Bildern:

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

Also hier habe ich null.

Und in meiner Datenbank wird der Wert des Bildes gespeichert als: Image=[B@43e5ac48]


Beim Abrufen von DB habe ich nicht genau Byte [] ..... Hilfe bekommen?
Siten

Antworten:


67

Hier der Code, den ich für meine App verwendet habe

Dieser Code nimmt ein Bild von der URL und konvertiert es in ein Byte-Array

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

Um das Bild in db zu speichern, habe ich diesen Code verwendet.

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

Um das Bild wieder abzurufen, ist dies der Code, den ich verwendet habe.

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

Zum Schluss laden Sie dieses Bild in eine Bildansicht

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

insertStmt.bindBlob (3, this.accImage); wird verwendet, um das Bild einzufügen, in dem accImage ein Byte-Array ist, das von der getLogoImage-Methode im ersten Codeblock zurückgegeben wird
blessenm

1
Ich habe null bei Bitmap. Ich habe den Wert von Byte []
Siten

Können Sie das Byte-Array direkt nach der Konvertierung der URL in ein Byte-Array auf eine Bildansicht setzen? Wenn Sie das Bild dann anzeigen können. Dann können wir wissen, dass in den Datenbankoperationen etwas schief läuft. Andernfalls liegt ein Fehler in der Art und Weise vor, wie Sie vom Server auf das Image zugreifen.
Blessenm

1
@blessenm Ich mache so etwas. Aber mit mehr Bildern / Byte-Array in SQLite. Wie kann ich den Bitmap-Speicherfehler vermeiden?
Mari_Yaguchi

Die Cursor-Nullprüfung ist sinnlos: Sie haben sie bereits beim Aufruf von moveToFirst verwendet.
RichieHH

24

Deklarieren Sie in der DBAdaper-Datenbank-Helferklasse die Tabelle wie folgt

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

Fügen Sie die Werte wie folgt ein:

konvertiere zuerst die Bilder als 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);

in der DEAdaper-Klasse

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

Rufen Sie das Bild wie folgt ab

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

Konvertieren Sie das Byte [] in ein Bild

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

Ich denke, dieser Inhalt kann Ihr Problem lösen


Überprüfen Sie zuerst, ob Sie das Byte [] vom Cursor abgerufen haben oder nicht, indem Sie die Variable
imageByteArray.length verwenden

Überprüfen Sie die Länge von Byte [], dh photo.lenght. Wenn der Wert größer als Null ist, erhalten Sie mit Sicherheit die richtige Bitmap. Wenn die Länge Null ist, überprüfen Sie Ihre Abfrage.
Balaji.K

"System.out.println (" >>>>>>>>>> "+ imageByteArray.length);" was es druckt
Balaji.K

warum bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos); ? Was ist mit Ich möchte mein Bild nicht komprimieren?
Mirko


1

In insert ()

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

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

Hoffe es hilft dir.


0

für ein ionisches Projekt

    var imgURI = "";
    var imgBBDD = ""; // sqllite zum Speichern in

    Funktion takepicture () {
                var options = {
                    Qualität: 75,
                    destinationType: Camera.DestinationType.DATA_URL,
                    sourceType: Camera.PictureSourceType.CAMERA,
                    allowEdit: true,
                    encodingType: Camera.EncodingType.JPEG,
                    Zielbreite: 300,
                    Zielhöhe: 300,
                    popoverOptions: CameraPopoverOptions,
                    saveToPhotoAlbum: false
                };

                $ cordovaCamera.getPicture (Optionen) .then (Funktion (imageData) {
                    imgURI = "data: image / jpeg; base64," + imageData;
                    imgBBDD = imageData;
                }, function (err) {
                    // Es ist ein Fehler aufgetreten. Zeigen Sie dem Benutzer eine Nachricht
                });
            }}

Und jetzt setzen wir imgBBDD in SqlLite

     Funktion saveImage = Funktion (theId, theimage) {
      var insertQuery = "INSERT INTO images (id, image) VALUES (" + theId + ", '" + theimage + "');"
      console.log ('>>>>>>>');
      DDBB.SelectQuery (insertQuery)
                    .then (Funktion (Ergebnis) {
                        console.log ("Bild gespeichert");
                    })
                    .catch (Funktion (err) 
                     {
                        deferred.resolve (err);
                        return cb (err);
                    });
    }}

Eine serverseitige (PHP)

        $ request = file_get_contents ("php: // input"); // ruft die Rohdaten ab
        $ dades = json_decode ($ request, true); // true für die Rückgabe als Array


    if ($ dades == "") {
            $ array = array ();
            $ array ['error'] = -1;
            $ array ['descError'] = "Fehler beim Abrufen der Datei";
            $ array ['logError'] = '';
            echo json_encode ($ array);
            Ausfahrt;
        }}
        // Sende das Bild erneut an den Client
        Header ('Inhaltstyp: Bild / JPEG');
        Echo '';


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

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

-1

Möglicherweise möchten Sie auch zu / von base64 codieren und decodieren

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

Es gibt keinen guten Grund, über base64 zu gehen, wenn Sie ein Byte-Array speichern können, da dies nur den erforderlichen Speicherplatz erhöhen würde (und unnötige Zeitcodierung verschwenden würde). Base64-codiert ist kaum lesbar.
Sveinung Kval Bakken
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.