I'm developing an app which involves capture, save and retrieve image from SQLite. I managed to capture and save image into SQLite. However, I cannot retrieve the image back. I have converted the image into byte array before saved it inside SQLite.
This is my code - Database.java:
public String displayImageBendaOne(String rowId) {
SQLiteDatabase db=helper.getReadableDatabase();
Cursor cursor = db.query(true, BacaHelper.TABLE_NAME_BENDA, new String[] {BacaHelper.UID,
BacaHelper.BENDA, BacaHelper.BENDA_IMAGE, BacaHelper.BENDA_ID}, BacaHelper.BENDA_ID + "==" + rowId, null,
null, null, null, null);
StringBuffer buffer = new StringBuffer();
if (cursor.moveToFirst()) {
{
//byte[] bImageOne=cursor.getBlob(cursor.getColumnIndex(BacaHelper.BENDA_IMAGE));
byte[] bImageOne = cursor.getBlob(1);
buffer.append(bImageOne);
}
}
db.close();
return buffer.toString();
}
Baca.java:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.benda_read);
bacaHelper= new BacaDatabaseAdapter(this);
bIOne = (ImageView) findViewById(R.id.imageOne);
passVar = getIntent().getStringExtra(benda.ID_EXTRA);
String bendaIOne = bacaHelper.displayImageBendaOne(passVar);
Log.e("Byte[] ", bendaIOne);
ByteArrayInputStream imageStream = new ByteArrayInputStream(bendaIOne.getBytes());
theImage = BitmapFactory.decodeStream(imageStream);
imageStream.reset();
bIOne.setImageBitmap(theImage);
}
There are no syntax error at the moment but when I run my apps, the image does not appear. In LogCat showed SKImageDecoder:: Factory returned null. What is the meaning of this statement?
There is something about above coding I cannot figure out. I have decided to convert from image to byte array to string to byte array to image. Which is a long process because I don't know how to directly retrieve value of byte array from database.
Can anyone point out what I should do? Thanks in advance.
Updated: this is the class where I converted image into byte array and save inside database.
protected void onActivityResult (int requestCode, int resultCode, Intent data) {
if (resultCode != RESULT_OK)
return;
switch (requestCode) {
case CAMERA_REQUEST:
Bundle extras = data.getExtras();
String bendaTambah=benda.getText().toString();
if (extras != null) {
Bitmap yourImage = extras.getParcelable("data");
// convert bitmap to byte
ByteArrayOutputStream stream = new ByteArrayOutputStream();
yourImage.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte imageInByte[] = stream.toByteArray();
Log.e("output before conversion", imageInByte.toString());
// Inserting Contacts
Log.d("Insert: ", "Inserting ..");
bacaHelper.addContact(new BendaCall(bendaTambah, imageInByte, passVar));
Intent i = new Intent(benda.this,
benda.class);
startActivity(i);
finish();
}
break;
case PICK_FROM_GALLERY:
Bundle extras2 = data.getExtras();
String bendaTambah2=benda.getText().toString();
if (extras2 != null) {
Bitmap yourImage = extras2.getParcelable("data");
// convert bitmap to byte
ByteArrayOutputStream stream = new ByteArrayOutputStream();
yourImage.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte imageInByte[] = stream.toByteArray();
Log.e("output before conversion", imageInByte.toString());
// Inserting Contacts
Log.d("Insert: ", "Inserting ..");
bacaHelper.addContact(new BendaCall(bendaTambah2, imageInByte, passVar));
Intent i = new Intent(benda.this,
benda.class);
startActivity(i);
finish();
} else{
Message.message(this, "Tidak berjaya menambah gambar ");
}
break;
}
}
Try out this code
Modify your displayImageBendaOne method like
public Bitmap displayImageBendaOne(String rowId){
SQLiteDatabase db=helper.getReadableDatabase();
Cursor cursor = db.query(true, BacaHelper.TABLE_NAME_BENDA, new String[] {BacaHelper.UID,
BacaHelper.BENDA, BacaHelper.BENDA_IMAGE, BacaHelper.BENDA_ID}, BacaHelper.BENDA_ID + "==" + rowId, null,
null, null, null, null);
//StringBuffer buffer= new StringBuffer();
Bitmap bm=null;
if (cursor.moveToFirst()) {
{
//byte[] bImageOne=cursor.getBlob(cursor.getColumnIndex(BacaHelper.BENDA_IMAGE));
byte[] bImageOne = cursor.getBlob(1);
bm=BitmapFactory.decodeByteArray(bImageOne , 0, bImageOne.length);
// buffer.append(bImageOne);
}
}
db.close();
return bm;
}
In your onCreate method instead of
String bendaIOne = bacaHelper.displayImageBendaOne(passVar);
Log.e("Byte[] ", bendaIOne);
ByteArrayInputStream imageStream = new ByteArrayInputStream(bendaIOne.getBytes());
theImage = BitmapFactory.decodeStream(imageStream);
imageStream.reset();
bIOne.setImageBitmap(theImage);
Use this
Bitmap image=bacaHelper.displayImageBendaOne(passVar);
bIOne.setImageBitmap(image);
code to open camera
if (android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED))
{
// String s=sharedPreferences.getString("source", "");
Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
File file = new File(Environment.getExternalStorageDirectory()+File.separator + "image.jpg");
path1=Environment.getExternalStorageDirectory()+File.separator + "image.jpg";
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));
startActivityForResult(intent, CAPTURE_IMAGE_FULLSIZE_ACTIVITY_REQUEST_CODE);
}
else
{
ContextWrapper contextWrapper = new ContextWrapper(AddItem.this);
File file =new File(contextWrapper.getDir("Inventory", Context.MODE_PRIVATE)+File.separator + "image.jpg");
path1=contextWrapper.getDir("Inventory", Context.MODE_PRIVATE)+File.separator + "image.jpg";
Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
// File file = new File(Environment.getExternalStorageDirectory()+File.separator + "image.jpg");
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));
startActivityForResult(intent, CAPTURE_IMAGE_FULLSIZE_ACTIVITY_REQUEST_CODE);
}
code to get image from camera
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == AddItem.this.RESULT_OK)
{
if (requestCode == CAPTURE_IMAGE_FULLSIZE_ACTIVITY_REQUEST_CODE)
{//if image is captured from camera
// count++;
Bitmap bitmap;
String fname;
if (android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED))
{
File file = new File(Environment.getExternalStorageDirectory()+File.separator + "image.jpg");
BitmapFactory.Options btmapOptions = new BitmapFactory.Options();
Bitmap bm = BitmapFactory.decodeFile(file.getAbsolutePath(),btmapOptions);
bitmap = decodeSampledBitmapFromFile(file.getAbsolutePath(), 500, 500);
fname="image.jpg";
try {
ExifInterface exif = new ExifInterface(file.getAbsolutePath());
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL);
int rotate = 0;
switch(orientation) {
case ExifInterface.ORIENTATION_ROTATE_270:
rotate-=90;break;
case ExifInterface.ORIENTATION_ROTATE_180:
rotate-=90;break;
case ExifInterface.ORIENTATION_ROTATE_90:
rotate-=90;break;
}
// Log.d("Fragment", "EXIF info for file " + name1 + ": " + rotate);
} catch (IOException e) {
// Log.d("Fragment", "Could not get EXIF info for file " + name1 + ": " + e);
}
// viewImage.setImageBitmap(bitmap);
}
else
{
ContextWrapper contextWrapper = new ContextWrapper(AddItem.this);
File file =new File(contextWrapper.getDir("Inventory", Context.MODE_PRIVATE)+File.separator + "image.jpg");
// File file = new File(Environment.getExternalStorageDirectory()+File.separator + "image.jpg");
BitmapFactory.Options btmapOptions = new BitmapFactory.Options();
Bitmap bm = BitmapFactory.decodeFile(file.getAbsolutePath(),btmapOptions);
bitmap = decodeSampledBitmapFromFile(file.getAbsolutePath(), 500, 500);
fname="image.jpg";
// viewImage.setImageBitmap(bitmap);
}
//add to database
addlabel.setVisibility(View.VISIBLE);
Inventory inv= new Inventory(bitmap,fname,name,date);
DbHelper.open();
long count=DbHelper.insertInvDetails(inv);
//Toast.makeText(AddItem.this, count+"", Toast.LENGTH_LONG).show();
DbHelper.close();
}
}
}
code to obtain a full size image
public static Bitmap decodeSampledBitmapFromFile(String path, int reqWidth, int reqHeight)
{ // BEST QUALITY MATCH
//First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(path, options);
// Calculate inSampleSize, Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
options.inPreferredConfig = Bitmap.Config.RGB_565;
int inSampleSize = 1;
if (height > reqHeight)
{
inSampleSize = Math.round((float)height / (float)reqHeight);
}
int expectedWidth = width / inSampleSize;
if (expectedWidth > reqWidth)
{
//if(Math.round((float)width / (float)reqWidth) > inSampleSize) // If bigger SampSize..
inSampleSize = Math.round((float)width / (float)reqWidth);
}
options.inSampleSize = inSampleSize;
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeFile(path, options);
}
Utility class use to converting image to byte array and decoding it back to bimap
import java.io.ByteArrayOutputStream;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.util.Log;
public class Utility {
// convert from bitmap to byte array
public static byte[] getBytes(Bitmap bitmap) {
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(CompressFormat.PNG, 0, stream);
return stream.toByteArray();
}
// convert from byte array to bitmap
public static Bitmap getPhoto(byte[] image) {
Log.i("", image.toString());
return BitmapFactory.decodeByteArray(image, 0, image.length);
}
}
Database code to insert data
public long insertInvDetails(Inventory invent) {
mDb = mDbHelper.getWritableDatabase();
ContentValues cv = new ContentValues();
cv.put(EMP_PHOTO, Utility.getBytes(invent.getBitmap()));
cv.put(EMP_NAME, invent.getName());
cv.put(EMP_PNAME, invent.getPersonName());
cv.put(EMP_Date, invent.getDate());
cv.put("IsDeleted", 0);
long count=mDb.insert(INVENTORY_TABLE, null, cv);
return count;
}
UPDATE
code to retrieve data
public List<Inventory> getSelectedContacts() {
List<Inventory> invlist = new ArrayList<Inventory>();
// Select All Query
mDb = mDbHelper.getWritableDatabase();
Cursor cursor = mDb.query(true, INVENTORY_TABLE, new String[] {EMP_ID, EMP_PHOTO,
EMP_NAME, EMP_PNAME,EMP_Date }, "IsDeleted=1", null, null, null, null, null);
// looping through all rows and adding to list
if (cursor.moveToFirst()) {
do {
Inventory inv = new Inventory();
inv.setID(cursor.getInt(0));
byte[] blob = cursor.getBlob(cursor.getColumnIndex(EMP_PHOTO));
inv.setBitmap(Utility.getPhoto(blob));
inv.setName(cursor.getString(2));
inv.setPersonName(cursor.getString(3));
inv.setDate(cursor.getString(4));
// Adding contact to list
invlist.add(inv);
} while (cursor.moveToNext());
}
mDb.close();
// return contact list
return invlist;
}
Code to call getSelectedContactsand display image in linearlayout
List<Inventory> select_contacts = db.getSelectedContacts();
LinearLayout newll=new LinearLayout(MainPage.this);
newll.setOrientation(LinearLayout.VERTICAL);
for (Inventory cn : select_contacts) {
ImageView myImage = new ImageView(MainPage.this);
myImage.setImageBitmap(cn.getBitmap());
newll.addView(myImage);
}
//add newll to your parent view
Here is my inventory class for holding values
package com.graficali.inventorysystem;
import android.graphics.Bitmap;
public class Inventory {
private Bitmap bmp;
private String filename;
private String personname;
String created_at;
private int id;
public Inventory()
{
}
public Inventory(Bitmap b, String n, String pn, String created_at) {
bmp = b;
filename = n;
personname = pn;
this.created_at=created_at;
}
public Bitmap getBitmap() {
return bmp;
}
public String getName() {
return filename;
}
public String getDate() {
return this.created_at;
}
public int getID() {
return this.id;
}
public String getPersonName() {
return personname;
}
public void setBitmap(Bitmap bmp) {
this.bmp=bmp;
}
public void setName(String filename) {
this.filename=filename;
}
public void setID(int id) {
this.id=id;
}
public void setPersonName(String personname)
{
this.personname=personname;
}
public void setDate(String created_at) {
this.created_at = created_at;
}
}