102

In my application I am uploading an image from gallery and I want to store this image in the SQLite database. How do I store a bitmap in the database? I am converting bitmap to a string and saving it in the database. While retrieving it from the database, I am not able to assign that string to ImageView since it is a string.

Imageupload12 .java:

 public class Imageupload12 extends Activity { Button buttonLoadImage; ImageView targetImage; int i = 0; Database database = new Database(this); String i1; String img; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main5); buttonLoadImage = (Button) findViewById(R.id.loadimage); targetImage = (ImageView) findViewById(R.id.targetimage); Bundle b = getIntent().getExtras(); if (b != null) { img = b.getString("image"); targetImage2.setImageURI("image"); //i am getting error as i cant assign string to imageview. } buttonLoadImage.setOnClickListener(new Button.OnClickListener() { public void onClick(View arg0) { // TODO Auto-generated method stub Intent intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI); Log.i("photo", "" + intent); startActivityForResult(intent, i); i = i + 1; } }); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { // TODO Auto-generated method stub super.onActivityResult(requestCode, resultCode, data); switch (requestCode) { case 0: if (resultCode == RESULT_OK) { Uri targetUri = data.getData(); // textTargetUri.setText(targetUri.toString()); Bitmap bitmap; try { bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(targetUri)); targetImage.setImageBitmap(bitmap); i1 = bitmap.toString(); Log.i("firstimage........", "" + i1); targetImage.setVisibility(0); SQLiteDatabase db = database.getWritableDatabase(); db.execSQL("INSERT INTO UPLOAD VALUES('" + i1 + "');"); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } } break; } } } 

Image.class:

 public class Image extends Activity { Database database = new Database(this); static EfficientAdapter adapter, adapter1; static ListView lv1; static SQLiteDatabase db; static EfficientAdapter adp; static Cursor c1; static Vector < String > IMAGE = new Vector < String > (); @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); db = database.getReadableDatabase(); c1 = db.rawQuery("select * from UPLOAD;", null); if (c1.moveToFirst()) { do { IMAGE.add(c1.getString(0).toString()); } while (c1.moveToNext()); c1.close(); } lv1 = (ListView) findViewById(R.id.List); adapter = new EfficientAdapter(this); lv1.setAdapter(adapter); ImageView add = (ImageView) findViewById(R.id.imv1a); add.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub IMAGE.clear(); Intent i = new Intent(Image.this, Imageupload12.class); startActivity(i); } }); } private static class EfficientAdapter extends BaseAdapter { // protected final Context Context = null; protected LayoutInflater mLayoutInflater; AlertDialog.Builder aBuilder; public EfficientAdapter(Context context) { // TODO Auto-generated constructor stub mLayoutInflater = LayoutInflater.from(context); } @Override public int getCount() { // TODO Auto-generated method stub return IMAGE.size(); } @Override public Object getItem(int position) { // TODO Auto-generated method stub return position; } @Override public long getItemId(int position) { // TODO Auto-generated method stub return position; } @Override public View getView(final int position, View convertView, ViewGroup parent) { // TODO Auto-generated method stub final ViewHolder mVHolder; if (convertView == null) { convertView = mLayoutInflater.inflate(R.layout.pjtlistdetails, parent, false); mVHolder = new ViewHolder(); mVHolder.t1 = (TextView) convertView.findViewById(R.id.pjtdetails); mVHolder.time = (TextView) convertView.findViewById(R.id.name); mVHolder.imv = (ImageButton) convertView.findViewById(R.id.editic); mVHolder.imvd = (ImageView) convertView.findViewById(R.id.delete); mVHolder.imvf = (ImageView) convertView.findViewById(R.id.fwd); mVHolder.imv.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String img = IMAGE.elementAt(position); Log.i("image...", "" + img); Context ctx = v.getContext(); Intent myIntent = new Intent(); ctx = v.getContext(); myIntent.setClass(ctx, Imageupload12.class); myIntent.putExtra("image", img); ctx.startActivity(myIntent); IMAGE.clear(); } }); static class ViewHolder { ImageButton imv; ImageView imvd, imvf; } } } } } 
1

5 Answers 5

138

You have to use "blob" to store image.

ex: to store a image in to db:

public void insertImg(int id , Bitmap img ) { byte[] data = getBitmapAsByteArray(img); // this is a function insertStatement_logo.bindLong(1, id); insertStatement_logo.bindBlob(2, data); insertStatement_logo.executeInsert(); insertStatement_logo.clearBindings() ; } public static byte[] getBitmapAsByteArray(Bitmap bitmap) { ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); bitmap.compress(CompressFormat.PNG, 0, outputStream); return outputStream.toByteArray(); } 

To retrieve a image from db:

public Bitmap getImage(int i){ String qu = "select img from table where feedid=" + i ; Cursor cur = db.rawQuery(qu, null); if (cur.moveToFirst()){ byte[] imgByte = cur.getBlob(0); cur.close(); return BitmapFactory.decodeByteArray(imgByte, 0, imgByte.length); } if (cur != null && !cur.isClosed()) { cur.close(); } return null; } 
Sign up to request clarification or add additional context in comments.

2 Comments

here you are inserting a particular image in database but i need to pick a image from gallery and then i need to insert that image in database and retrieve that image.
to select a image from gallery check this question. stackoverflow.com/questions/2507898/… using this coding you can load a gallery image into bitmap. after that store that bitmap into db like i show it here.
38

Use blob to store your image in your sqlite database. Below is an example on how to to use blob.

Setting Up the database

CREATE TABLE " + DB_TABLE + "("+ KEY_NAME + " TEXT," + KEY_IMAGE + " BLOB);"; 

Insert in the Database:

public void addEntry( String name, byte[] image) throws SQLiteException{ ContentValues cv = new ContentValues(); cv.put(KEY_NAME, name); cv.put(KEY_IMAGE, image); database.insert( DB_TABLE, null, cv ); } 

Retrieving data:

 byte[] image = cursor.getBlob(1); 

Note:

  1. Before inserting into database, you need to convert your Bitmap image into byte array first then apply it using database query.
  2. When retrieving from database, you certainly have a byte array of image, what you need to do is to convert byte array back to original image. So, you have to make use of BitmapFactory to decode.

Below is an Utility class which I hope could help you:

public class DbBitmapUtility { // 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 getImage(byte[] image) { return BitmapFactory.decodeByteArray(image, 0, image.length); } } 

5 Comments

Nice, but you should dispose the stream in getBytes(Bitmap bitmap)
Don't forget to call stream.close right before return stream.toByteArray(); to avoid leaks.
@LazyNinja how to pass the selected Image inside the byte Array stackoverflow.com/questions/63610127/…
@Karthickyuvan I have seen your question. Instead of passing the image why not pass the COLUMN_ID? Since you can access the database from anywhere, just retrieve the image by using the columnId. Hope it helps.
I cant able to insert a image !
5

To store any image in sqlite database you need to store that image in byte array instead of string. Convert that image to byte array & store that byte [] to DB. While retrieving that image you will get byte [] convert that byte [] to bitmap by which you will get original image.

Comments

4

I believe the best way of storing an image to an SQLLite database is to use the Base 64 algorithm. which converts an image to plain text and back again. You can download the full example Android project at: www.developersfound.com/Base64FromStream.zip. This program does not store the image but it does convert the image from image to text and back again. The Download link above contains the Kotlin code version of below.

Here is the class:

package com.example.TestProject; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.util.Base64; import android.util.Log; import java.io.*; import java.net.URL; import java.net.URLConnection; import java.nio.channels.FileChannel; public class Base64CODEC { private int IO_BUFFER_SIZE = 64; //private int IO_BUFFER_SIZE = 8192; private URL urlObject = null; private URLConnection myConn = null; ByteArrayOutputStream os = null; public void Base64CODEC() {} public Bitmap Base64ImageFromURL(String url) { Bitmap bitmap = null; InputStream in = null; BufferedOutputStream out = null; try { urlObject = new URL(url); myConn = urlObject.openConnection(); in = myConn.getInputStream(); final ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); out = new BufferedOutputStream(dataStream, IO_BUFFER_SIZE); copyCompletely(in, out); final byte[] data = dataStream.toByteArray(); BitmapFactory.Options options = new BitmapFactory.Options(); bitmap = BitmapFactory.decodeByteArray(data, 0, data.length, options); } catch (IOException e) { Log.e("TAG", "Could not load Bitmap from: " + url); } finally { //closeStream(in); try { in.close(); } catch (IOException e) { e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. } //closeStream(out); try { out.close(); } catch (IOException e) { e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. } } return bitmap; } private void copyCompletely(InputStream input, OutputStream output) throws IOException { // if both are file streams, use channel IO if ((output instanceof FileOutputStream) && (input instanceof FileInputStream)) { try { FileChannel target = ((FileOutputStream) output).getChannel(); FileChannel source = ((FileInputStream) input).getChannel(); source.transferTo(0, Integer.MAX_VALUE, target); source.close(); target.close(); return; } catch (Exception e) { /* failover to byte stream version */ } } byte[] buf = new byte[8192]; while (true) { int length = input.read(buf); if (length < 0) break; output.write(buf, 0, length); } try { input.close(); } catch (IOException ignore) { } try { output.close(); } catch (IOException ignore) {} } public String convertToBase64(Bitmap bitmap) { ByteArrayOutputStream os = new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.PNG,100,os); byte[] byteArray = os.toByteArray(); return Base64.encodeToString(byteArray, 0); } public Bitmap convertToBitmap(String base64String) { byte[] decodedString = Base64.decode(base64String, Base64.DEFAULT); Bitmap bitmapResult = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length); return bitmapResult; } } 

And here is the main activity that uses the class:

package com.example.TestProject; import android.app.Activity; import android.graphics.Bitmap; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.view.View; import android.widget.ImageView; public class MainActivity extends Activity implements Runnable { private Thread thread = null; private Bitmap bitmap = null; private Base64CODEC base64CODEC = null; private ImageView imgViewSource = null; private ImageView imgViewDestination = null; private boolean isSourceImageVisible = false; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } public void CmdLoadImage_Click(View view) { try { if(isSourceImageVisible == true) { imgViewSource.setImageBitmap(null); imgViewDestination.setImageBitmap(null); isSourceImageVisible = false; } else { base64CODEC = new Base64CODEC(); thread = new Thread(this); thread.start(); } } catch (NullPointerException e) {} } public void CmdEncodeImage_Click(View view) { Base64CODEC base64CODEC = new Base64CODEC(); try { String base64String = base64CODEC.convertToBase64(bitmap); imgViewDestination = (ImageView) findViewById(R.id.imgViewDestination); Bitmap imgViewDestinationBitmap = base64CODEC.convertToBitmap(base64String); imgViewDestination.setImageBitmap(imgViewDestinationBitmap); } catch (NullPointerException e) { // } } @Override public void run() { bitmap = base64CODEC.Base64ImageFromURL("http://developersfound.com/me.png"); handler.sendEmptyMessage(0); } private Handler handler = new Handler() { @Override public void handleMessage(Message msg) { imgViewSource = (ImageView) findViewById(R.id.imgViewSource); imgViewSource.setImageBitmap(bitmap); isSourceImageVisible = true; thread = null; } }; } 

2 Comments

Oh, no! You will bloat your database! You say you believe it best, do you have a reason why you believe so?
What should we store in DB android- storing bitmap as blob or in string format?
1

Don't forget to write user permission code in Manifest file

 protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); CameraActivity = this; imageView = (ImageView) findViewById(R.id.image_view); database = new ImageDatabase(this); //Set OnClick Listener to button view captureImage = (Button) findViewById(R.id.capture_image); captureImage.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); startActivityForResult(cameraIntent, CAMERA_REQUEST); } }); } @Override public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { if (requestCode == CAMERA_REQUEST && resultCode == Activity.RESULT_OK) { theImage = (Bitmap) data.getExtras().get("data"); ByteArrayOutputStream stream = new ByteArrayOutputStream(); theImage.compress(Bitmap.CompressFormat.PNG, 100, stream); byte[] byteArray = stream.toByteArray(); SQLiteDatabase db = database.getWritableDatabase(); ContentValues values = new ContentValues(); values.put(ImageDatabase.KEY_IMG_URL, byteArray); db.insert(ImageDatabase.TABLE_NAME, null, values); db.close(); Bitmap b = getTheImage(); imageView.setImageBitmap(b); } } public Bitmap getTheImage(){ SQLiteDatabase db = database.getReadableDatabase(); Cursor cursor = (Cursor) db.rawQuery(" SELECT * FROM "+ImageDatabase.TABLE_NAME,null,null); if (cursor.moveToFirst()){ byte[] imgByte = cursor.getBlob(cursor.getColumnIndex(ImageDatabase.KEY_IMG_URL)); cursor.close(); return BitmapFactory.decodeByteArray(imgByte,0,imgByte.length); } if (cursor != null && !cursor.isClosed()) { cursor.close(); } return null; } } 

DATABASE CLASS

class ImageDatabase extends SQLiteOpenHelper { public Context context; public static final String DATABASE_NAME = "dataManager"; public static final int DATABASE_VERSION = 1; public static final String TABLE_NAME = "data"; public static final String KEY_ID = "id"; public static final String KEY_IMG_URL = "ImgFavourite"; public ImageDatabase(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); this.context = context; //Toast.makeText(context, "Constructor called", Toast.LENGTH_LONG).show(); } public static final String CREATE_TABLE = "CREATE TABLE " + TABLE_NAME + "(" + KEY_ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + KEY_IMG_URL + " BLOB " + ")"; public static final String DROP_TABLE = "DROP TABLE IF EXISTS " + TABLE_NAME + ""; @Override public void onCreate(SQLiteDatabase db) { db.execSQL(CREATE_TABLE); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { db.execSQL(DROP_TABLE); onCreate(db); } public void deleteEntry(long row) { SQLiteDatabase sqLiteDatabase = getWritableDatabase(); sqLiteDatabase.delete(TABLE_NAME, KEY_ID + "=" + row, null); } } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.