I'm trying to get an image from the Gallery and send it to a server.
I do get an base64 encoded string but it's a thin line, not the whole image.
For example, I used Motobit to decode this random image. The base64 string I got
works fine. But the encoded string that I get from my app for the same image is really smaller and when you convert into an image it becomes this.
Here is my code:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_create_profile);
Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);
photoPickerIntent.setType("image/*");
startActivityForResult(photoPickerIntent, SELECT_PHOTO);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent imageReturnedIntent) {
super.onActivityResult(requestCode, resultCode, imageReturnedIntent);
switch(requestCode) {
case SELECT_PHOTO:
if(resultCode == RESULT_OK){
try {
Uri selectedImage = imageReturnedIntent.getData();
String imageStream = getRealPathFromURI(context, selectedImage);
Bitmap bitmap = BitmapFactory.decodeFile(imageStream);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOutputStream);
byte[] byteArray = byteArrayOutputStream .toByteArray();
String encodedString = Base64.encodeToString(byteArray, Base64.DEFAULT);
Log.e(LOG_TAG, encodedString);
}catch (Exception e){
e.printStackTrace();
}
}
}
}
public String getRealPathFromURI(Context context, Uri contentUri) {
Cursor cursor = null;
try {
String[] proj = { MediaStore.Images.Media.DATA };
cursor = context.getContentResolver().query(contentUri, proj, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
} finally {
if (cursor != null) {
cursor.close();
}
}
}
What is making my encodedString becomes only a piece of the image? Thanks!
Maybe the string is correct but the Log method has a character limit.
Related
I want to create a similar function as below image. Allow user to select image / pdf file from device and convert the file into inputstream as string and sent to server. I had go through this Attaching a file of any type in Android application? and successfully to call for document but does not have option for camera. Appreciate if there any source i can refer or library that able to perform this: provide option to select from gallery/take new photo/document Select file and convert to string (inputstream)
//Json that server going to receive
"Attachment": {
"InputStream": "string",
"FileName": "string"
}
/*My Code*/
public void goToAttachment(){
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/*|application/pdf");
startActivityForResult(Intent.createChooser(intent, null), SELECTFILE_RESULT_CODE);
}
#Override
public void onActivityResult(int requestCode, int resultCode, #Nullable Intent data){
switch (requestCode){
case SELECTFILE_RESULT_CODE:
if(resultCode == RESULT_OK){
fileSrc = data.getData().getPath();
}
break;
}
}
You can use below code to get first Bitmap of Image and then get String from Bitmap Object:
#Override
public void onActivityResult(int requestCode, int resultCode, #Nullable Intent data){
switch (requestCode){
case SELECTFILE_RESULT_CODE:
if(resultCode == RESULT_OK){
// Let's read picked image data - its URI
Uri pickedImage = data.getData();
// Let's read picked image path using content resolver
String[] filePath = { MediaStore.Images.Media.DATA };
Cursor cursor = getContentResolver().query(pickedImage, filePath, null, null, null);
cursor.moveToFirst();
String imagePath = cursor.getString(cursor.getColumnIndex(filePath[0]));
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
Bitmap bitmap = BitmapFactory.decodeFile(imagePath, options);
String bmpString= bitMapToString(bitmap)
cursor.close();
}
break;
}
}
You can use below method to convert Bitmap to String:
public String bitMapToString(Bitmap bitmap){
ByteArrayOutputStream baos=new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG,100, baos);
byte [] b=baos.toByteArray();
String temp=Base64.encodeToString(b, Base64.DEFAULT);
return temp;
}
you can change Bitmap Compress format JPG or PNG as par your image.
For PDF and other file you can use below method to convert it into String.
private String getString(String filepath) throws IOException {
InputStream inputStream = new FileInputStream(filepath);
byte[] byteArray = IOUtils.toByteArray(inputStream);
String encoded = Base64.encodeToString(byteArray, Base64.DEFAULT);
return encoded;
}
To get File path you can use bellow code:
public String getRealPathFromURI(Context context, Uri contentUri) {
Cursor cursor = null;
try {
String[] proj = { MediaStore.Images.Media.DATA };
cursor = context.getContentResolver().query(contentUri, proj, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
} finally {
if (cursor != null) {
cursor.close();
}
}
}
I want to allow user to upload image from gallery into an android application that i am creating. At the moment i am able to allow the user to chose the image from the gallery here in the codes below:
/* Choose an image from Gallery */
void openImageChooser() {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select Picture"), PICK_IMAGE);
}
Then onActivityResult i try to get the path of the image and convert it into URI then i later convert it into into Bitmap to display to the user in my codes below:
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
if (requestCode == PICK_IMAGE) {
// Get the url from data
Uri selectedImageUri = data.getData();
if (null != selectedImageUri) {
// Get the path from the Uri
String path = getPathFromURI(selectedImageUri);
Log.i(TAG, "Image Path : " + path);
// Set the image in ImageView
profileImage.setImageURI(selectedImageUri);
}
final InputStream imageStream;
try {
assert selectedImageUri != null;
imageStream = getContentResolver().openInputStream(selectedImageUri);
final Bitmap selectedImage = BitmapFactory.decodeStream(imageStream);
encodedImage = encodeImage(selectedImage);
Log.i("encodedImage", encodedImage);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
}
public String getPathFromURI(Uri contentUri) {
String res = null;
String[] proj = {MediaStore.Images.Media.DATA};
Cursor cursor = getContentResolver().query(contentUri, proj, null, null, null);
if (cursor.moveToFirst()) {
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
res = cursor.getString(column_index);
}
cursor.close();
return res;
}
private String encodeImage(Bitmap bm)
{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bm.compress(Bitmap.CompressFormat.JPEG,100,baos);
byte[] b = baos.toByteArray();
String encImage = Base64.encodeToString(b, Base64.DEFAULT);
return encImage;
}
On click of this button below i want to save the encoded image into SharedPreferences so when the user starts the application again i can show that image to the user but unfortunately i am unable to get the encoded image and i don't know how to set it on onCreateView method.
btnAddImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
SharedPreferences.Editor editor = prefs.edit();
editor.putString("image", encodedImage);
editor.apply();
showSnackSuccess();
}
});
I'm trying to load an image from the gallery, but toSave.recycle() doesn't work.
I mean when toSave.recycle() is called the screen becomes white, the app doesn't crash but the image is not shown.
Do you have any suggestions?
Here the code:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == LOAD_IMAGE_RESULT && resultCode == RESULT_OK && data != null) {
Uri pickedImage = data.getData();
String[] filePath = { MediaStore.Images.Media.DATA };
Cursor cursor = getContentResolver().query(pickedImage, filePath, null, null, null);
cursor.moveToFirst();
String imagePath = cursor.getString(cursor.getColumnIndex(filePath[0]));
Bitmap bitmap = BitmapFactory.decodeFile(imagePath);
postImage.setImageBitmap(bitmap);
saveImage(bitmap);
cursor.close();
}
}
Here the method that converts bitmap image and save it in Firebase.
public void saveImage(Bitmap toSave){
if (toSave!=null) {
ByteArrayOutputStream stream = new ByteArrayOutputStream();
toSave.compress(Bitmap.CompressFormat.JPEG, 50, stream);
toSave.recycle();
byte[] byteArray = stream.toByteArray();
String imageString = Base64.encodeToString(byteArray, Base64.DEFAULT);
simplepostRef.child("image").setValue(imageString);
}
Thank you a lot!
bitmap.recycle() is working in your case. You just dont need to recycle the bitmap because you are showing this bitmap in a imageview.Have a look at the docs.
In android, I open a bitmap from the image picker, and load it into a imageview. If the user selects a big image, the app will crash. I tried try/catch, but it didn't work.
Is there a way to check the file size before loading it into a bitmap?
This is the code:
This is the return function from when I choose an image
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
ImageUploadHandler.handleResult(this, data);
}
}
this is from another file
public void handleResult(Context context, Intent data) {
Bitmap bitmap = null;
try {
bitmap = MyImage.GetBitmapFromPath(context, data.getData());
ByteArrayOutputStream out = new ByteArrayOutputStream();
bitmap.compress(CompressFormat.PNG, 100, out);
int size = out.size();
isReady = size <= IMAGE_THRESHOLD;
} catch (Exception e) {
isReady = false;
Log.d("Image Error", e.getMessage());
}
if (isReady) {
DialogImageView.setImageBitmap(bitmap);
DialogStatus.setText(context.getString(R.string.image_ok));
} else {
DialogImageView.setImageDrawable(null);
DialogStatus.setText(context.getString(R.string.too_big_image));
}
}
another file
public static Bitmap GetBitmapFromPath(Context context, Uri uri) {
String[] projection = { MediaStore.Images.Media.DATA };
Cursor cursor = context.getContentResolver().query(uri, projection, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
String filePath = cursor.getString(column_index);
cursor.close();
Bitmap bitmap = BitmapFactory.decodeFile(filePath);
return bitmap;
}
This line
bitmap = MyImage.GetBitmapFromPath(context, data.getData());
from the handleResult function, causes a outofmemory error when a user loads a big image.
How can I fix this?
Thanks.
try code similar to this, you just need to get a File object from the Bitmap you intend to check:
File file = new File(uri); // or new File(filePath);
file.length() // should give you a file size in bytes
In my app, a user click a button to open the Choser to choose a pic. On my activity result the code is
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
if (requestCode == SELECT_PICTURE_REQUEST_CODE) {
Uri selectedImageUri = data.getData();
if(selectedImageUri!=null){
imageviewTest.setImageURI(selectedImageUri)
}else{
}
}
}
}
The image is not displayed. I am wondering why? I noticed some people on this forum pass this value to contentresolver, why is that? Shouldn't the path be sufficient?
Thanks
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
if (requestCode == SELECT_PICTURE_REQUEST_CODE) {
BitmapFactory.Options bfOptions =new BitmapFactory.Options();
Uri selectedImage = data.getData();
if(selectedImage!=null){
String galleryImatePath = getRealPathFromURI(selectedImage);
try{
bfOptions.inDither=false; //Disable Dithering mode
bfOptions.inPurgeable=true; //Tell to gc that whether it needs free memory, the Bitmap can be cleared
bfOptions.inInputShareable=true; //Which kind of reference will be used to recover the Bitmap data after being clear, when it will be used in the future
bfOptions.inSampleSize=5;
bfOptions.inTempStorage=new byte[32 * 1024];
InputStream stream = getContentResolver().openInputStream(selectedImage);
final Bitmap myImage = BitmapFactory.decodeStream(stream, null , bfOptions);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
myImage.compress(Bitmap.CompressFormat.JPEG, 100, bos);
bitmapdata = bos.toByteArray();
imageviewTest.setImageBitmap(myImage)
}else{
}
}
}
}
public String getRealPathFromURI(Uri contentUri) {
String[] proj = { MediaStore.Images.Media.DATA };
Cursor cursor = managedQuery(contentUri, proj, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}