I have a fragment that contains an image view and button when I click on the button am going to an activity that has an image as a bitmap and in the activity, I have a button (save) that should finish the activity and go back to the fragment with the bitmap data.
I tried to use intents and bundles but nothing worked.
You need to convert your Bitmap data to an byte array then put it into the Bundle
ByteArrayOutputStream mStream = new ByteArrayOutputStream();
yourBitmapImage.compress(Bitmap.CompressFormat.PNG, 100, mStream);
byte[] byteArray = mStream.toByteArray();
Bundle mBundle = new Bundle();
mBundle.putByteArray("image",byteArray);
Passing Bitmap Object via bundle intents is very dangerous and you may end up getting errors especially for bitmaps of uknown lengths since there is even a limit for the size of the Parcelable extra.its highly unrecomended .Better solution would be to save it to a file then the path to a String value and pass it to the next activity or even to shared prefrence just in case it might be needed even after the app closes or even needed elsewhere in your code without using up your memory.Bitmaps especially are a great threat to memory if mishandled.See
public class Bitmap_saver{
public static String my_bitmap_path(Context act) {
SharedPreferences prefs = act.getSharedPreferences("SHAREDpREFname", act.MODE_PRIVATE);
return prefs.getString("my_bitmap_address", null);
}
public static void set_my_bitmap_address(Context act, String path) {
SharedPreferences.Editor saver = act.getSharedPreferences("SHAREDpREFname", act.MODE_PRIVATE).edit();
saver.putString("my_bitmap_address", path);
saver.commit();
}
public static String save_to_file(Bitmap fpb)
{
String img_name="BIT_"+ System.currentTimeMillis()+".JPG";
OutputStream fOutputStream = null;
File file = new File( Environment.getExternalStorageDirectory().toString() + "/YOUR_APP_DATA/");
if (!file.exists()) {
Log.e("Creating data dir=>",""+ String.valueOf(file.mkdirs()));
}
file = new File(Environment.getExternalStorageDirectory().toString() + "/YOUR_APP_DATA/", img_name);
try {
fOutputStream = new FileOutputStream(file);
fpb.compress(Bitmap.CompressFormat.JPEG, 100, fOutputStream);
fOutputStream.flush();
fOutputStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
return "error";
} catch (IOException e) {
e.printStackTrace();
// Toast.makeText(this, "Save Failed", Toast.LENGTH_SHORT).show();
return "error";
}
return file.getAbsolutePath();
}
}
Call it like this to save Bitmap_saver.set_my_bitmap_path(your_context,Bitmap_saver.save_to_file(your_bitmap));
from your retreiving fragment/activity/class call this Bitmap myBitmap = BitmapFactory.decodeFile(Bitmap_saver.my_bitmap_path(your_context));
I end up using this approach:
in your fragment:
Intent signatureIntent = new Intent(getActivity(), SignatureActivity.class);
startActivityForResult(signatureIntent, your_request_code);
#Override
public void onActivityResult(int requestCode, int resultCode,
#Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == your_request_code&& resultCode == Activity.RESULT_OK){
String received = data.getStringExtra("extra");
byte[] decodedString = Base64.decode(received, Base64.DEFAULT);
Bitmap decodedByte = BitmapFactory.decodeByteArray(decodedString, 0,
decodedString.length);
}
}
in your activity:
bitmap = signatureView.getSignatureBitmap();
Intent resultIntent = new Intent();
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOutputStream);
byte[] byteArray = byteArrayOutputStream.toByteArray();
String encoded = Base64.encodeToString(byteArray, Base64.DEFAULT);
resultIntent .putExtra("extra",encoded);
setResult(Activity.RESULT_OK, resultIntent);
finish();
I want to store data into the database and want to upload an image in optional.
It means that if i am inserting the record without adding image then it will store in database without the image name.
right now when i am fill the data and insert an image then it is storing in the database if i don't select any image and i add only data then in database the data is not inserted and showing me blank value in every field
I tried a lot but not getting the required output.
My code main.java
buy_image1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
selectImage();
edit.putInt("ImageID", 1);
edit.commit();
}
});
public void selectImage()
{
i = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(i, RESULT_LOAD_IMAGE);
/*i.putExtra("crop", "true");
i.putExtra("outputX", 512);
i.putExtra("outputY", 512);
i.putExtra("aspectX", 1);
i.putExtra("aspectY", 1);
i.putExtra("scale", true);
*/
}
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == RESULT_LOAD_IMAGE && resultCode == getActivity().RESULT_OK && null != data) {
final int IMAGE_MAX_SIZE = 1200000; // 1.2MP
Uri selectedImage = data.getData();
int imgid = 0;
String[] filePathColumn = {MediaStore.MediaColumns.DATA};
Cursor cursor = getActivity().getContentResolver().query(selectedImage, filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
picturePath = cursor.getString(columnIndex);
cursor.close();
Log.d("Value", picturePath);
fileName = new File(picturePath).getName();
// imgname.setText(fileName);
String fileNameSegments[] = picturePath.split("/");
fileName = fileNameSegments[fileNameSegments.length - 1];
// MyParams.put("filename", fileName);
Bitmap yourSelectedImage = BitmapFactory.decodeFile(picturePath);
sp = getActivity().getSharedPreferences("Image ID", Context.MODE_PRIVATE);
imgid = sp.getInt("ImageID", 0);
Log.d("IMGID", Integer.toString(imgid));
BitmapFactory.Options options =null;
options = new BitmapFactory.Options();
options.inSampleSize = 5;
bitmap = BitmapFactory.decodeFile(picturePath, options);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 85, stream);
byte[] byte_arr = stream.toByteArray();
// Encode Image to String
encodedString = Base64.encodeToString(byte_arr, 0);
if(imgid == 1) {
buy_image1.setImageBitmap(yourSelectedImage);
img1 = fileName;
encodedStringIMG1 = encodedString;
}else if(imgid == 2){
buy_image2.setImageBitmap(yourSelectedImage);
img2 = fileName;
encodedStringIMG2 = encodedString;
}
else{
Log.d("IMGID","IMAGE ID IS 0");
}
}
private void InsertWodinformation() {
service(strwodname,strbranch,strcontactperson,strcontact,strwhatsapp,stremail,
strspinnercity,straddress,opendate1,birthdate,ani,strpancard,strtinnumber,strbankname,strbankholdername,strbankac,
strbankcity, strifsccode,strsecuritycheque,strrefrence1,strrefrence2,strremarks,img1,encodedStringIMG1,img2,encodedStringIMG2);
}
private void service(
String strwodname,String strbranch,
String strcontactperson, String strcontact,
String strwhatsapp, String stremail, String strspinnercity,
String straddress, String opendate1, String birthdate, String ani,
String strpancard, String strtinnumber, String strbankname, String strbankholdername
,String strbankac,String strbankcity, String strifsccode,String strsecuritycheque,String strrefrence1,
String strrefrence2,String strremarks,String i1,String encode1,String i2,String encode2
) {
class AddVisitclass extends AsyncTask<String, Void, String> {
ProgressDialog loading;
RegisterUserClass ruc = new RegisterUserClass();
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected String doInBackground(String... params) {
HashMap<String, String> param = new HashMap<String, String>();
/*param.put("firm", params[1]);
param.put("oname", params[2]);
param.put("pname1", params[3]);
param.put("pname2", params[4]);
*/
param.put("wname", params[0]);
param.put("branch", params[1]);
param.put("cname", params[2]);
param.put("contact", params[3]);
param.put("whatsapp", params[4]);
param.put("email", params[5]);
param.put("city", params[6]);
param.put("address", params[7]);
param.put("odate", params[8]);
param.put("bdate", params[9]);
param.put("adate", params[10]);
param.put("pancard", params[11]);
param.put("tinno", params[12]);
param.put("bnm", params[13]);
param.put("bank_ac_holder", params[14]);
param.put("bank_ac_no", params[15]);
param.put("bcity", params[16]);
param.put("ifsc_code", params[17]);
param.put("cheque", params[18]);
param.put("ref1", params[19]);
param.put("ref2", params[20]);
param.put("remarks", params[21]);
param.put("pan", params[22]);
param.put("epan", params[23]);
param.put("aadhar", params[24]);
param.put("eaadhar", params[25]);
/*
param.put("light", params[26]);
param.put("elight", params[27]);
param.put("vat", params[28]);
param.put("evat", params[29]);
param.put("vcard", params[30]);
param.put("evcard", params[31]);
param.put("shop", params[32]);
param.put("eshop", params[33]);
*/
param.put("username",uid);
String result = ruc.sendPostRequest(url_addwod, param);
Log.d("Result", result);
Log.d("Data", param.toString());
return result;
}
//#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
//loading.dismiss();
Toast.makeText(getActivity(), "W.O.D. added successfully...!!!", Toast.LENGTH_LONG).show();
/* FragmentTransaction t = getActivity().getSupportFragmentManager().beginTransaction();
TabFragment mFrag = new TabFragment();
t.replace(com.Weal.sachin.omcom.R.id.framelayout, mFrag);
t.commit();
*/
}
}
AddVisitclass regi = new AddVisitclass();
regi.execute(strwodname,strbranch,strcontactperson,strcontact,strwhatsapp,stremail,
strspinnercity,straddress,opendate1,birthdate,ani,strpancard,strtinnumber,strbankname,strbankholdername,strbankac,
strbankcity, strifsccode,strsecuritycheque,strrefrence1,strrefrence2,strremarks,i1,encode1,i2,encode2);
}
And one more thing when image is uploading to the server it is generating the lower size but i want it in default size.
The best way to store images/files data is to save the images to the device storage resource (e.g internal memory or external),then you have the image URL/URI saved in your database (instead of having blob field in the database), and to display it all you have to do is to retrieve the file URL and display it on the device.
I hope this gives you a better solution for this issue.
The best way to save images are save them in your computer or device you are using and pass the path (location) of the image through a sql query to the database and when you want to access the image get the location of the image from the database and display.
following link will help you to understand
http://www.androidhive.info/2011/11/android-sqlite-database-tutorial/
Consider first compressing your images, to reduce the size of the image for storage. You have three options here, first you can get the base64 representation of the image, which is a string then store it , or get the byte array output and still store it. And lastly store the uri reference for the image located on the phone. Though i would not recommend this approach, because it is subjected to path changes and user deletion.
Here is a great library that uses google webp.WebP is a modern image format that provides superior lossless and lossy compression for images.WebP lossless images are 26% smaller in size compared to PNGs. WebP lossy images are 25-34% smaller than comparable JPEG images at equivalent SSIM quality index. Link to library.
Here is a galore of code snippets that can perform your request!
private static String CompressJPEG(Bitmap bitmap) {
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream);
byte[] byteFormat = stream.toByteArray();
return Base64.encodeToString(byteFormat, Base64.DEFAULT);
}
private static byte[] CompressJPEGByteArray(Bitmap bitmap) {
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream);
return stream.toByteArray();
}
private static String CompressPNG(Bitmap bitmap) {
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] byteFormat = stream.toByteArray();
return Base64.encodeToString(byteFormat, Base64.DEFAULT);
}
private static byte[] CompressPNGByteArray(Bitmap bitmap) {
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
return stream.toByteArray();
}
private static Bitmap RevertImageBase64(String encodedImage) {
byte[] decodedString = Base64.decode(encodedImage, Base64.DEFAULT);
return BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length);
}
public static Bitmap RevertFromByteArray(byte[] arr) {
return BitmapFactory.decodeByteArray(arr, 0, arr.length);
}
Here is also code to get the extension from a uri.
public static void GetExtensionFromContentURI(Context context, Uri uri) {
ContentResolver cR = context.getContentResolver();
MimeTypeMap mime = MimeTypeMap.getSingleton();
String ext = mime.getExtensionFromMimeType(cR.getType(uri));
}
Hope this helps :)
You have to covert bitmap to BLOB format to save it ti db llook below
code :
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, byteArrayOutputStream);
byte[] byteArray = byteArrayOutputStream.toByteArray();
String encodedData = Base64.encodeToString(byteArray, Base64.DEFAULT);
dba.insertPhoto(byteArray);
Regarding the size issue you mentioned, in onActivityResult(), the statement:
options.inSampleSize = 5;
could be the reason for the file to be smaller than the original image.
This is needed for the ImageView. Before compressing, keep a non compressed coopy for transmission to the server.
To troubbleshoot the insert of the image you need to post:
If the column in the database is defined as "not null"
A Log.d() of the value it is sending to the server when no picture is selected.
The code on the server that receives the data and performs runs the insert.
Refactoring code like below might help you. Don't take method names, variable names and other parts as a real example. I wanted to give you a bird-eye view of sample design.
//controller of user request.
handleRequest(){
String imagePath=null;
if(imageExists){ //if user sent image to server.
imagePath=saveImageAndReturnImagePath(...);
}
saveRecordToDB(request.getText(), imagePath);
}
//save image to disk and return image path.
private String saveImageAndReturnImagePath(...){
//do image manipulation here, save image to disk, return path.
return imagePath;
}
//insert a new record to db.
private void saveRecordToDB(String text, imagePath){
Record a=new Record(text, imagePath);
dao.save(a);
}
The simplest way to cache images . is to use JakeWharton/picasso2-okhttp3-downloader
Here's an example :
OkHttpClient okHttpClient = new OkHttpClient();
okHttpClient.networkInterceptors().add(new Interceptor() {
#Override
public Response intercept(Chain chain) throws IOException {
Response originalResponse = chain.proceed(chain.request());
return originalResponse.newBuilder().header("Cache-Control", "max-age=" + (60 * 60 * 24 * 365)).build();
}
});
try{
okHttpClient.setCache(new Cache(this.getCacheDir(), Integer.MAX_VALUE));
OkHttpDownloader okHttpDownloader = new OkHttpDownloader(okHttpClient);
Picasso picasso = new Picasso.Builder(this).downloader(okHttpDownloader).build();
picasso.load("pucul").error(R.drawable.teacher).into(imgvw);
}
catch (Exception e){
add this to your gradle file
compile 'com.jakewharton.picasso:picasso2-okhttp3-downloader:1.1.0'
Source :
I have an activity to choose and save a profile picture. There is an image view and a button that starts the gallery activity for result awiting the user to choose an image. When the gallery is closed, the following code is executed:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if ((resultCode == RESULT_OK) && (requestCode == SELECT_PHOTO)) {
Uri selectedImage = data.getData();
try {
Bitmap image = this.decodeAndScaleImage(selectedImage, 285);
imgInsertPicture.setImageBitmap(image);
this.imagePresent = true;
this.saveMyProfilePicture(image);
this.popImageView();
} catch (IOException e) {
e.printStackTrace();
showToast(R.string.error_saving_picture);
}
}
}
private void saveMyProfilePicture(Bitmap picture) throws IOException {
FileOutputStream outputStream = openFileOutput(Globals.MY_PICTURE_FILE_NAME, MODE_PRIVATE);
picture.compress(Globals.MY_PICTURE_FORMAT, 90, outputStream);
outputStream.close();
ByteArrayOutputStream rawOutputStream = new ByteArrayOutputStream();
picture.compress(Globals.MY_PICTURE_FORMAT, 90, rawOutputStream);
byte[] rawPictureData = rawOutputStream.toByteArray();
rawOutputStream.close();
byte[] base64PictureData = Base64.encode(rawPictureData, Base64.DEFAULT);
rawPictureData = null;
FileOutputStream base64OutputStream = openFileOutput(Globals.MY_PICTURE_B64_FILE_NAME, MODE_PRIVATE);
base64OutputStream.write(base64PictureData);
base64OutputStream.close();
}
I debugged this code and verified that:
- no exception is thrown;
- the written files contain the exact amount of data (17kB for the jpg image, 24kB for the base64 version);
- the produced bitmap is the one that I expect and is displayed correctly in the image view.
popImageView is only used to bump the image view on top of other views that were on the front before an image was chosen; and decodeAndScale method only works on bitmap data in memory and doesn't save anything.
However, when I try to reload the current picture when the activity starts, the image displayed is blank and the jpeg file conly contains 3 bytes:
#Override
public void onStart() {
super.onStart();
if (!imagePresent && pictureExists()) {
File pictureFile = new File(getFilesDir(), Globals.MY_PICTURE_FILE_NAME);
imgInsertPicture.setImageURI(Uri.fromFile(pictureFile));
popImageView();
imagePresent = true;
}
}
Here pictureExists checks that the file name is contained in the collection returned by listFiles(). pictureFile.exists() returns true, but as I said, it conly contains 3 bytes. I also tried using BitmapFactory.decodeX, but since the file is broken, it was useless.
I cannot understand why. I checked that the file was written entirely and then it disappears...
When I was debugging on my Nexus S the code worked fine, but then I switched to a Nexus 5 and it broke.
Have you tried decoding the file to a bitmap using BitmapFactory?
http://developer.android.com/reference/android/graphics/BitmapFactory.html#decodeFile(java.lang.String)
Haven't tested the following code but can you please try:
File pictureFile = new File(getFilesDir(), Globals.MY_PICTURE_FILE_NAME);
Bitmap bitmapImage = BitmapFactory.decodeFile(Uri.fromFile(pictureFile));
imgInsertPicture.setImageBitmap(bitmapImage);
popImageView();
imagePresent = true;
Try this in your onActivityResult
Uri selectedImage = data.getData();
String[] filePathColumn = {MediaStore.Images.Media.DATA};
Cursor cursor = getActivity().getContentResolver().query(
selectedImage, filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
String filePath = cursor.getString(columnIndex);
cursor.close();
selectedImagePath =filePath;
then use selectedImagePath as file path.
Hope it helps.