I am trying to make an app to select an image from the gallery or google photos and then crop it to make it my app background. The problem I am facing is that When I try to crop the picture using google photos then it gets saved but the app background doesn't change and I don't recive any crashes or any errors but when I crop it using the gallery app everything seems to work perfectly.
Here is my code to select photos:
Intent i = new Intent(Intent.ACTION_GET_CONTENT, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(i, SELECT_PICTURE);
case SELECT_PICTURE: {
if (resultCode == RESULT_OK && null != data) {
mHandler.post(new Runnable() {
#Override
public void run() {
Uri selectedImageUri = data.getData();
InputStream imageStream;
Bitmap selectedImage;
try {
cropCapturedImage(getImageUrlWithAuthority(getApplicationContext(),selectedImageUri));
} catch (ActivityNotFoundException aNFE) {
//display an error message if user device doesn't support
showToast(getString(R.string.error_crop_not_supported));
try {
String[] filePathColumn = {MediaStore.Images.Media.DATA};
Cursor cursor = getContentResolver().query(getImageUrlWithAuthority(getApplicationContext(),selectedImageUri), filePathColumn, null, null, null);
cursor.moveToFirst();
imageStream = getContentResolver().openInputStream(getImageUrlWithAuthority(getApplicationContext(),selectedImageUri));
selectedImage = BitmapFactory.decodeStream(imageStream);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
selectedImage.compress(Bitmap.CompressFormat.JPEG, 100, baos);
byte[] b = baos.toByteArray();
String encodedImage = Base64.encodeToString(b, Base64.DEFAULT);
//SharePreference to store image
PrefManager.putString(Constant.IMAGE_DATA, encodedImage);
cursor.close();
//set gallery image
setChatBackground();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
});
}
Here is my cropIntent code:
public void cropCapturedImage(Uri picUri) {
Intent cropIntent = new Intent("com.android.camera.action.CROP");
cropIntent.setDataAndType(picUri, "image/*");
cropIntent.putExtra("crop", "true");
cropIntent.putExtra("aspectX", 9);
cropIntent.putExtra("aspectY", 14);
cropIntent.putExtra("outputX", 256);
cropIntent.putExtra("outputY", 256);
cropIntent.putExtra("return-data", true);
startActivityForResult(cropIntent, CROP_PICTURE);
}
ase CROP_PICTURE: {
Uri uri = data.getData();
String[] filePathColumn = {MediaStore.Images.Media.DATA};
Cursor cursor = getContentResolver().query(uri, filePathColumn, null, null, null);
if(cursor.moveToFirst()){
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
String yourRealPath = cursor.getString(columnIndex);
} else {
//boooo, cursor doesn't have rows ...
}
cursor.close();
String v= data.toString();
if (resultCode == RESULT_OK && null != data) {
mHandler.post(new Runnable() {
#Override
public void run() {
try {
Bundle extras = data.getExtras();
Bitmap thePic = extras.getParcelable("data");
ByteArrayOutputStream baos = new ByteArrayOutputStream();
thePic.compress(Bitmap.CompressFormat.JPEG, 100, baos);
byte[] b = baos.toByteArray();
String encodedImage = Base64.encodeToString(b, Base64.DEFAULT);
//SharePreference to store image
PrefManager.putString(Constant.IMAGE_DATA, encodedImage);
//set gallery image
setChatBackground();
} catch (NullPointerException e) {
Log.d(TAG, e.getLocalizedMessage());
}
}
});
}
No, Android Does Not Have a Crop Intent
Calling method startActivity() on an Intent with an action of com.android.camera.action.CROP. They are doing this to crop an image.
This is a really bad idea.
Source here - CommonsBlog
Try to log your selectedImageUri first.
I suspect that the google photos returns a url to online file, while the gallery app return a local file path.
Related
I have implemented image cropping in my app using android intent like below:
CropIntent = new Intent("com.android.camera.action.CROP");
I have received the cropped image and displayed on my UI but I want to perform further use cases like upload the cropped image uri. The problem is that no uri is returned in activity.
Here's my crop image intent snippet:
galleryFAB.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Log.d(TAG, "Gallery Btn Clicked");
selectFromGallery();
}
});
private void selectFromGallery() {
galleryIntent = new Intent(Intent.ACTION_GET_CONTENT);
galleryIntent.setType("image/*");
startActivityForResult(Intent.createChooser(galleryIntent, "Choose From"), 2);
}
my code in activity result method:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
InputStream inputStream;
if (requestCode == 2 && resultCode == RESULT_OK){
if (data != null){
cropImageUri = data.getData();
userImage.setImageURI(cropImageUri);
try {
originalBitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), cropImageUri);
inputStream = getContentResolver().openInputStream(data.getData());
originalBitmap = BitmapFactory.decodeStream(inputStream);
Log.d(TAG, "Original bitmap byte count is:\t" + originalBitmap.getByteCount());
resizedBitmap = getResizedBitmap(originalBitmap, 200);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
resizedBitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
Log.d(TAG, "Resized bitmap byte count is:\t" + resizedBitmap.getByteCount());
try {
File file = saveBitmap("avatar_image");
upLoadFile(file);
} catch (IOException ex) {
ex.printStackTrace();
}
byte[] bytes = stream.toByteArray();
/**
* For Shared Preferences
* **/
encodedImage = Base64.encodeToString(bytes, Base64.DEFAULT);
imagePrefs = getSharedPreferences("ImagePrefs", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = imagePrefs.edit();
editor.putString("image_user", encodedImage).commit();
upLoadBytes(bytes);
} catch (IOException e) {
e.printStackTrace();
}
cropImage();
}
} else if (requestCode == PERM_CODE){
if (data != null){
//I want to get the cropped image uri here but unable to. Have tried converting the bitmap rcvd here to uri but in activity, ntn is returned. kindly guide me
Bundle bundle = data.getExtras();
originalBitmap = bundle.getParcelable("data");
userImage.setImageBitmap(resizedBitmap);
}
}
}
my crop image function:
private void cropImage() {
try {
CropIntent = new Intent("com.android.camera.action.CROP");
CropIntent.setDataAndType(cropImageUri, "image/*");
CropIntent.putExtra("crop", true);
CropIntent.putExtra("outputX", 200);
CropIntent.putExtra("outputY", 200);
CropIntent.putExtra("aspectX", 1);
CropIntent.putExtra("aspectY", 1);
CropIntent.putExtra("scale", true);
CropIntent.putExtra("return-data", true);
startActivityForResult(CropIntent, PERM_CODE);
} catch (ActivityNotFoundException ex){
}
}
Can anyone say how to get the output uri? Thanks.
If the cropped image is showing in an ImageView, follow this link to save it to device storage, then you can upload the file.
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 using the below code to get an image from video that i want to upload it to server and the image will be my thumbnail image there ... it works correctly and shows the image in ImageView ... but some thing that is wrong is I can't upload it without saving on SD Card ... is there any way for me to upload Bitmap image directly to server without SD Card URI?
My Code:
private void chooseVideo() {
Intent intent = new Intent();
intent.setType("video/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select a Video "), SELECT_VIDEO);
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
if (requestCode == SELECT_VIDEO) {
System.out.println("SELECT_VIDEO");
selectedImageUri = data.getData();
textView.setText(selectedPath);
bt = createVideoThumbnail(this, selectedImageUri);
iv_image.setImageBitmap(bt);
}
}
}
public static Bitmap createVideoThumbnail(Context context, Uri uri) {
Bitmap bitmap = null;
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
try {
retriever.setDataSource(context, uri);
bitmap = retriever.getFrameAtTime(-1);
} catch (RuntimeException ex) {
// Assume this is a corrupt video file.
} finally {
try {
retriever.release();
} catch (RuntimeException ex) {
// Ignore failures while cleaning up.
}
}
return bitmap;
}
try this
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream);
byte[] byte_arr = stream.toByteArray();
String image_str = Base64.encodeToString(byte_arr, Base64.DEFAULT);
Then POST the image_str to the server, base64 decode it back to an image.
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.
I try to select an image from gallery and saved in parse cloud server in android.
But I am unable to do.
I have tried the following code:
OnImageView Click event choose image:
imageDish.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
try {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(
Intent.createChooser(intent, "Select Picture"),
SELECT_PICTURE);
} catch (Exception e) {
Toast.makeText(getActivity(),
"Select Image From Gallery", Toast.LENGTH_LONG)
.show();
// TODO: handle exception
}
}
});
OnActivityResult:
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK) {
if (requestCode == SELECT_PICTURE) {
selectedImageUri = data.getData();
selectedImagePath = getPath(selectedImageUri);
System.out.println("Image Path : " + selectedImagePath);
imageDish.setImageURI(selectedImageUri);
}
}
}
#SuppressWarnings("deprecation")
public String getPath(Uri uri) {
String[] projection = {MediaStore.Images.Media.DATA};
Cursor cursor = getActivity().managedQuery(uri, projection, null, null, null);
int column_index = cursor
.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
Parse Code for save image:
InputStream imageStream = null;
try {
imageStream = getActivity().getContentResolver().openInputStream(
selectedImageUri);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
Bitmap bitmap = BitmapFactory.decodeStream(imageStream);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
// Compress image to lower quality scale 1 - 100
bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] image = stream.toByteArray();
ParseFile file = new ParseFile("FoodImage", image);
// Upload the image into Parse Cloud
file.saveInBackground();
Log.d("File======", "" + file);
try {
ParseObject Foodobject = new ParseObject("Food");
Foodobject.put("FoodName", Name);
Foodobject.put("ResId", ParseObject.createWithoutData("Restaurant",Res_id);
Foodobject.put("FoodCategory", ParseObject.createWithoutData("FoodCategory", _CategoryId));
Foodobject.put("FoodDesc", Des);
Foodobject.put("Price",priceNumber);
Foodobject.put("VegOnly", "Y");
Foodobject.put("IsRecommended", false);
Foodobject.put("FoodImage", file);
Foodobject.saveInBackground();
} catch (Exception ex) {
Log.e("Error", "" + ex);
}
Here is my log output:
File======: com.parse.ParseFile#39f19700
Replace your code with this
ParseFile file = new ParseFile("FoodImage.png", image);
In parse docs it is clearly mentioned that you give a name to the file that has a file extension. This lets Parse figure out the file type and handle it accordingly.
https://parse.com/docs/android/guide#files
i think your issue on image size, it might be your selected image from gallery is too large to save in parse.com
so try this code.
It is working for me .
ByteArrayOutputStream stream = null;
Bitmap bitmap = BitmapFactory.decodeFile(picturePath)
Bitmap newbitmap = Bitmap.createScaledBitmap(bitmap, 200, 200, true);
stream = new ByteArrayOutputStream();
newbitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] image = stream.toByteArray();
final ParseFile file = new ParseFile("FoodImage.png", image);
file.saveInBackground(new SaveCallback() {
#Override
public void done(ParseException e) {
if(e==null){
// Your Parse Code....
}
}