Wie füge ich ein Bild in die Raumpersistenzbibliothek ein?
Lesezeit: 6 Minuten
Ich verwende die Raumpersistenzbibliothek für meine Android-Anwendung. Jetzt muss ich ein Bild in meine Datenbank einfügen. Ich definiere erfolgreich @Entity für den primitiven Datentyp. und auch durch die Konverterklasse habe ich alle Objekte, Datum und Uhrzeit gespeichert. Jetzt muss ich Image speichern. Ich kann nicht verstehen, wie wir Spalteninformationen und Entitäten definieren und wie wir diese Daten einfügen und Daten aus der Tabelle lesen.
Was ist die maximale Größe der Daten, die in die einzelne Zeile eingefügt werden? Was ist die maximale und minimale Größe von Daten in einem Feld in Android SQLite?
Sie können Blob verwenden, um Bilder in Room zu speichern.
@CommonsWare Was schlagen Sie vor, wenn Sie nicht empfehlen, Bilder in der Datenbank zu speichern? Bilder im externen Speicher speichern?
– Aniruddha
21. Februar 2018 um 19:36 Uhr
@Aniruddha: Ob Sie verwenden interne Speicher oder externer Speicher hängt davon ab, ob der Benutzer unabhängigen Zugriff auf die Bilder benötigt.
– CommonsWare
21. Februar 2018 um 19:50 Uhr
@CommonsWare Wäre für Lernzwecke am besten, wenn Sie erklären könnten, warum Sie nicht empfehlen, das Bild in der Datenbank zu speichern.
– Aniruddha
22. Februar 2018 um 5:10 Uhr
Es wird normalerweise nicht empfohlen, Bilddaten in der Datenbank zu speichern. Wenn es jedoch für Ihr Projekt erforderlich ist, können Sie dies tun.
Bilddaten werden normalerweise unter Verwendung des BLOB-Datentyps in db gespeichert, Room bietet auch Unterstützung für den BLOB-Datentyp Dokumentation
Sie können Ihre Entitätsklasse wie unten erwähnt deklarieren, um Bilddaten zu speichern.
@Entity(tableName = "test")
public class Test{
@PrimaryKey
@ColumnInfo(name = "_id")
private int id;
@ColumnInfo(typeAffinity = ColumnInfo.BLOB)
private byte[] image;
}
Danke, es funktioniert. Ich muss Encoder und Decoder hinzufügen, die das Rohbild in Byte konvertieren[] und byte[] zum Rohbild
– Prinz Kumar
6. November 2017 um 9:52 Uhr
@PrinceKumar True, Sie benötigen Encoder und Decoder für Bitmap zu Byte[] und umgekehrt.
– Pinakin Kansara
22. Februar 2018 um 5:52 Uhr
Ich kann den Blob-Typ nicht verwenden?
– Jhon Fredy Trujillo Ortega
7. März 2018 um 17:03 Uhr
@JhonFredyTrujilloOrtega, Wenn Sie dann kein Blob verwenden möchten, komprimieren Sie zuerst Ihr Bild, konvertieren Sie es dann in eine “Base 64” -Zeichenfolge und speichern Sie es in db. Das Speichern von „blob“ oder „base 64“ wird nicht empfohlen. Am besten speichern Sie die Datei lokal im Dateisystem und fügen nur einen Referenzeintrag in db hinzu. es liegt jedoch an Ihrer Anforderung.
– Pinakin Kansara
13. März 2018 um 5:10 Uhr
Es scheint, als würde diese Lösung BLOB nicht wirklich verwenden. Diese Lösung sorgt dafür, dass die App das Byte-Array vollständig im Speicher hält, während eine echte Verwendung von BLOB, wie z. B. in SQLite oder MySQL, InputStream zum Schreiben und OutputStream zum Schreiben verwenden würde. Wenn also das Byte-Array zu groß ist, wird jeweils nur ein Puffer davon im Speicher gehalten. Übrigens unterstützt BitmapFactory das Arbeiten mit InputStream. Fehlt diese Funktion in der ROOM-Datenbank?
– Elad Lavi
28. April 2018 um 5:23 Uhr
Adithya Reddy
Wie Pinakin erwähnte, wird es nicht empfohlen, ein Bild in einer Datenbank zu speichern, und der Dateipfad wäre besser, aber wenn es erforderlich ist, ein Bild zu speichern, würde ich vorschlagen, das Bild auf unter 2 MB zu komprimieren (hier ist ein Beispiel), um eine Beschädigung der App zu vermeiden. Room unterstützt BLOB für Bilder. Entitätsklasse in kotlin:
ImageTest.kt
@Entity
class ImageTest {
@PrimaryKey(autoGenerate = true)
var id: Int = 1
@ColumnInfo(typeAffinity = ColumnInfo.BLOB)
var data: ByteArray? = null
}
ImageDao.kt
@Dao
interface ImageTestDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun upsertByReplacement(image: List<ImageTest>)
@Query("SELECT * FROM image")
fun getAll(): List<ImageTest>
@Query("SELECT * FROM image WHERE id IN (:arg0)")
fun findByIds(imageTestIds: List<Int>): List<ImageTest>
@Delete
fun delete(imageTest: ImageTest)
}
Datenbank.kt
import android.arch.persistence.room.Database
import android.arch.persistence.room.RoomDatabase
import android.arch.persistence.room.TypeConverters
@Database(entities = arrayOf(ImageTest::class), version = 1)
@TypeConverters(DataConverters::class)
abstract class Database : RoomDatabase() {
abstract fun getImageTestDao(): ImageTestDao
}
In DatabaseHelper so etwas wie
class DatabaseHelper(context: Context) {
init {
DatabaseHelper.context = WeakReference(context)
}
companion object {
private var context: WeakReference<Context>? = null
private const val DATABASE_NAME: String = "image_test_db"
private var singleton: Database? = null
private fun createDatabase(): Database {
return Room.databaseBuilder(context?.get() ?:
throw IllegalStateException("initialize by calling
constructor before calling DatabaseHelper.instance"),
Database::class.java,
DATABASE_NAME)
.build()
}
val instance: Database
@Synchronized get() {
if (null == singleton)
singleton = createDatabase()
return singleton as Database
}
fun setImage(img: Bitmap){
val dao = DatabaseHelper.instance.getImageTestDao()
val imageTest = ImageTest()
imageTest.data = getBytesFromImageMethod(image)//TODO
dao.updsertByReplacement(imageTest)
fun getImage():Bitmap?{
val dao = DatabaseHelper.instance.getImageTestDao()
val imageByteArray = dao.getAll()
return loadImageFromBytes(imageByteArray[0].data)
//change accordingly
}
Korrigiere mich, wenn ich falsch liege. Hoffe, das hilft jemandem da draußen
Vielen Dank für die Erklärung jeder Zeile und die leicht verständliche Lösung meines gesamten Projekts in Java.
– Prinz Kumar
6. November 2017 um 9:51 Uhr
AdamHurwitz
Speichern Sie das Bild als Datei und speichern Sie den Dateipfad Uri in Room
Wie in … gesehen KameraX‘s Bilderfassung Anwendungsfall, wenn ein Foto erfolgreich aufgenommen wurde, die Dateipfadreferenz Uri, savedUrikann sicher abgerufen werden.
Anschließend kann der Uri mit in einen String umgewandelt werden savedUri.toString()und in Raum gespeichert.
Es ist wichtig sicherzustellen, dass die Room-Dateireferenz auch aktualisiert wird, wenn die Datei verschoben oder gelöscht wird.
Die in Room gespeicherte Bildzeichenfolge muss möglicherweise wieder in einen Uri konvertiert werden, um mit einer Bildbibliothek wie Glide with angezeigt zu werden Uri.parse(someString).
Im CameraX-Beispiel kann der Uri eines Bildpfads sicher abgerufen werden onImageSaved.
Es würde dann mit Kotlin Coroutines oder RxJava aus dem Haupt-Thread in Room gespeichert, vorzugsweise in einem ViewModel oder an einem Ort, der die Geschäftslogik getrennt von der Ansichtslogik behandelt.
private fun takePhoto() {
// Get a stable reference of the modifiable image capture use case
val imageCapture = imageCapture ?: return
// Create time-stamped output file to hold the image
val photoFile = File(
outputDirectory,
SimpleDateFormat(FILENAME_FORMAT, Locale.US
).format(System.currentTimeMillis()) + ".jpg")
// Create output options object which contains file + metadata
val outputOptions = ImageCapture.OutputFileOptions.Builder(photoFile).build()
// Set up image capture listener, which is triggered after photo has
// been taken
imageCapture.takePicture(
outputOptions, ContextCompat.getMainExecutor(this), object : ImageCapture.OnImageSavedCallback {
override fun onError(exc: ImageCaptureException) {
Log.e(TAG, "Photo capture failed: ${exc.message}", exc)
}
override fun onImageSaved(output: ImageCapture.OutputFileResults) {
val savedUri = Uri.fromFile(photoFile)
val msg = "Photo capture succeeded: $savedUri"
Toast.makeText(baseContext, msg, Toast.LENGTH_SHORT).show()
Log.d(TAG, msg)
}
})
}
Das Erstellen einer Datei für das Bild und das Speichern des Dateipfads in Room deckt den lokalen Speicher ab. Um sicherzustellen, dass die Bilder auf mehreren Geräten gespeichert werden oder wenn der Datencache und die Daten gelöscht werden, wird eine Form von Cloud-Speicher wird benötigt, um die Dateien in den lokalen Speicher hochzuladen und herunterzuladen und mit ihm zu synchronisieren.
14319100cookie-checkWie füge ich ein Bild in die Raumpersistenzbibliothek ein?yes
Sie können Blob verwenden, um Bilder in Room zu speichern.
– Reena
21. September 2017 um 7:14 Uhr
Folge dies developer.android.com/topic/libraries/architecture/room.html
– Ankita
21. September 2017 um 7:18 Uhr
@CommonsWare Was schlagen Sie vor, wenn Sie nicht empfehlen, Bilder in der Datenbank zu speichern? Bilder im externen Speicher speichern?
– Aniruddha
21. Februar 2018 um 19:36 Uhr
@Aniruddha: Ob Sie verwenden interne Speicher oder externer Speicher hängt davon ab, ob der Benutzer unabhängigen Zugriff auf die Bilder benötigt.
– CommonsWare
21. Februar 2018 um 19:50 Uhr
@CommonsWare Wäre für Lernzwecke am besten, wenn Sie erklären könnten, warum Sie nicht empfehlen, das Bild in der Datenbank zu speichern.
– Aniruddha
22. Februar 2018 um 5:10 Uhr