Reputation: 1344
I am using Room persistent library to store image in the format of Blob.
@Entity(tableName = AppConstants.TABLE_OBSERVATIONS_IMAGE)
public class ImageModel {
@ColumnInfo(typeAffinity = ColumnInfo.BLOB)
public byte[] image;
public ImageModel() {
}
@Ignore
public ImageModel( byte[] image ) {
this.image = image;
}
public byte[] getImage() {
return image;
}
public void setImage(byte[] image) {
this.image = image;
}
}
Now i want to fetch it and show it in image view. But it is giving exception. i am using following code to show image, where model.getImage() is image that i have stored. But it is returning null bitmap and causing app crash.
ImageModel model = observationModelArrayList.get(position).getImageModels().get(i);
ImageView image = new ImageView(context);
image.setLayoutParams(new android.view.ViewGroup.LayoutParams(100, 100));
image.setMaxHeight(100);
image.setMaxWidth(100);
Bitmap bmp = BitmapFactory.decodeByteArray(model.getImage(), 0, model.getImage().length);
//ImageView image = (ImageView) findViewById(R.id.imageView1);
image.setImageBitmap(Bitmap.createScaledBitmap(bmp, image.getWidth(), image.getHeight(), false));
// Adds the view to the layout
holder.llayImages.addView(image);
Please help.
Upvotes: 0
Views: 5600
Reputation: 459
For Room, in kotlin, adding the following type converter to my database worked for me:
class DataConverters {
@TypeConverter
fun fromBitmap(bitmap: Bitmap?): ByteArray {
return if (bitmap != null) {
val size = bitmap.byteCount
val buffer = ByteBuffer.allocate(size)
bitmap.copyPixelsToBuffer(buffer)
buffer.rewind()
ByteArray(size).apply {
buffer.get(this)
shortIntToBytesPair(bitmap.width).let {
this[0] = it.first
this[1] = it.second
}
shortIntToBytesPair(bitmap.height).let {
this[2] = it.first
this[3] = it.second
}
shortIntToBytesPair(bitmap.density).let {
this[4] = it.first
this[5] = it.second
}
}
} else {
byteArrayOf()
}
}
@TypeConverter
fun toBitmap(bytes: ByteArray): Bitmap? {
return if (bytes.isNotEmpty()) {
val width = bytesPairToShortInt(bytes[0], bytes[1])
val height = bytesPairToShortInt(bytes[2], bytes[3])
val density = bytesPairToShortInt(bytes[4], bytes[5])
Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888).apply {
this.density = density
val buffer = ByteBuffer.wrap(bytes)
this.copyPixelsFromBuffer(buffer)
}
} else {
null
}
}
private fun shortIntToBytesPair(value: Int): Pair<Byte, Byte> {
return ((value ushr 8) and 0x000000FF).toByte() to (value and 0x000000FF).toByte()
}
private fun bytesPairToShortInt(high: Byte, low: Byte): Int {
return ((high.toInt() and 0x000000FF) shl 8) + (low.toInt() and 0x000000FF)
}
}
Upvotes: 1
Reputation: 935
You can store the image in internal storage for that it didn't require the storage permission to load the image you can use
private void loadImage(String path){
try {
File file = new File(path, "profile.jpg");
Bitmap b = BitmapFactory.decodeStream(new FileInputStream(file));
ImageView img=(ImageView)findViewById(R.id.imgPicker);
img.setImageBitmap(b); // it will display the image in imageview
String file_path = saveToInternalStorage(b); // store this file_path in db
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
for loading the image from the server you can use the glide library like this
GlideApp.with(context)
.asBitmap()
.load(url)
.into(new SimpleTarget<Bitmap>() {
@Override public void onResourceReady(@NonNull Bitmap resource, Transition<? super Bitmap> transition) {
String file_path = saveToInternalStorage(resource); // store the bitmap
// save this file_path to your db
}
});
for saving the image you can use this method
private String saveToInternalStorage(Bitmap bitmapImage){
ContextWrapper cw = new ContextWrapper(getApplicationContext());
// path to /data/data/yourapp/app_data/imageDir
File directory = cw.getDir("imageDir", Context.MODE_PRIVATE);
// Create imageDir
File mypath=new File(directory,"profile.jpg");
FileOutputStream fos = null;
try {
fos = new FileOutputStream(mypath);
// Use the compress method on the BitMap object to write image to the OutputStream
bitmapImage.compress(Bitmap.CompressFormat.PNG, 100, fos);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return mypath.getAbsolutePath();
}
for loading bitmap, you can use glide get the bitmap from glide and use save method to store bitmap. after saving the image file in the internal storage store the path in your database hope it will help you...
Upvotes: 2