androidimagesqlitedisplay

Unable to retrieve image from SQLite. SKImageDecoder::Factory returned null


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

Solution

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

    }