I have been stuck in camera for 6 days but not getting any proper solution. When I am capturing image through camera intent, image is being rotated. I tried to fix the orientation but sometimes it's not giving bitmap value in onActivityResult(). It shows a black screen when I try to set image in ImageView. Here is my code Please help me -
//call intent to capture image
captureBtn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
try {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getActivity().getPackageManager()) != null)
{
startActivityForResult(takePictureIntent,AlletConstants.CAPTURE_RECEIPT_IMAGE);
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case AlletConstants.CAPTURE_RECEIPT_IMAGE:
if(data != null)
{
Uri qrcodeImageUri = data.getData();
bitmapReceiptImage = handleQrBarCodeImage(qrcodeImageUri);
mImageCaptureUri = AlletCommonUtility.bitmapToUri(getActivity(), bitmapReceiptImage);
doCrop();
AlletCommonUtility.showToast(getActivity(),"Uri = "+mImageCaptureUri);
}
break;
case AlletConstants.CROP_RECEIPT_FROM_CAMERA:
if(data != null)
{
Bundle qrcodeextras = data.getExtras();
if (qrcodeextras != null) {
Bitmap cropBitmap = qrcodeextras.getParcelable("data");
receiptImageView.setImageBitmap(cropBitmap);
bitmapReceiptImage = cropBitmap;
}
File qrcodeFile = new File(mImageCaptureUri.getPath());
if (qrcodeFile.exists())
qrcodeFile.delete();
}
break;
default:
break;
}
}
// use to get bitmap from uri
private Bitmap handleReceiptImage(Uri selectedImageUri)
{
String[] filePathColumn = {MediaStore.Images.Media.DATA };
Cursor cursor = getActivity().getContentResolver().query(selectedImageUri, filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
picturePath = cursor.getString(columnIndex);
cursor.close();
Bitmap bitmap = setCameraImageRotation(picturePath);
return bitmap;
}
private Bitmap setCameraImageRotation(String picturePath)
{
Bitmap bitmapQrBarImage = null;
try {
File f = new File(picturePath);
ExifInterface exif = new ExifInterface(f.getPath());
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
AlletCommonUtility.showToast(getActivity(), "Orienattion = "+orientation);
Matrix mat = new Matrix();
mat.postRotate(getImageOrientation(orientation));
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize= 4;
Bitmap bmp = BitmapFactory.decodeStream(new FileInputStream(f), null, options);
bitmapQrBarImage = Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(), bmp.getHeight(), mat, true);
if (bitmapQrBarImage != null) {
AlletCommonUtility.showToast(getActivity(), "CAMERA_PIC_SELECTION = "+bitmapQrBarImage);
}
}
catch (IOException e) {
Log.w("TAG", "-- Error in setting image");
}
catch(OutOfMemoryError oom) {
Log.w("TAG", "-- OOM Error in setting image");
}
return bitmapQrBarImage;
}
// Use to crop image
private void doCrop() {
final ArrayList<CropOption> cropOptions = new ArrayList<CropOption>();
Intent intent = new Intent("com.android.camera.action.CROP");
intent.setType("image/*");
List<ResolveInfo> list = getActivity().getPackageManager().queryIntentActivities( intent, 0 );
int size = list.size();
if (size == 0) {
AlletCommonUtility.showToast(getActivity(), AlletMessage.NOT_CROP_IMAGE);
return;
} else {
intent.setData(mImageCaptureUri);
intent.putExtra("outputX", 200);
intent.putExtra("outputY", 200);
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
intent.putExtra("scale", true);
intent.putExtra("return-data", true);
if (size == 1) {
Intent i = new Intent(intent);
ResolveInfo res = list.get(0);
i.setComponent( new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
startActivityForResult(i, AlletConstants.CROP_RECEIPT_FROM_CAMERA);
} else {
for (ResolveInfo res : list) {
final CropOption co = new CropOption();
co.title = getActivity().getPackageManager().getApplicationLabel(res.activityInfo.applicationInfo);
co.icon = getActivity().getPackageManager().getApplicationIcon(res.activityInfo.applicationInfo);
co.appIntent= new Intent(intent);
co.appIntent.setComponent( new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
cropOptions.add(co);
}
CropOptionAdapter adapter = new CropOptionAdapter(getActivity(), cropOptions);
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle("Choose Crop App");
builder.setAdapter( adapter, new DialogInterface.OnClickListener() {
public void onClick( DialogInterface dialog, int item ) {
startActivityForResult( cropOptions.get(item).appIntent, AlletConstants.CROP_RECEIPT_FROM_CAMERA);
}
});
builder.setOnCancelListener( new DialogInterface.OnCancelListener() {
#Override
public void onCancel( DialogInterface dialog ) {
if (mImageCaptureUri != null ) {
getActivity().getContentResolver().delete(mImageCaptureUri, null, null );
mImageCaptureUri = null;
}
}
} );
AlertDialog alert = builder.create();
alert.show();
}
}
}
// use to rotate captured image from device camera
public static int getImageOrientation(int rotation)
{
int angle = 0;
switch (rotation) {
case 0:
angle = 90;
break;
case ExifInterface.ORIENTATION_ROTATE_90:
angle = 90;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
angle = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_270:
angle = 270;
break;
default:
break;
}
return angle;
}
I am getting image in landscape mode but not in potrait mode. Camera preview automatically rotates by 90 degrees after capturing image.
It is because of the image's EXIF data. You need to use a rotation method.
Depending on your build-in Camera orientation and orientation of device the pictures will have different rotations. You check the rotation of your particular image through ExifInterface.
/**
* #param filename Path to image file
* #param captureTime Time when image file was created
*/
public static int extractExifOrientationTagFromImageFile(String filename, long creationTime) {
/* The issue is on some devices, there's a bug that makes the picture taken saved in your app folder without proper
exif tags while a properly rotated image is saved in the android default folder (even though it shouldn't be).
Now what we do is recording the time when we're starting the camera app. Then we query
the Media Provider to see if any pictures were saved after this timestamp we've saved. That means most likely Android OS
saved the properly rotated picture in the default folder and of course put an entry in the media store and we can use the
rotation information from this row. */
int imageRotation = -1;
long imageFileSize = new File(filename).length();
Cursor mediaFileCursor = getContext().getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
new String[] { MediaStore.Images.ImageColumns.ORIENTATION, MediaStore.MediaColumns.SIZE },
MediaStore.MediaColumns.DATE_ADDED + " >= ?", new String[] { String.valueOf(creationTime / 1000 - 1) },
MediaStore.MediaColumns.DATE_ADDED + " DESC");
if((mediaFileCursor != null) && (mediaFileCursor.getCount() != 0)) {
while(mediaFileCursor.moveToNext()) {
long mediaFileSize = getLongFromCursor(mediaFileCursor, MediaStore.MediaColumns.SIZE);
// Extra check to make sure that we are getting the orientation from the proper file
if(mediaFileSize == imageFileSize) {
imageRotation = getIntFromCursor(mediaFileCursor, MediaStore.Images.ImageColumns.ORIENTATION);
break;
}
}
}
/* Now if the rotation at this point is still -1, then that means this is one of the devices with proper rotation information. */
if(imageRotation == -1) {
ExifInterface exif = null;
try {
exif = new ExifInterface(filename);
}
catch (IOException e) {
e.printStackTrace();
}
imageRotation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, -1);
}
return imageRotation;
}
private static final int COLUMN_NOT_EXISTS = -1;
public static Long getLongFromCursor(Cursor cursor, String columnName) {
int columnIndex;
if((columnIndex = cursor.getColumnIndex(columnName)) != COLUMN_NOT_EXISTS) {
return cursor.getLong(columnIndex);
}
else {
return null;
}
}
public static Integer getIntFromCursor(Cursor cursor, String columnName) {
int columnIndex;
if((columnIndex = cursor.getColumnIndex(columnName)) != COLUMN_NOT_EXISTS) {
return cursor.getInt(columnIndex);
}
else {
return null;
}
}
Now when you have your image rotation you can rotate it's bitmap properly:
int imageRotation = extractExifOrientationTagFromImageFile(lastCapturedMediaUriPath, cameraAppInvokeTime);
Matrix matrix = new Matrix();
switch(imageRotation) {
case ExifInterface.ORIENTATION_ROTATE_90:
matrix.postRotate(90);
break;
case ExifInterface.ORIENTATION_ROTATE_180:
matrix.postRotate(180);
break;
case ExifInterface.ORIENTATION_ROTATE_270:
matrix.postRotate(270);
break;
default:
break;
}
final Bitmap loadedBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
Related
I'm trying to load an image from gallery in a ImageView. This code work correctly on Huawei p10, but don't work correctly on Samsung s5 and other devices. When i load the image the orientation is not correctly.
I'm using this function to load from gallery but the orientation is always 0.
public void loadPostImage(View v) {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select Picture"), SELECT_PICTURE1);
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
if (requestCode == SELECT_PICTURE1) {
selectedImageUri = data.getData();
if (null != selectedImageUri) {
flag=true;
path = selectedImageUri.getPath();
int orientation = getOrientation(getApplicationContext(), selectedImageUri);
Log.e("image path", path + "");
image_post.setImageURI(selectedImageUri);
}
}
}
}
private static int getOrientation(Context context, Uri photoUri) {
Cursor cursor = context.getContentResolver().query(photoUri,
new String[]{MediaStore.Images.ImageColumns.ORIENTATION}, null, null, null);
if (cursor.getCount() != 1) {
cursor.close();
return -1;
}
cursor.moveToFirst();
int orientation = cursor.getInt(0);
cursor.close();
cursor = null;
return orientation;
}
I tried also with EXIF. But nothing is changed.
public void controlRotate(Uri photoUri) throws IOException {
ExifInterface exif = new ExifInterface(photoUri.getPath());
int exifRotation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_UNDEFINED);
switch (exifRotation) {
case ExifInterface.ORIENTATION_ROTATE_90: {
float photoRotation = 90.0f;
break;
}
case ExifInterface.ORIENTATION_ROTATE_180: {
float photoRotation = 180.0f;
break;
}
case ExifInterface.ORIENTATION_ROTATE_270: {
float photoRotation = 270.0f;
break;
}
}
}
I resolved the problem using this snippet
public void orientation(Uri selectedImageUri){
Uri uri = selectedImageUri; // the URI you've received from the other app
InputStream in = null;
try {
in = getContentResolver().openInputStream(uri);
ExifInterface exifInterface = new ExifInterface(in);
int rotation = 0;
int orientation = exifInterface.getAttributeInt(
ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL);
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
rotation = 90;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
rotation = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_270:
rotation = 270;
break;
}
// Now you can extract any Exif tag you want
// Assuming the image is a JPEG or supported raw format
} catch (IOException e) {
// Handle any errors
} finally {
if (in != null) {
try {
in.close();
} catch (IOException ignored) {}
}
}
}
This question already has answers here:
Why does an image captured using camera intent gets rotated on some devices on Android?
(23 answers)
Closed 6 years ago.
in my app I need to load image from camera.
This is the code I've used:
private void openCamera()
{
mMediaUri =getOutputMediaFileUri(MEDIA_TYPE_IMAGE);
Intent photoIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
photoIntent.putExtra(MediaStore.EXTRA_OUTPUT, mMediaUri);
startActivityForResult(photoIntent, REQUEST_TAKE_PHOTO);
}
private Uri getOutputMediaFileUri(int mediaTypeImage)
{
//check for external storage
if(isExternalStorageAvaiable())
{
File mediaStorageDir = getActivity().getExternalFilesDir(Environment.DIRECTORY_PICTURES);
String fileName = "";
String fileType = "";
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new java.util.Date());
fileName = "IMG_"+timeStamp;
fileType = ".jpg";
File mediaFile;
try
{
mediaFile = File.createTempFile(fileName,fileType,mediaStorageDir);
Log.i("st","File: "+Uri.fromFile(mediaFile));
}
catch (IOException e)
{
e.printStackTrace();
Log.i("St","Error creating file: " + mediaStorageDir.getAbsolutePath() +fileName +fileType);
return null;
}
return FileProvider.getUriForFile(getActivity(),BuildConfig.APPLICATION_ID + ".provider", mediaFile);
}
//something went wrong
return null;
}
private boolean isExternalStorageAvaiable()
{
String state = Environment.getExternalStorageState();
if(Environment.MEDIA_MOUNTED.equals(state))
{
return true;
}
else
{
return false;
}
}
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
if(resultCode == DIALOG_CODE)
{
String s = data.getStringExtra("choose");
if(s.equals(getString(R.string.takephoto)))
{
openCamera();
}
else if(s.equals(getString(R.string.library)))
{
openGallery();
}
}
else if(resultCode == RESULT_OK)
{
if (requestCode == REQUEST_TAKE_PHOTO || requestCode == REQUEST_PICK_PHOTO) //dalla fotocamera
{
if (data != null) //caso galleria
{
mMediaUri = data.getData();
}
Picasso.with(getActivity()).load(mMediaUri).resize(1280, 1280).transform(new RoundedTransformation()).centerCrop().into(photo, new Callback()
{
public void onSuccess()
{
}
#Override
public void onError() {
}
});
}
}
}
and it works but it gives me this error: if I take a photo like this:
it loads a picture in imageview in this way:
but if I load the picture from the gallery, it works ok.
What's the error here?
Thanks
You have to rotate image using ExifInterface.
Image rotate based on image capture angle.
ExifInterface will rotate image even if you click photo from any angle.
It will display properly.
File mediaFile = new File(mediaPath);
Bitmap bitmap;
if (mediaFile.exists()) {
if (isImage(mediaPath)) {
Bitmap myBitmap = BitmapFactory.decodeFile(mediaFile.getAbsolutePath());
int height = (myBitmap.getHeight() * 512 / myBitmap.getWidth());
Bitmap scale = Bitmap.createScaledBitmap(myBitmap, 512, height, true);
int rotate = 0;
try {
exif = new ExifInterface(mediaFile.getAbsolutePath());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_UNDEFINED);
switch (orientation) {
case ExifInterface.ORIENTATION_NORMAL:
rotate = 0;
break;
case ExifInterface.ORIENTATION_ROTATE_270:
rotate = 270;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
rotate = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_90:
rotate = 90;
break;
}
Matrix matrix = new Matrix();
matrix.postRotate(rotate);
Bitmap rotateBitmap = Bitmap.createBitmap(scale, 0, 0, scale.getWidth(),
scale.getHeight(), matrix, true);
displayImage.setImageBitmap(rotateBitmap);
}
}
public static boolean isImage(String str) {
boolean temp = false;
String[] arr = { ".jpeg", ".jpg", ".png", ".bmp", ".gif" };
for (int i = 0; i < arr.length; i++) {
temp = str.endsWith(arr[i]);
if (temp) {
break;
}
}
return temp;
}
I am trying number of tutorials and sample codes for take an image from gallery or camera then crop the image and upload it to server. I was implemented the code for that in that code am facing few problems the are.
In pre Lollipop devices when I crop the image using photos app the image is not getting reflected in image view but it's showing the message as image saved..
In nexus phone both camera and gallery is not working.
5.0 versions in few devices when I crop the image am getting the image like shown below
below is my code snippet.`
public void getPhoto() {
final String[] items = new String[] { "Take from camera",
"Select from gallery" };
ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(),
android.R.layout.select_dialog_item, items);
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle("Select Image");
builder.setAdapter(adapter, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int item) { // pick from
// camera
if (item == 0) {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(
"android.intent.extras.CAMERA_FACING",
android.hardware.Camera.CameraInfo.CAMERA_FACING_FRONT);
mImageCaptureUri = Uri.fromFile(new File(Environment
.getExternalStorageDirectory(), "tmp_avatar_"
+ String.valueOf(System.currentTimeMillis())
+ ".jpg"));
intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT,
mImageCaptureUri);
try {
intent.putExtra("return-data", true);
startActivityForResult(intent, PICK_FROM_CAMERA);
} catch (ActivityNotFoundException e) {
e.printStackTrace();
}
} else { // pick from file
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setType("image/*");
// startActivityForResult(intent, SELECT_PICTURE);
startActivityForResult(intent, PICK_FROM_FILE);
}
}
});
final AlertDialog dialog = builder.create();
dialog.show();
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode != Activity.RESULT_OK)
return;
switch (requestCode) {
case PICK_FROM_CAMERA:
doCrop();
break;
case PICK_FROM_FILE:
mImageCaptureUri = data.getData();
doCrop();
break;
case CROP_FROM_CAMERA:
Bundle extras = data.getExtras();
if (extras != null) {
photo = extras.getParcelable("data");
profile_image = encodeTobase64(photo);
saveType = "photo";
try {
JSONObject obj = new JSONObject();
obj.put("user_id", user_id);
obj.put("mode", saveType);
obj.put("photo", profile_image);
obj.put("is_profile", 1);
saveResponse(obj);
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
File f = new File(mImageCaptureUri.getPath());
if (f.exists())
f.delete();
break;
}
}
private void doCrop() {
final ArrayList<CropOption> cropOptions = new ArrayList<CropOption>();
Intent intent = new Intent("com.android.camera.action.CROP");
intent.setType("image/*");
List<ResolveInfo> list = getActivity().getPackageManager()
.queryIntentActivities(intent, 0);
int size = list.size();
if (size == 0) {
Toast.makeText(getActivity(), "Can not find image crop app",
Toast.LENGTH_SHORT).show();
return;
} else {
intent.setData(mImageCaptureUri);
intent.putExtra("crop", "true");
intent.putExtra("outputX", 300);
intent.putExtra("outputY", 300);
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
intent.putExtra("scale", true);
intent.putExtra("circleCrop", new String(""));
intent.putExtra("return-data", true);
if (size == 1) {
Intent i = new Intent(intent);
ResolveInfo res = list.get(0);
i.setComponent(new ComponentName(res.activityInfo.packageName,
res.activityInfo.name));
startActivityForResult(i, CROP_FROM_CAMERA);
} else {
for (ResolveInfo res : list) {
final CropOption co = new CropOption();
co.title = getActivity().getPackageManager()
.getApplicationLabel(
res.activityInfo.applicationInfo);
co.icon = getActivity().getPackageManager()
.getApplicationIcon(
res.activityInfo.applicationInfo);
co.appIntent = new Intent(intent);
co.appIntent
.setComponent(new ComponentName(
res.activityInfo.packageName,
res.activityInfo.name));
cropOptions.add(co);
}
CropOptionAdapter adapter = new CropOptionAdapter(
getActivity(), cropOptions);
AlertDialog.Builder builder = new AlertDialog.Builder(
getActivity());
builder.setTitle("Choose Crop App");
builder.setAdapter(adapter,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int item) {
startActivityForResult(
cropOptions.get(item).appIntent,
CROP_FROM_CAMERA);
}
});
builder.setOnCancelListener(new DialogInterface.OnCancelListener() {
#Override
public void onCancel(DialogInterface dialog) {
if (mImageCaptureUri != null) {
getActivity().getContentResolver().delete(
mImageCaptureUri, null, null);
mImageCaptureUri = null;
}
}
});
AlertDialog alert = builder.create();
alert.show();
}
}
}
public String encodeTobase64(Bitmap image) {
Bitmap immagex = image;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
immagex.compress(Bitmap.CompressFormat.JPEG, 100, baos);
image_Array = baos.toByteArray();
String imageEncoded = Base64
.encodeToString(image_Array, Base64.DEFAULT);
return imageEncoded;
}
`
comment below before duplicating this question because i was checked a lot but didn't find any solution for this, please let me know if you need more information.
I have the same problem last week and I finally solve it, it's a little bit different in my case I get an image in Base64 from a server then crop it
here's the code
byte[] decodedString = Base64.decode(imageJson, Base64.DEFAULT);
Bitmap tmp = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length);
bitmapDecoded = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length);
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
int h = metrics.heightPixels;
int w = metrics.widthPixels;
Bitmap resized = Bitmap.createScaledBitmap(tmp, tmp.getWidth(), (int) (tmp.getHeight()*1.6), true);
imageView.setImageBitmap(canvas.getCircleBitmap(resized, w,h));
imageJson is the image in Base64 it's a String I transform it in a Bitmap, after I get the size of the screen, the Bitmap resized is here for have a square image, cause I have a 16/9 image this is maybe not usefull for you, and finally I show the bitmap in an imageView and crop it with the canvas method getCircleBitmap
here is the method
public Bitmap getCircleBitmap(Bitmap bitmap,int width, int height) {
final Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
bitmap.getHeight(), Bitmap.Config.ARGB_8888);
final Canvas canvas = new Canvas(output);
final int color = Color.RED;
final Paint paint = new Paint();
final Rect rect = new Rect((int)(bitmap.getWidth()*0.054), (int) (height*0.005), (int) (bitmap.getWidth()*0.945), (bitmap.getHeight()));
final RectF rectF = new RectF(rect);
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(color);
canvas.drawOval(rectF, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, paint);
bitmap.recycle();
return output;
}
You can change the value of the rect for fit it for your usage
I declare this method in a canvas class who extends View, really hope this help you too and sorry for my english
i also facing this issue..Now its working fine because i m using library
**compile 'com.soundcloud.android:android-crop:1.0.1#aar'**
public Uri mImageCaptureUri=null;
Pick image from gallery
Intent i = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(i, PICK_FROM_FILE);
this is add to onActivityResult method
//call this line after crop it
if(requestCode == Crop.REQUEST_CROP){
handleCrop(resultCode, data);
}
case PICK_FROM_FILE:
mImageCaptureUri = data.getData();
beginCrop(mImageCaptureUri);
break;
private void beginCrop(Uri source) {
Uri destination = Uri.fromFile(new File(getCacheDir(), "cropped"));
Crop.of(source, destination).asSquare().start(this);
}
private void handleCrop(int resultCode, Intent result) {
if (resultCode == RESULT_OK) {
// mImage.setImageURI(Crop.getOutput(result));
Picasso.with(SettingsActivity.this).load(Crop.getOutput(result)).transform(new RoundTransform()).into(mImage);
mImageCaptureUri=Crop.getOutput(result);
getImageUri(mImageCaptureUri); //this method uri stored to sdcard
} else if (resultCode == Crop.RESULT_ERROR) {
Toast.makeText(this, Crop.getError(result).getMessage(), Toast.LENGTH_SHORT).show();
}
}
If user requests to take a picture:
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(BaseActivity.this.getPackageManager()) != null) {
File photoFile = null;
try {
photoFile = ImageVideoUtil.createImageFile();
} catch (IOException ex) {
ex.printStackTrace();
}
if (photoFile != null) {
imagePath = Uri.fromFile(photoFile);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, imagePath);
startActivityForResult(takePictureIntent, ApplicationConstants.REQUEST_CAMERA);
}
}
If user requests to pick from camera you can use:
Intent intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent, ApplicationConstants.REQUEST_GALLERY);
dialog.dismiss();
And on your activity result you can get uri and use it:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
BaseFragment fragment = (BaseFragment) getSupportFragmentManager().findFragmentById(R.id.fl_main);
if (resultCode == RESULT_OK) {
Bitmap bitmap = null;
switch (requestCode) {
case ApplicationConstants.REQUEST_CAMERA:
if (imagePath != null && fragment instanceof PhotoView) {
bitmap = Tools.fromGallery(this, imagePath);
if (bitmap != null) {
bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth() / 2, bitmap.getHeight() / 2);
((PhotoView) fragment).onPhotoSet(bitmap);
}
}
break;
case ApplicationConstants.REQUEST_GALLERY:
Uri uri = data.getData();
imagePath = uri;
bitmap = Tools.fromGallery(this, uri);
if (bitmap != null && fragment instanceof PhotoView) {
bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth() / 2, bitmap.getHeight() / 2);
((PhotoView) fragment).onPhotoSet(bitmap);
}
break;
case ApplicationConstants.REQUEST_VIDEO:
if (fragment instanceof VideoView) {
((VideoView) fragment).onVideoSelected(videoPath);
}
break;
}
}
}
Here the ImageVideoUtil Class which'll help you to crop, scale, save and read image video operations.
public class ImageVideoUtil {
public static void startCameraIntent(Activity activity) {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// Ensure that there's a camera activity to handle the intent
if (takePictureIntent.resolveActivity(activity.getPackageManager()) != null) {
// Create the File where the photo should go
File photoFile = null;
try {
photoFile = createImageFile();
} catch (IOException ex) {
// Error occurred while creating the File
ex.printStackTrace();
}
// Continue only if the File was successfully created
if (photoFile != null) {
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile));
activity.startActivityForResult(takePictureIntent, ApplicationConstants.REQUEST_CAMERA);
}
}
}
public static File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "SnapSense" + timeStamp + "_";
File storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
File image = File.createTempFile(imageFileName, /* prefix */
ApplicationConstants.DEFAULT_IMGAE_SUFFIX, /* suffix */
storageDir /* directory */
);
// Save a file: path for use with ACTION_VIEW intents
return image;
}
public static File createVideoFile() throws IOException {
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "SnapSense" + timeStamp + "_";
File storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES);
File video = File.createTempFile(imageFileName, /* prefix */
ApplicationConstants.DEFAULT_VIDEO_SUFFIX, /* suffix */
storageDir /* directory */
);
// Save a file: path for use with ACTION_VIEW intents
return video;
}
public static Bitmap decodeBitmap(Bitmap bmp) {
try {
ByteArrayOutputStream out = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.PNG, 50, out);
return BitmapFactory.decodeStream(new ByteArrayInputStream(out.toByteArray()));
} catch (Exception ex) {
ex.printStackTrace();
}
return bmp;
}
}
Finally here are some other static methods to help you:
public static Bitmap fromGallery(Context context, final Uri selectedImageUri) {
try {
Bitmap bm = MediaStore.Images.Media.getBitmap(context.getContentResolver(), selectedImageUri);
ExifInterface exif = new ExifInterface(selectedImageUri.getPath());
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
int angle = 0;
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
angle = 90;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
angle = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_270:
angle = 270;
break;
default:
angle = 0;
break;
}
Matrix mat = new Matrix();
if (angle == 0 && bm.getWidth() > bm.getHeight())
mat.postRotate(90);
else
mat.postRotate(angle);
return Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), bm.getHeight(), mat, true);
} catch (IOException e) {
e.printStackTrace();
} catch (OutOfMemoryError oom) {
oom.printStackTrace();
}
return null;
}
public static String getRealPathFromURI(Activity activity, Uri contentUri) {
String[] proj = {MediaStore.Images.Media.DATA};
Cursor cursor = activity.managedQuery(contentUri, proj, null, null, null);
int column_index = cursor
.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
I hope my code helps you. Good Luck.
I was facing same issue in Nexus. I used Android Image Cropper which is very lightweight and flexible.
compile 'com.theartofdev.edmodo:android-image-cropper:2.2.+'
Each version has there own way to get path:
Try this method will work for every version, IT WORKED FOR ME:
public static String getRealPathFromURI(final Context context, final Uri uri) {
final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
// DocumentProvider
if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
// ExternalStorageProvider
if (isExternalStorageDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
if ("primary".equalsIgnoreCase(type)) {
return Environment.getExternalStorageDirectory() + "/"
+ split[1];
}
// TODO handle non-primary volumes
}
// DownloadsProvider
else if (isDownloadsDocument(uri)) {
final String id = DocumentsContract.getDocumentId(uri);
final Uri contentUri = ContentUris.withAppendedId(
Uri.parse("content://downloads/public_downloads"),
Long.valueOf(id));
return getDataColumn(context, contentUri, null, null);
}
// MediaProvider
else if (isMediaDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
Uri contentUri = null;
if ("image".equals(type)) {
contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
} else if ("video".equals(type)) {
contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
} else if ("audio".equals(type)) {
contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
}
final String selection = "_id=?";
final String[] selectionArgs = new String[]{split[1]};
return getDataColumn(context, contentUri, selection,
selectionArgs);
}
}
// MediaStore (and general)
else if ("content".equalsIgnoreCase(uri.getScheme())) {
return getDataColumn(context, uri, null, null);
}
// File
else if ("file".equalsIgnoreCase(uri.getScheme())) {
return uri.getPath();
}
return null;
}
I have written a program which has a button which when clicked captures a photo through camera and want to set the captured image on the same activity below the button.
Everything works without giving an error. The image is also getting saved to the respective location. But the image is not getting displayed, which means something is going wrong.
Below is my Code for the above :
public class MainActivity extends ActionBarActivity {
Button b1;
private File imageFile;
ImageView img;
private Uri uri;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
b1 = (Button) findViewById(R.id.buttonPicture);
img = (ImageView) findViewById(R.id.imageView1);
b1.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
imageFile = new File(
Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
"test.jpeg");
uri = Uri.fromFile(imageFile);
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);
startActivityForResult(intent, 0);
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
if (requestCode == 0 && data != null) {
switch (resultCode) {
case Activity.RESULT_OK:
if (imageFile.exists()) {
Bitmap photo = (Bitmap) data.getExtras().get(
MediaStore.EXTRA_OUTPUT);
previewCapturedImage();
img.setImageBitmap(photo);
} else {
Toast.makeText(getBaseContext(), "File was not saved",
Toast.LENGTH_SHORT).show();
}
break;
case Activity.RESULT_CANCELED:
break;
default:
break;
}
}
}
private void previewCapturedImage() {
try {
// bimatp factory
BitmapFactory.Options options = new BitmapFactory.Options();
// downsizing image as it throws OutOfMemory Exception for larger
options.inSampleSize = 8;
final Bitmap bitmap = BitmapFactory.decodeFile(uri.getPath(),
options);
img.setImageBitmap(bitmap);
} catch (NullPointerException e) {
e.printStackTrace();
}
}
}
Once you press Ok button after capturing image, you can take the captured image from the Extras using Intent(data in your case) parameter received through onActivityResult
Simply use this code inside onActivityResult
Bitmap photo = (Bitmap) data.getExtras().get("data");
imgViewLogo.setImageBitmap(photo);
Try with below code:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
if (requestCode == 0 && data != null) {
switch (resultCode) {
case Activity.RESULT_OK:
if (imageFile.exists()) {
private String selectedImagePath;
Uri selectedImageUri = data.getData();
String filePath = null;
String filemanagerstring = selectedImageUri.getPath();
selectedImagePath = getPath(selectedImageUri);
if (selectedImagePath != null) {
filePath = selectedImagePath;
} else if (filemanagerstring != null) {
filePath = filemanagerstring;
} else {
Toast.makeText(getApplicationContext(), R.string.unknownPath, Toast.LENGTH_LONG).show();
if (filePath != null) {
decodeFile(filePath);
} else {
bitmap = null;
}
} else {
Toast.makeText(getBaseContext(), "File was not saved",
Toast.LENGTH_SHORT).show();
}
break;
case Activity.RESULT_CANCELED:
break;
default:
break;
}
}
}
//getPath method
public String getPath(Uri uri) {
String[] projection = { MediaColumns.DATA };
Cursor cursor = managedQuery(uri, projection, null, null, null);
if (cursor != null) {
int column_index = cursor.getColumnIndexOrThrow(MediaColumns.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
} else
return null;
}
//decodeFile method
public void decodeFile(String filePath) {
private Bitmap bitmap;
try {
File f = new File(filePath);
ExifInterface exif = new ExifInterface(f.getPath());
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
int angle = 0;
if (orientation == ExifInterface.ORIENTATION_ROTATE_90) {
angle = 90;
} else if (orientation == ExifInterface.ORIENTATION_ROTATE_180) {
angle = 180;
} else if (orientation == ExifInterface.ORIENTATION_ROTATE_270) {
angle = 270;
}
Matrix mat = new Matrix();
mat.postRotate(angle);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 2;
Bitmap bmp = BitmapFactory.decodeStream(new FileInputStream(f), null, options);
bitmap = Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(), bmp.getHeight(), mat, true);
ByteArrayOutputStream outstudentstreamOutputStream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, outstudentstreamOutputStream);
img.setImageBitmap(selfieBitmap);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}
}
I developed an app in which the user can capture an image either from camera or gallery. For that, the user can click on the imageview, then a dialog shows up and the user can choose to capture from camera or gallery.
If the user chooses to capture the image from gallery or with the front camera then it works fine and the captured image shows up in the imageview. But if the user chooses the back camera and takes the photo and return back to activity, then the image does not show up in the imageview at all.
Here my full source code:
public class PostActivity extends Activity implements OnClickListener {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
setContentView(R.layout.post);
image = (ImageView) findViewById(R.id.image);
ab = getActionBar();
ab.setDisplayHomeAsUpEnabled(true);
image.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
show(); //here the dialog box is called, to choose the capture option
}
});
image.setTag(null);
captureImageInitialization();
}
private void show() {
dialog.show();
}
private void captureImageInitialization() {
final Item[] items = {
new Item("Camera", R.drawable.ic_action_camera_dark),
new Item("Gallery", R.drawable.ic_action_collection),
};
ListAdapter adapter = new ArrayAdapter<Item>(this,
android.R.layout.select_dialog_item, android.R.id.text1, items) {
public View getView(int position, View convertView, ViewGroup parent) {
// User super class to create the View
View v = super.getView(position, convertView, parent);
TextView tv = (TextView) v.findViewById(android.R.id.text1);
// Put the image on the TextView
tv.setCompoundDrawablesWithIntrinsicBounds(
items[position].icon, 0, 0, 0);
// Add margin between image and text (support various screen
// densities)
int dp5 = (int) (5 * getResources().getDisplayMetrics().density + 0.5f);
tv.setCompoundDrawablePadding(dp5);
return v;
}
};
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Take Image from ...");
builder.setAdapter(adapter, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int item) {
if (item == 0) {
Intent intent = new Intent(
"android.media.action.IMAGE_CAPTURE");
startActivityForResult(intent, PICK_FROM_CAMERA);
} else {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(intent, PICK_FROM_FILE);
}
}
});
dialog = builder.create();
}
public static class Item {
public final String text;
public final int icon;
public Item(String text, Integer icon) {
this.text = text;
this.icon = icon;
}
#Override
public String toString() {
return text;
}
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case PICK_FROM_CAMERA:
mImageCaptureUri = data.getData();
imagepath = getPath(mImageCaptureUri);
BitmapFactory.Options options0 = new BitmapFactory.Options();
options0.inSampleSize = 2;
options0.inScaled = false;
options0.inDither = false;
options0.inPreferredConfig = Bitmap.Config.ARGB_8888;
bmp = BitmapFactory.decodeFile(imagepath, options0);
Matrix matrix = new Matrix();
ExifInterface exif;
int m = 0;
try {
exif = new ExifInterface(imagepath);
int orientation = exif.getAttributeInt(
ExifInterface.TAG_ORIENTATION, 1);
Log.d("EXIF", "Exif: " + orientation);
if (orientation == 6) {
m = 90;
} else if (orientation == 3) {
m = 180;
} else if (orientation == 8) {
m = 270;
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
matrix.postRotate(m);
bmp = Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(),
bmp.getHeight(), matrix, false);
ByteArrayOutputStream baos0 = new ByteArrayOutputStream();
image.setImageBitmap(getRoundedCornerBitmap(bmp));
image.setTag("1");
bmp.compress(Bitmap.CompressFormat.JPEG, 100, baos0);
byte[] imageBytes0 = baos0.toByteArray();
krt1 = Base64.encodeToString(imageBytes0, Base64.DEFAULT);
break;
case PICK_FROM_FILE:
mImageCaptureUri = data.getData();
imagepath = getPath(mImageCaptureUri);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 2;
options.inScaled = false;
options.inDither = false;
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
bmp = BitmapFactory.decodeFile(imagepath, options);
ExifInterface exif2;
int m2 = 0;
try {
exif2 = new ExifInterface(imagepath);
int orientation = exif2.getAttributeInt(
ExifInterface.TAG_ORIENTATION, 1);
Log.d("EXIF", "Exif: " + orientation);
if (orientation == 6) {
m2 = 90;
} else if (orientation == 3) {
m2 = 180;
} else if (orientation == 8) {
m2 = 270;
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
ByteArrayOutputStream baos2 = new ByteArrayOutputStream();
Matrix matrix2 = new Matrix();
matrix2.postRotate(m2);
bmp = Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(),
bmp.getHeight(), matrix2, false);
image.setImageBitmap(getRoundedCornerBitmap(bmp));
image.setTag("1");
bmp.compress(Bitmap.CompressFormat.JPEG, 100, baos2);
byte[] imageBytes2 = baos2.toByteArray();
krt1 = Base64.encodeToString(imageBytes2, Base64.DEFAULT);
break;
}
}
public String getPath(Uri uri) {
String res = null;
String[] proj = { MediaStore.Images.Media.DATA };
Cursor cursor = getApplicationContext().getContentResolver().query(uri,
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;
}
This issue with the back camera is really weird, because I never had such an issue. (BTW tested on Samsung device). Any help is appreciated.
I am using this code for taking the image from front facing camera -
public class CameraController {
private Context context;
private boolean hasCamera;
private Camera camera;
private int cameraId;
public CameraController(Context c){
context = c.getApplicationContext();
if(context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)){
cameraId = getFrontCameraId();
if(cameraId != -1){
hasCamera = true;
}else{
hasCamera = false;
}
}else{
hasCamera = false;
}
}
public boolean hasCamera(){
return hasCamera;
}
public void getCameraInstance(){
camera = null;
if(hasCamera){
try{
camera = Camera.open(cameraId);
prepareCamera();
}
catch(Exception e){
hasCamera = false;
}
}
}
public void takePicture(){
if(hasCamera){
camera.takePicture(null,null,mPicture);
}
}
public void releaseCamera(){
if(camera != null){
camera.stopPreview();
camera.release();
camera = null;
}
}
private int getFrontCameraId(){
int camId = -1;
int numberOfCameras = Camera.getNumberOfCameras();
CameraInfo ci = new CameraInfo();
for(int i = 0;i < numberOfCameras;i++){
Camera.getCameraInfo(i,ci);
if(ci.facing == CameraInfo.CAMERA_FACING_FRONT){
camId = i;
}
}
return camId;
}
private void prepareCamera(){
SurfaceView view = new SurfaceView(context);
try{
camera.setPreviewDisplay(view.getHolder());
}catch(IOException e){
throw new RuntimeException(e);
}
camera.startPreview();
Camera.Parameters params = camera.getParameters();
params.setJpegQuality(100);
camera.setParameters(params);
}
private PictureCallback mPicture = new PictureCallback(){
#Override
public void onPictureTaken(byte[] data, Camera camera){
File pictureFile = getOutputMediaFile();
if(pictureFile == null){
Log.d("TEST", "Error creating media file, check storage permissions");
return;
}
try{
Log.d("TEST","File created");
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
}catch(FileNotFoundException e){
Log.d("TEST","File not found: "+e.getMessage());
} catch (IOException e){
Log.d("TEST","Error accessing file: "+e.getMessage());
}
}
};
private File getOutputMediaFile(){
// To be safe, you should check that the SDCard is mounted
// using Environment.getExternalStorageState() before doing this.
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),"MyCameraApp");
// This location works best if you want the created images to be shared
// between applications and persist after your app has been uninstalled.
// Create the storage directory if it does not exist
if(!mediaStorageDir.exists()){
if(!mediaStorageDir.mkdirs()){
return null;
}
}
// Create a media file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
File mediaFile;
mediaFile = new File(mediaStorageDir.getPath()+File.separator+"IMG_"+timeStamp+".jpg");
return mediaFile;
}
}
Hope this helps you.