i have a database with categories, here they are
@Entity
data class Category(
@PrimaryKey(autoGenerate = true) val uid: Int,
@ColumnInfo(name = "name") val name: String,
@ColumnInfo(name = "color") val color: Int,
@ColumnInfo(name = "icon", typeAffinity = ColumnInfo.BLOB) val icon: ByteArray?
)
i would like to save svg to icon field. what would i do to to save it? i have tried nothing cause i couldn't not find the way to solve my problem
CodePudding user response:
Use following code.
convertSVGToByteArray(R.drawable.ic_add)
You can save your SVG in form of byte array.
fun convertSVGToByteArray(resId: Int): ByteArray {
val byteArrayOutputStream = ByteArrayOutputStream()
val drawable: Drawable? = ContextCompat.getDrawable(context, resId)
drawable?.let {
val bitmap = Bitmap.createBitmap(drawable.intrinsicWidth, drawable.intrinsicHeight, Bitmap.Config.ARGB_8888)
val canvas = Canvas(bitmap)
drawable.setBounds(0, 0, canvas.width, canvas.height)
drawable.draw(canvas)
bitmap?.let {
bitmap.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOutputStream)
bitmap.recycle()
}
}
return byteArrayOutputStream.toByteArray()
}
Steps
- Convert your 'svg' to bitmap
- Get byte array from bitmap
- Recycle bitmap to release memory
- Save your byte array.
CodePudding user response:
You need to convert the svg to a ByteArray to save it. However, that may not be the best solution.
In short to save the file you will have to have the file somewhere and convert it to a ByteArray (which is really what a file (any file) contains/is anyway) and then when/after extracting it from the database convert it back accordingly.
As such it makes some sense to instead save a means of accessing the file (e.g. it's path or latter part of it's path) then all you have to do is access the file from the path.
Furthermore although SQLite, and therefore Room (it being a wrapper around Room), can store pretty large amounts of data, there is an issue with how SQLite on Android and therefore Room extracts data. It does this via a Cursor which is a buffer that buffers part of the output from an extract (query). The actual buffer block, is called a CursorWindow and is limited to up to 4Mb (unless overridden). A single row CANNOT be split between buffers (i.e. a buffer must be able to hold at least 1 row). So if the svg is 4MB (or even less depending upon the implementation) it cannot be in a single attempt.
Such buffering is quite efficient when the buffer can hold a large number of rows but the fewer rows per buffer then they become less efficient and more resource hungry.
In short the recommended way is to not save the files in the database but to save a reference to the file.
- Saying that the following may be of interest (initially mentioning 10kB) SQLite 35% Faster Than The Filesystem