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();
}
}
}
Related
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 am trying to get the URI of a photo taken with the phone. I am trying to convert the data passed to "onActivityResult" to a URI, then convert this URI to a string to store in my database. This method does work with videos, so how can this be achieved with a photo? I get a null pointer exception when I try to convert the data to URI. Should I use a different function to convert the photo data to a URI? My code is as follows:
Button intent to start video recorder:
recordVideoButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent startVideoFunction = new Intent();
startVideoFunction.setAction(MediaStore.ACTION_VIDEO_CAPTURE);
startActivityForResult(startVideoFunction, REQUEST_CODE_VIDEO);
}
});
Button intent to start photo capture:
takePhotosButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent startPhotoFunction = new Intent();
startPhotoFunction.setAction(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(startPhotoFunction, REQUEST_CODE_PHOTO);
}
});
onActivityResult method:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
try {
switch (requestCode) {
case REQUEST_CODE_VIDEO:
videoUri = data.getData();
String videoPath = videoUri.toString();
videoDB.addVideoRow(videoPath);
//displayVideo.setVideoURI(videoUri);
//displayVideo.start();
break;
case REQUEST_CODE_PHOTO:
photoUri = data.getData();
String photoPath = photoUri.toString();
videoDB.addPhotoRow(photoPath);
break;
}
}catch (NullPointerException e){
//prevent crash when returning with Null data to mainactivity.
}
}
UPDATED onActivityResult:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent
data) {
// try {
switch (requestCode) {
case REQUEST_CODE_VIDEO:
videoUri = data.getData();
String videoPath = videoUri.toString();
videoDB.addVideoRow(videoPath);
//displayVideo.setVideoURI(videoUri);
//displayVideo.start();
break;
case REQUEST_CODE_PHOTO:
Bitmap photo = (Bitmap) data.getExtras().get("data");
Uri tempUri = getImageUri(getApplicationContext(), photo);
File finalFile = new File(getRealPathFromURI(tempUri));
String photoPath = finalFile.toString();
videoDB.addPhotoRow(photoPath);
break;
}
//}catch (NullPointerException e){
//prevent crash when returning with Null data to mainactivity.
//}
}
public Uri getImageUri(Context inContext, Bitmap inImage) {
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
inImage.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
String path = MediaStore.Images.Media.insertImage(inContext.getContentResolver(), inImage, "Title", null);
return Uri.parse(path);
}
public String getRealPathFromURI(Uri uri) {
Cursor cursor = getContentResolver().query(uri, null, null, null, null);
cursor.moveToFirst();
int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
return cursor.getString(idx);
}
To get Uri from Image: Convert the Bitmap to Uri using below mentioned code. You can always change the Bitmap compression format to PNG but then avoid using the line .compress as it will be of no use. PNG don't get compressed.
public Uri getImageUri(Context inContext, Bitmap inImage) {
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
inImage.compress(Bitmap.CompressFormat.JPEG, 100, bytes); // Used for compression rate of the Image : 100 means no compression
String path = Images.Media.insertImage(inContext.getContentResolver(), inImage, "xyz", null);
return Uri.parse(path);
}
To get the Absolute Path from Uri use this method
public String getRealPathFromURI(Uri uri) {
Cursor cursor = getContentResolver().query(uri, null, null, null, null);
cursor.moveToFirst();
int id_uri = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
return cursor.getString(id_uri);
}
Hope this solves your problem.
You are on the wrong way. Now you will save only a thumbnail of the image taken and save that to file. While the orriginal full image is already in a file on the file system.
Tell the camera app with the intent where to store the image to be taken. Use a putExtra for EXTRA_OUTPUT.
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.
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
MY SOLUTION: Ok some good answers. This is what I came up with. Not sure to answer my own question or put it here for proper stackoverflowness so if anyone knows please share.
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
switch (requestCode) {
case cameraData:
Bundle extras = data.getExtras();
bmp = (Bitmap) extras.get("data");
iv.setVisibility(View.VISIBLE);
break;
case SELECT_PICTURE:
Uri selectedImageUri = data.getData();
selectedImagePath = getPath(selectedImageUri);
File imgFile = new File(selectedImagePath);
bmp = BitmapFactory.decodeFile(imgFile.getAbsolutePath());
break;
}
iv.setVisibility(View.VISIBLE);
iv.setImageBitmap(bmp);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.JPEG, 50, stream); // compress
byte[] ba = stream.toByteArray();
image_str = Base64.encodeBytes(ba);
}
}
//////////////////////////////////////////////////////////////////////////////////////////
OK I have a path to picture in my gallery. I want to take that picture and turn it into a bundle so I can 64 encode it to upload to my server. here is my onActivityResult. I have it working from taking a picture with the camera just not getting it from the gallery.
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK){
switch(requestCode){
case cameraData:
Bundle extras = data.getExtras();
bmp = (Bitmap) extras.get("data");
Log.e("picture","Take Picture");
break;
case SELECT_PICTURE:
Uri selectedImageUri = data.getData();
selectedImagePath = getPath(selectedImageUri);
Log.e("picture",selectedImagePath);
File imgFile = new File(selectedImagePath);
bmp = (Bitmap) BitmapFactory.decodeFile(imgFile.getAbsolutePath());
Bundle extras1 = ((Cursor) imgFile).getExtras();
// bmp = (Bitmap) extras1.get("data");
Log.e("picture","from Gallery");
break;
}
}
}
the base 64 code is not mine its from this site: http://blog.sptechnolab.com/2011/03/09/android/android-upload-image-to-server/
getPath:
public String getPath(Uri uri) {
String[] projection = { MediaStore.Images.Media.DATA };
Cursor cursor = managedQuery(uri, projection, null, null, null);
int column_index = cursor
.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
Why would you want to turn the bitmap into a bundle? And why do you want to turn the file into a base64 String before you upload?
Here and here are examples that upload a file.
http://pastebin.com/3A5gMFsF
Seems to do what you want. Looks like when you get a file URI back you need to dig through some Content Resolvers to actually get the file itself.
Uri photoUri = data.getData();
if (photoUri != null)
{
try {
String[] filePathColumn = {MediaStore.Images.Media.DATA};
Cursor cursor = getContentResolver().query(photoUri, filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
String filePath = cursor.getString(columnIndex);
cursor.close();
bMap_image = BitmapFactory.decodeFile(filePath);
ImageView img = (ImageView) findViewById(R.id.gallery1);
img.setImageBitmap(bMap_image);
Edit: The only difference I see between this version and your version is that this version doesn't convert the filePath into a File before calling BitMap.Decode. It calls BitmapFactory.decodeFile directly on the file path returned from the content resolover.
You can directly convert the bitmap to base64.
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bitmap.compress(CompressFormat.PNG, 0 /*ignored for PNG*/, bos);
byte[] bitmapdata = bos.toByteArray();
byte[] dataToUpload = Base64.encode(bitmapdata , DEFAULT);
To convert the bitmap to Bundle use bundle.putParcelable("dataToUpload", bitmap)
and retireve it using bundle.getParcelable("dataToUpload").