How to store images in SQLite database (insert, update, delete and fetch) in your Android App?

This video shows simple steps to store the image files in your local SQLite database. For storing the Images in the database, unlike simple text or numbers, it uses BLOB field. It first converts the image file (or image) into bitmap. Then it converts the bitmap into bytes by compressing the bitmap using the PNG compress format.

It uses the same method to either insert or update the image field in the SQLite database.

It does the reverse while fetching the information from the SQLite database. It first retrieves the byte array information. Then it converts the byte array into Bitmap using the decodeByteArray method from BitmapFactory.

It uses an ImageView widget to display or show the output fetched from the database column.

In the deletion method, it simply deletes the row from the database using the where clause for the respective row (entry).

In this tutorial it has hardcoded the Name (Key/ index) field of the database as “MyImage”. But in all practical scenario this field entry should be taken from the user (will change as per the use-case).

I hope you like this video. For any questions, suggestions or appreciation please contact us at: https://programmerworld.co/contact/ or email at: programmerworld1990@gmail.com

Source Code:

package com.programmerworld.imgefileinsqlitedatabase;

import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;

import android.Manifest;
import android.content.ContentValues;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;

import java.io.ByteArrayOutputStream;

public class MainActivity extends AppCompatActivity {

private EditText editTextFileName;
private TextView textViewStatus;
private ImageView imageView;

private mySqliteDBHandler sqliteDBHandler;
private SQLiteDatabase sqLiteDatabase;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE}, PackageManager.PERMISSION_GRANTED);

editTextFileName = findViewById(R.id.editTextTextFileName);
textViewStatus = findViewById(R.id.textViewStatus);
imageView = findViewById(R.id.imageView);

try {
sqliteDBHandler = new mySqliteDBHandler(this, "ImageDatabase", null, 1);
sqLiteDatabase = sqliteDBHandler.getWritableDatabase();
sqLiteDatabase.execSQL("CREATE TABLE ImageTable(Name TEXT, Image BLOB)");
}
catch (Exception e){
e.printStackTrace();
}
}

public void buttonInsert(View view){
String stringFilePath = Environment.getExternalStorageDirectory().getPath()+"/Download/"+editTextFileName.getText().toString()+".jpeg";
Bitmap bitmap = BitmapFactory.decodeFile(stringFilePath);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 0, byteArrayOutputStream);
byte[] bytesImage = byteArrayOutputStream.toByteArray();

ContentValues contentValues = new ContentValues();
contentValues.put("Name", "MyImage");
contentValues.put("Image", bytesImage);
sqLiteDatabase.insert("ImageTable", null, contentValues);
textViewStatus.setText("Insert Successful");
}

public void buttonUpdate(View view){
String stringFilePath = Environment.getExternalStorageDirectory().getPath()+"/Download/"+editTextFileName.getText().toString()+".jpeg";
Bitmap bitmap = BitmapFactory.decodeFile(stringFilePath);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 0, byteArrayOutputStream);
byte[] bytesImage = byteArrayOutputStream.toByteArray();

ContentValues contentValues = new ContentValues();
contentValues.put("Name", "MyImage");
contentValues.put("Image", bytesImage);

sqLiteDatabase.update("ImageTable", contentValues, null, null);
textViewStatus.setText("Update Successful");
}

public void buttonDelete(View view){
if (sqLiteDatabase.delete("ImageTable", "Name=\"MyImage\"", null)>0){
textViewStatus.setText("Deletion successful");
}
}

public void buttonFetch(View view){
String stringQuery = "Select Image from ImageTable where Name=\"MyImage\"";
Cursor cursor = sqLiteDatabase.rawQuery(stringQuery, null);
try {
cursor.moveToFirst();
byte[] bytesImage = cursor.getBlob(0);
cursor.close();
Bitmap bitmapImage = BitmapFactory.decodeByteArray(bytesImage, 0, bytesImage.length);
imageView.setImageBitmap(bitmapImage);
textViewStatus.setText("Fetch Successful");
}
catch (Exception e){
textViewStatus.setText("ERROR");
}
}
}

package com.programmerworld.imgefileinsqlitedatabase;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

import androidx.annotation.Nullable;

public class mySqliteDBHandler extends SQLiteOpenHelper {
public mySqliteDBHandler(@Nullable Context context, @Nullable String name, @Nullable SQLiteDatabase.CursorFactory factory, int version) {
super(context, name, factory, version);
}

@Override
public void onCreate(SQLiteDatabase db) {

}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

}
}

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.programmerworld.imgefileinsqlitedatabase">

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>

</manifest>

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">

<TextView
android:id="@+id/textViewStatus"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_bias="0.489"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.435" />

<EditText
android:id="@+id/editTextTextFileName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="83dp"
android:layout_marginTop="43dp"
android:ems="10"
android:hint="@string/enter_file_name"
android:inputType="textPersonName"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:autofillHints="" />

<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="49dp"
android:layout_marginTop="40dp"
android:onClick="buttonInsert"
android:text="@string/insert"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/editTextTextFileName" />

<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="103dp"
android:layout_marginTop="40dp"
android:onClick="buttonUpdate"
android:text="@string/update"
app:layout_constraintStart_toEndOf="@+id/button"
app:layout_constraintTop_toBottomOf="@+id/editTextTextFileName" />

<Button
android:id="@+id/button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="49dp"
android:layout_marginTop="38dp"
android:onClick="buttonDelete"
android:text="@string/delete"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/button" />

<Button
android:id="@+id/button4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="96dp"
android:layout_marginTop="42dp"
android:onClick="buttonFetch"
android:text="@string/fetch"
app:layout_constraintStart_toEndOf="@+id/button3"
app:layout_constraintTop_toBottomOf="@+id/button2" />

<ImageView
android:id="@+id/imageView"
android:layout_width="222dp"
android:layout_height="180dp"
android:layout_marginStart="82dp"
android:layout_marginTop="39dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textViewStatus"
app:srcCompat="@drawable/ic_launcher_background"
android:contentDescription="@string/todo" />

</androidx.constraintlayout.widget.ConstraintLayout>

// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
google()
jcenter()
}
dependencies {
classpath "com.android.tools.build:gradle:4.0.1"

// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}

allprojects {
repositories {
google()
jcenter()
}
}

task clean(type: Delete) {
delete rootProject.buildDir
}

apply plugin: 'com.android.application'

android {
compileSdkVersion 30
buildToolsVersion "29.0.3"

defaultConfig {
applicationId "com.programmerworld.imgefileinsqlitedatabase"
minSdkVersion 26
targetSdkVersion 30
versionCode 1
versionName "1.0"

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}

buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}

dependencies {
implementation fileTree(dir: "libs", include: ["*.jar"])
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'

}

<resources>
<string name="app_name">Imge File in SQlite Database</string>
<string name="enter_file_name">Enter File Name ...</string>
<string name="insert">Insert</string>
<string name="update">Update</string>
<string name="delete">Delete</string>
<string name="fetch">Fetch</string>
<string name="todo">TODO</string>
</resources>

Screenshots:

Leave a Reply

%d bloggers like this: