Android : Compress & Insert images into SQLite Database - android

I'm working on an app, in witch i need to store more than 1600 images (.PNG) in BLOB format. Each image has nearly 230KB in size.
What i want to do, is to compress images to someting below 20KB. So as a result the whole size of images will be around 32 MB (1600 x 20KB) and the final apk size will be reduced.
To explain more : what i want to do is to compress images from 230KB to under 20KB to save more space in the database. the database will be filled with data and images before integrating it in the apk.
So if i compressed images stored in database. the database size will reduce. and it will not take a lot of space inside APK
Any suggestions on how to do that ?
NOTE : the Database will be filled with information before integrating in the app.

I think it would be the best to store those images on server, and once user downloads your app you should transfer images to app.
1600 is really a big number for app before it's installed...

I do not know if this is the best way to save storage space using SQLite and I am still looking for it, but here we go.
You can select the source of your image, such as gallery or camera and below is the code.
private void selectProductImage() {
final CharSequence[] itens = {"Use Camera", "Gallery", "Cancel"};
AlertDialog.Builder builder = new AlertDialog.Builder(this,R.style.AlertDialog);
builder.setItems(itens, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
if (itens[which].equals("Use Camera")) {
Toast.makeText(YourActivity.this, "Use Camera", Toast.LENGTH_SHORT).show();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(new String[]{Manifest.permission.CAMERA}, MY_CAMERA_PERMISSION_CODE);
} else {
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cameraIntent, CAMERA_REQUEST);
}
} else if (itens[which].equals("Gallery")) {
Toast.makeText(YourActivity.this, "Gallery", Toast.LENGTH_SHORT).show();
Intent galleryIntent = new Intent();
galleryIntent.setAction(Intent.ACTION_GET_CONTENT);
galleryIntent.setType("image/*");
startActivityForResult(galleryIntent, REQUEST_GALLERY_PHOTO);
} else if (itens[which].equals("Cancel")) {
dialog.dismiss();
}
}
});
builder.show();
}
Maybe you need permission to use the camera
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == MY_CAMERA_PERMISSION_CODE) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//Toast.makeText(this, "camera permission granted", Toast.LENGTH_LONG).show();
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cameraIntent, CAMERA_REQUEST);
} else {
Toast.makeText(this, "camera permission denied", Toast.LENGTH_LONG).show();
}
return;
}
}
Here is how to handle the image from the source you selected.
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == CAMERA_REQUEST && resultCode == Activity.RESULT_OK) {
Bitmap bitmap = Bitmap.createScaledBitmap((Bitmap) data.getExtras().get("data"),96, 96, true);
mProductImage.setImageBitmap(bitmap);
isPriviteImage = true;
}
if (requestCode == REQUEST_GALLERY_PHOTO && resultCode == RESULT_OK && data != null) {
//mProductImage.setImageURI(data.getData());
// INSERT IMAGE INTO SQLite
Uri uri = data.getData();
try {
InputStream inputStream = getContentResolver().openInputStream(uri);
Bitmap bitmap = Bitmap.createScaledBitmap(BitmapFactory.decodeStream(inputStream),96, 96, true);
mProductImage.setImageBitmap(bitmap);
isPriviteImage = true;
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
As you can notice in my example, there is no place to save the image case you selected camera and I placed the image on an ImageView variable named mProductImage.
From now, you can use a Button to save the image in your SQLite Database. Here is the function you can use for it.
private void saveImage() {
productTablePath = Environment.getExternalStorageDirectory()+"/YourAditionalPath/";
ProductDatabaseHelper productDatabaseHelper = new ProductDatabaseHelper(getApplicationContext(), "dbname.db", productTablePath);
productListTable = productDatabaseHelper.getWritableDatabase();
productRepository = new ProductRepository(productListTable);
try {
if (isPriviteImage) {
productRepository.addProduct(imageViewToByte(mProductImage));
isPriviteImage = false;
} else {
productRepository.addProduct(null);
}
mProductImage.setImageResource(R.drawable.shopping_cart_black_48dp);
} catch (Exception e) {
e.printStackTrace();
}
}
Where imageViewToByte functon is:
private byte[] imageViewToByte(CircleImageView image) {
Bitmap bitmap = ((BitmapDrawable)image.getDrawable()).getBitmap();
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG,100,stream);
byte[] byteArray = stream.toByteArray();
return byteArray;
}
Now you need to implement the SQLiteOpenHelper. You need to create a new class for this. The java file name I used for this was ProductDatabaseHelper.java.
public class ProductDatabaseHelper extends SQLiteOpenHelper {
private static int dbVersion = 1;
public ProductDatabaseHelper(Context context, String name, String storageDirectory) {
super(context, storageDirectory+name, null, dbVersion);
}
#Override
public void onCreate(SQLiteDatabase db) {
StringBuilder sql = new StringBuilder();
sql.append("CREATE TABLE IF NOT EXISTS PRODUCTLIST (");
sql.append(" IMAGE BLOB,");
db.execSQL(sql.toString());
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
Now you need to implement your CRUD (Create new item, Read, Update and Delete).
public class ProductRepository {
SQLiteDatabase instance;
public ProductRepository(SQLiteDatabase instance) {
this.instance = instance;
}
public void addProduct(byte[] image){
ContentValues contentValues = new ContentValues();
contentValues.put("IMAGE",image);
instance.insertOrThrow("PRODUCTLIST",null, contentValues);
}
}
It is important to mention that the compression of the image was made in the onActivityResult() for both source image (camera and gallery).
with the command:
Bitmap bitmap = Bitmap.createScaledBitmap(capturedImage, width, height, true);
Besides that, here is a link where we can read a little bit about compression.
https://androidwave.com/capture-image-from-camera-gallery/
If you have a better way to compress images to save in SQLite Database, please post your code here!

Related

startActivityForResults not working when the child activity calls another activity

I have 3 activities say A, B and C.
A calls B.
When B doesn't call C it returns to A. But when B calls C it doesn't return to A, the app stops.
Now the real problem is, from activity A I want to call an image picker and crop the image. That's Activity B which crops and calls C for picking image.
Activity A:
iv_profile_pic.setOnClickListener(new View.OnClickListener() {//iv_profile_pic is an ImageView
#Override
public void onClick(View view) {
Intent i=new Intent(MainActivity.this,profile_pic_chooser.class);
i.setFlags(0);
MainActivity.this.startActivityForResult(i, 999);
Toast.makeText(getApplicationContext(),"Reached",Toast.LENGTH_SHORT).show();
}
});
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
if (requestCode == 999) {
Bitmap image=data.getParcelableExtra("picture");
iv_profile_pic.setImageBitmap(image);
}
}
Activity B:
It has 2 buttons. Load and Crop. Load when clicked calls ImageChooserIntent and chooses an image which is opened in B with guidlines to crop.
Crop when clicked should return back to A the cropped image.
If crop is called without calling load, it returns to A with null, of-course.
But if Load is clicked first and then Crop is called, the app simply stops.
public void onLoadImageClick(View view) {
startActivityForResult(getPickImageChooserIntent(), 200);
}
public void onCropImageClick(View view) {
Bitmap cropped = mCropImageView.getCroppedImage(500, 500);
if (cropped != null) {
mCropImageView.setImageBitmap(cropped);
iv.setImageBitmap(cropped);
Intent returnIntent = new Intent();
returnIntent.putExtra("picture", cropped);
setResult(Activity.RESULT_OK, returnIntent);
finish();
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == Activity.RESULT_OK) {
Uri imageUri = getPickImageResultUri(data);
// For API >= 23 we need to check specifically that we have permissions to read external storage,
// but we don't know if we need to for the URI so the simplest is to try open the stream and see if we get error.
boolean requirePermissions = false;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M &&
checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED &&
isUriRequiresPermissions(imageUri)) {
// request permissions and handle the result in onRequestPermissionsResult()
requirePermissions = true;
mCropImageUri = imageUri;
requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 0);
}
if (!requirePermissions) {
mCropImageView.setImageUriAsync(imageUri);
}
}
}
I got a workaround. The most probable problem I was facing was:
I was using an external library for cropping the image. This library did 2 things.
First, selected an image using imageChooser intent.
Second, Cropped that image.
After the library cropped the image, it wasn't saving the cropped image in local/external storage. But I was trying to pass it back to parent directory.
There's the problem. The file doesn't exist and still I am trying to use it. The application terminates.
So my workaround was,
• Save the bitmap in storage
• Pass the Uri to parent
• Extract that Uri from child
• Make bitmap from that Uri
• Apply on the ImageView
So Activity B had:
public void onCropImageClick(View view) {
Bitmap cropped = mCropImageView.getCroppedImage(500, 500);
if (cropped != null) {
mCropImageView.setImageBitmap(cropped);
iv.setImageBitmap(cropped);
File externalStorageDirectory = Environment.getExternalStorageDirectory();
externalStorageDirectory= new File(externalStorageDirectory , "FOLDERNAME");
if(!createDirIfNotExists(externalStorageDirectory)){
Toast.makeText(this,"Failed creating Directory!",Toast.LENGTH_SHORT).show();
}else{
File filename=new File(externalStorageDirectory, String.valueOf(Calendar.getInstance().getTimeInMillis())+".PNG");
FileOutputStream out = null;
try {
out = new FileOutputStream(filename);
cropped.compress(Bitmap.CompressFormat.PNG, 100, out); // cropped is your Bitmap instance
// PNG is a lossless format, the compression factor (100) is ignored
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (out != null) {
out.close();
Intent returnIntent = new Intent();
returnIntent.putExtra("picture", Uri.fromFile(filename));
setResult(RESULT_OK, returnIntent);
finish();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
//Toast.makeText(this,mCropImageUri.toString(),Toast.LENGTH_SHORT).show();
}
And Activity A had:
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
if (requestCode == 999 && resultCode==RESULT_OK) {
Uri path=data.getParcelableExtra("picture");
Bitmap bitmap=null;
try {
bitmap= MediaStore.Images.Media.getBitmap(this.getContentResolver(), path);
} catch (IOException e) {
e.printStackTrace();
}
Toast.makeText(this,path.toString(),Toast.LENGTH_SHORT).show();
if (bitmap!=null){
iv_profile_pic.setImageBitmap(bitmap);
}
}
Maybe my problem statement is wrong, but workaround works. Any edits/suggestions
are 100% welcome. Just in-case someone like me gets stuck, this might help!

Android Studio - Long delay when selecting image through gallery

New to Android Studio, just wondering if anyone can help on this delay when I send an image that is taken from the gallery. Once image is selected there is a long delay until it is actually sent, and for a moment the screen goes black as well.
Here is the code - thanks
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.launch_voip_call) {
Utils.startCall(this, contact);
return true;
} else if (item.getItemId() == R.id.launch_camera) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("Pick Image from")
.setCancelable(false)
.setPositiveButton("Camera", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
//camera intent
Intent cameraIntent = new Intent(ConversationActivity.this, CameraActivity.class);
cameraIntent.putExtra("EXTRA_CONTACT_JID", contact.getJid());
startActivity(cameraIntent);
}
})
.setNegativeButton("Gallery", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
Intent intent = new Intent();
// Show only images, no videos or anything else
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
// Always show the chooser (if there are multiple options available)
startActivityForResult(Intent.createChooser(intent, "Select Picture"), PICK_IMAGE_REQUEST);
}
});
AlertDialog alert = builder.create();
alert.show();
}
return false;
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == PICK_IMAGE_REQUEST && resultCode == RESULT_OK && data != null && data.getData() != null) {
Uri uri = data.getData();
try {
Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), uri);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.WEBP, 5, stream);
byte[] byteArray = stream.toByteArray();
// Log.d(TAG, String.valueOf(bitmap));
EventBus.getDefault().post(new MessageEvent.SendMessage(contact.getJid(), byteArray, ""));
} catch (IOException e) {
e.printStackTrace();
}
}
}
#OnTextChanged(R.id.compose)
public void onMessageChanged(CharSequence s) {
sendButton.setVisibility(s.length() > 0 ? View.VISIBLE : View.INVISIBLE);
}
#OnClick(R.id.send)
public void onSend(final View view) {
String message = composeText.getText().toString().trim();
if (!message.isEmpty()) {
if (!amIOffline()) {
EventBus.getDefault().post(new MessageEvent.SendMessage(contact.getJid(), message));
composeText.setText("");
} else {
SimpleSnackbar.offlineGroupChat(view).show();
}
}
}
On Activity result is on Main Thread.. Compressing Image can take time.. Try to use AsyncTask to achieve compression in background and then send image in background as well.. Dont perform Compression on MainThread thats why you are getting long delay..
Let me know if you need code??
public class ImageSendingAsync extends AsyncTask<Bitmap,Void,Void> {
#Override
protected Void doInBackground(Bitmap... params) {
try {
Bitmap bitmap = params[0];
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.WEBP, 5, stream);
byte[] byteArray = stream.toByteArray();
// Log.d(TAG, String.valueOf(bitmap));
EventBus.getDefault().post(new MessageEvent.SendMessage(contact.getJid(), byteArray, ""));
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
//This will go in Activity Result
if (requestCode == PICK_IMAGE_REQUEST && resultCode == RESULT_OK && data != null && data.getData() != null) {
Uri uri = data.getData();
Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), uri);
new ImageSendingAsync().execute(bitmap);
}
I think the compress takes a while and thats why ur MainThread are not able to draw the Layout -> Black Screen.
maybe test the time it take to compress the pic.
if the time is to long, use ASyncTask.
[...]
long timeStart = System.currentTimeMillis();
bitmap.compress(Bitmap.CompressFormat.WEBP, 5, stream);
long timeEnd = System.currentTimeMillis();
Log.e("resizePicture Timer", "resize took " + (timeEnd - timeStart) + "ms");
[...]

how can I upload a photo from the gallery to parse.com?

I am trying to upload a photo from the gallery into my parse cloud but I can't figure it out here's my code and what I've done so far .
I've looked everywhere still can't find a solution , can't upload the photo :\
help me please.
public void loadImagefromGallery(View view) {
// Create intent to Open Image applications like Gallery, Google Photos
Intent galleryIntent = new Intent(Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
// Start the Intent
startActivityForResult(galleryIntent, RESULT_LOAD_IMG);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
try {
// When an Image is picked
if (requestCode == RESULT_LOAD_IMG && resultCode == RESULT_OK
&& null != data) {
// Get the Image from data
Uri selectedImage = data.getData();
myBitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), selectedImage);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
myBitmap.compress(Bitmap.CompressFormat.JPEG, 100, bos);
byte[] scaledData = bos.toByteArray();
photoFile = new ParseFile("my_photo.jpg", scaledData);
photoFile.saveInBackground(new SaveCallback() {
public void done(ParseException e) {
if (e != null) {
Toast.makeText(getApplicationContext(),
"Error saving: " + e.getMessage(),
Toast.LENGTH_LONG).show();
} else {
// do something
}
}
});
Save ParseObject in the background
// Create the ParseFile
ParseFile file = new ParseFile("androidbegin.png", image);
// Upload the image into Parse Cloud
file.saveInBackground();
// ParseObject
ParseObject pObject = new ParseObject("ExampleObject");
// Create a column named "ImageName" and set the string
pObject.put("ImageName", "image name here");
// Create a column named "ImageFile" and insert the image
pObject.put("ImageFile", file);
pObject.saveInBackground(); // asynchronous, no callback
Save in the background with callback
pObject.saveInBackground(new SaveCallback () {
#Override
public void done(ParseException ex) {
if (ex == null) {
isSaved = true;
} else {
// Failed
isSaved = false;
}
}
});

How to process a photo taken by an intent?

I'm completely news on android thing and unfortunately with little few time to learn it by the right way, I have a work to release.
The problem is: I need to take a picture and process her with an algorithm that I made.
I did it by the easiest way that I could find, I know it looks like really trahsie for those who really get android (sorry)
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
takePic();
protected void takePic(){
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(takePictureIntent, 100);
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Bundle extras = data.getExtras();
mImageBitmap = (Bitmap) extras.get("data");
Algorithm(mImageBitmap)
But it doesn't process, it takes a photo, ask to save or cancell and leaves the application, I have already made by different ways (creating a new activity), but nothing seems to work
Heres how I did it
To go to the camera:
Somewhere, declaire a fileUri variable and hold onto it
Uri fileUri;
final int TAKE_PICTURE=100;//this can be any int, really
public void goToCamera(){
Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
File photo;
try
{
// place where to store camera taken picture
photo = this.createTemporaryFile("picture", ".jpg");
Log.v(TAG, "Here(after createTempFile)");
photo.delete();
}
catch(Exception e)
{
Log.v(TAG, "Can't create file to take picture!" + e.getMessage());
Toast.makeText(context, "Please check SD card!", Toast.LENGTH_SHORT).show();
return;
}
fileUri = Uri.fromFile(photo);
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
//Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, TAKE_PICTURE);
}
Then to retreive the image
protected void onActivityResult(int requestCode, int resultCode, Intent data){
if (requestCode == TAKE_PICTURE && resultCode == RESULT_OK){
this.getContentResolver().notifyChange(uri, null);
ContentResolver cr = this.getContentResolver();
Bitmap bitmap;
try
{
BitmapFactory.Options ops = new BitmapFactory.Options();
ops.inSampleSize = 4;
bitmap = BitmapFactory.decodeFile(uri.getPath().toString(), ops);
}
catch (Exception e)
{
Toast.makeText(this, "Failed to load", Toast.LENGTH_SHORT).show();
Log.d(TAG, "Failed to load", e);
}
}
}
The create temp file mentioned above:
private File createTemporaryFile(String part, String ext) throws Exception
{
File tempDir= Environment.getExternalStorageDirectory();
tempDir=new File(tempDir.getAbsolutePath()+"/.temp/");
Log.i(TAG, tempDir.toString());
if(!tempDir.exists())
{
Log.i(TAG, "Dir doesnt exist");
tempDir.mkdirs();
}
return File.createTempFile(part, ext, tempDir);
}
I realize this isn't probably as simple as you were hoping for, but this approach seemed to be as flexible and compatible as possible. Let me know if I left anything else out

Compress a camera image and save it in Sqlite in android

i need to save a camera image from sd card to sqlite in android. The problem i am facing is out of memory exception. How i can compress this image and sav it in sqlite. The image format is jpeg
thanks in advance
jibysthomas
I do not know if this is the best way to save storage space using SQLite and I am still looking for it, but here we go.
You can select the source of your image, such as gallery or camera and below is the code.
private void selectProductImage() {
final CharSequence[] itens = {"Use Camera", "Gallery", "Cancel"};
AlertDialog.Builder builder = new AlertDialog.Builder(this,R.style.AlertDialog);
builder.setItems(itens, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
if (itens[which].equals("Use Camera")) {
Toast.makeText(YourActivity.this, "Use Camera", Toast.LENGTH_SHORT).show();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(new String[]{Manifest.permission.CAMERA}, MY_CAMERA_PERMISSION_CODE);
} else {
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cameraIntent, CAMERA_REQUEST);
}
} else if (itens[which].equals("Gallery")) {
Toast.makeText(YourActivity.this, "Gallery", Toast.LENGTH_SHORT).show();
Intent galleryIntent = new Intent();
galleryIntent.setAction(Intent.ACTION_GET_CONTENT);
galleryIntent.setType("image/*");
startActivityForResult(galleryIntent, REQUEST_GALLERY_PHOTO);
} else if (itens[which].equals("Cancel")) {
dialog.dismiss();
}
}
});
builder.show();
}
Maybe you need permission to use the camera
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == MY_CAMERA_PERMISSION_CODE) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//Toast.makeText(this, "camera permission granted", Toast.LENGTH_LONG).show();
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cameraIntent, CAMERA_REQUEST);
} else {
Toast.makeText(this, "camera permission denied", Toast.LENGTH_LONG).show();
}
return;
}
}
Here is how to handle the image from the source you selected.
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == CAMERA_REQUEST && resultCode == Activity.RESULT_OK) {
Bitmap bitmap = Bitmap.createScaledBitmap((Bitmap) data.getExtras().get("data"),96, 96, true);
mProductImage.setImageBitmap(bitmap);
isPriviteImage = true;
}
if (requestCode == REQUEST_GALLERY_PHOTO && resultCode == RESULT_OK && data != null) {
//mProductImage.setImageURI(data.getData());
// INSERT IMAGE INTO SQLite
Uri uri = data.getData();
try {
InputStream inputStream = getContentResolver().openInputStream(uri);
Bitmap bitmap = Bitmap.createScaledBitmap(BitmapFactory.decodeStream(inputStream),96, 96, true);
mProductImage.setImageBitmap(bitmap);
isPriviteImage = true;
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
As you can notice in my example, there is no place to save the image case you selected camera and I placed the image on an ImageView variable named mProductImage.
From now, you can use a Button to save the image in your SQLite Database. Here is the function you can use for it.
private void saveImage() {
productTablePath = Environment.getExternalStorageDirectory()+"/YourAditionalPath/";
ProductDatabaseHelper productDatabaseHelper = new ProductDatabaseHelper(getApplicationContext(), "dbname.db", productTablePath);
productListTable = productDatabaseHelper.getWritableDatabase();
productRepository = new ProductRepository(productListTable);
try {
if (isPriviteImage) {
productRepository.addProduct(imageViewToByte(mProductImage));
isPriviteImage = false;
} else {
productRepository.addProduct(null);
}
mProductImage.setImageResource(R.drawable.shopping_cart_black_48dp);
} catch (Exception e) {
e.printStackTrace();
}
}
Where imageViewToByte functon is:
private byte[] imageViewToByte(CircleImageView image) {
Bitmap bitmap = ((BitmapDrawable)image.getDrawable()).getBitmap();
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG,100,stream);
byte[] byteArray = stream.toByteArray();
return byteArray;
}
Now you need to implement the SQLiteOpenHelper. You need to create a new class for this. The java file name I used for this was ProductDatabaseHelper.java.
public class ProductDatabaseHelper extends SQLiteOpenHelper {
private static int dbVersion = 1;
public ProductDatabaseHelper(Context context, String name, String storageDirectory) {
super(context, storageDirectory+name, null, dbVersion);
}
#Override
public void onCreate(SQLiteDatabase db) {
StringBuilder sql = new StringBuilder();
sql.append("CREATE TABLE IF NOT EXISTS PRODUCTLIST (");
sql.append(" IMAGE BLOB,");
db.execSQL(sql.toString());
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
Now you need to implement your CRUD (Create new item, Read, Update and Delete).
public class ProductRepository {
SQLiteDatabase instance;
public ProductRepository(SQLiteDatabase instance) {
this.instance = instance;
}
public void addProduct(byte[] image){
ContentValues contentValues = new ContentValues();
contentValues.put("IMAGE",image);
instance.insertOrThrow("PRODUCTLIST",null, contentValues);
}
}
It is important to mention that the compression of the image was made in the onActivityResult() for both source image (camera and gallery).
with the command:
Bitmap bitmap = Bitmap.createScaledBitmap(capturedImage, width, height, true);
Besides that, here is a link where we can read a little bit about compression.
https://androidwave.com/capture-image-from-camera-gallery/
If you have a better way to compress images to save in SQLite Database, please post your code here!

Categories

Resources