I have a problem. See, please, my code.
if(savedInstanceState==null){
mImagePath = getIntent().getStringExtra("path");
new Thread(new Runnable() {
#Override
public void run() {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inMutable=true;
ExifInterface exif;
try {
exif = new ExifInterface(new File(mImagePath).getAbsolutePath());
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
int rotate = 0;
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_270:
rotate = 270;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
rotate = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_90:
rotate = 90;
break;
}
Bitmap rotatedBitmap = BitmapFactory.decodeFile(mImagePath,options);
if(rotatedBitmap==null){
Answers.getInstance().logCustom(new CustomEvent("Null 1"));
// The first place where sometimes bitmap is null
}
assert rotatedBitmap != null;
int width = rotatedBitmap.getWidth();
int height = rotatedBitmap.getHeight();
if (Math.max(width,height)>MAX_LENGTH_OF_IMAGE){
// if widht or height >1500 px then i resize the image
float factor = MAX_LENGTH_OF_IMAGE/Math.max(width,height);
width=(int)(width*factor);
height=(int)(height*factor);
mOriginalBitmap = Bitmap.createScaledBitmap(rotatedBitmap,width,height,true);
rotatedBitmap.recycle();
} else
mOriginalBitmap=rotatedBitmap;
if(rotate!=0){
Matrix matrix = new Matrix();
matrix.postRotate(rotate);
rotattedBitmap=Bitmap.createBitmap(mOriginalBitmap, 0, 0, width, height, matrix, true);
mOriginalBitmap.recycle();
mOriginalBitmap=rotattedBitmap;
}
if(mOriginalBitmap==null){
Answers.getInstance().logCustom(new CustomEvent("Null 187"));
//I didn't receive this message
}
} catch (IOException e) {
finish();
e.printStackTrace();
}
if(mOriginalBitmap==null){
Answers.getInstance().logCustom(new CustomEvent("Null 206"));
// The second place where bitmap sometimes is null
}
mCurrentBitmap=mOriginalBitmap.copy(Bitmap.Config.ARGB_8888,true);
handler.post(new Runnable() {
#Override
public void run() {
onCreated();
}
});
}
}).start();
}
Sometimes the bitmap is null (in two places). This error occurs in 6-7 users out of 1000.
I can always check if the bitmap is null and don't perform operations with this bitmap (bitmap.copy, bitmap.getwidth and others), but what should I do to always load a bitmap?
Related
Why images are rotated 90 degree in imageView?? and how to fix it??
All images in gallery are not rotated 90 degree in imageView.
I don't know why some images are rotated 90 degree in imageView.
#Override
protected void onActivityResult(int requestCode , int resultCode , Intent data){
if(requestCode == 100){
if(resultCode == Activity.RESULT_OK){
try{
ImageView imageView = (ImageView)View.inflate(this, R.layout.imagelayout, null);
Uri imgUri = data.getData();
Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), imgUri);
int height = bitmap.getHeight();
int width = bitmap.getWidth();
int newHeight = height;
int newWidth = width;
float rate = 0.0f;
if(width > height ){
if(imageFlipper.getWidth() < width ){
rate = imageFlipper.getWidth() / (float) width ;
newHeight = (int) (height * rate);
newWidth = imageFlipper.getWidth();
}
}else{
if(imageFlipper.getHeight() < height ){
rate = imageFlipper.getHeight() / (float) height ;
newWidth = (int) (width * rate);
newHeight = imageFlipper.getHeight();
}
}
Bitmap reSize = Bitmap.createScaledBitmap(bitmap , newWidth , newHeight,true);
imageView.setImageBitmap(reSize);
//imageView.setImageURI(imgUri);
imageFlipper.addView(imageView);
imageFlipper.setDisplayedChild(imageFlipper.getChildCount() - 1);
}catch(Exception e){
e.printStackTrace();
}
}
}
}
In some devices, when the camera is launched the orientation would change. In one of my apps, I also faced this issue. To handle this we need to find the orientation and rotate the picture accordingly.
// capture image orientation
public int getCameraPhotoOrientation(Context context, Uri imageUri,
String imagePath) {
int rotate = 0;
try {
context.getContentResolver().notifyChange(imageUri, null);
File imageFile = new File(imagePath);
ExifInterface exif = new ExifInterface(imageFile.getAbsolutePath());
int orientation = exif.getAttributeInt(
ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL);
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_270:
rotate = 270;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
rotate = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_90:
rotate = 90;
break;
}
Log.i("RotateImage", "Exif orientation: " + orientation);
Log.i("RotateImage", "Rotate value: " + rotate);
} catch (Exception e) {
e.printStackTrace();
}
return rotate;
}
We need to use this integer returned to set the angle for Imageview.
int rotateImage = getCameraPhotoOrientation(this, uriLargeImage,
mediaFile.getAbsolutePath());
articleview.setRotation(rotateImage); // articleview is ImageView
So basically, please find the orientation of the photo as and when it is taken. This is in ExifInterface. Use this information to rotate.
Hope this helps. All the best.
You must set the rotation in the imageview with which the photo was taken:
imageView.setRotation(getCameraPhotoOrientation(filepath));
imageView.setImageURI( Uri.fromFile(filepath));
public static int getCameraPhotoOrientation(String imagePath) {
int rotate = 0;
try {
ExifInterface exif = null;
try {
exif = new ExifInterface(imagePath);
} catch (IOException e1) {
e1.printStackTrace();
}
int orientation = exif.getAttributeInt(
ExifInterface.TAG_ORIENTATION, 0);
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_180:
rotate = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_90:
rotate = 90;
break;
case ExifInterface.ORIENTATION_ROTATE_270:
rotate = 90;
break;
default:
rotate = 0;
}
} catch (Exception e) {
e.printStackTrace();
}
return rotate;
}
As mentioned before it does it automatically. The way I fixed this, was by using this ImageCropper, which counter-rotates it automatically, which is amazing.
Click here: https://github.com/ArthurHub/Android-Image-Cropper
So not only do you get to crop and rotate your image, but it fixes the problem too!!
/**
* Rotate a bitmap clockwise and anticlockwise
*/
btn_clock = (Button) findViewById(R.id.btn_clockWise);
btn_clock.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Matrix mMatrix = new Matrix();
Matrix mat=img.getImageMatrix();
mMatrix.set(mat);
mMatrix.setRotate(90);
bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(),
bitmap.getHeight(), mMatrix, false);
img.setImageBitmap(bitmap);
}
});
btn_antiClock = (Button) findViewById(R.id.btn_AnticlockWise);
btn_antiClock.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Matrix mMatrix = new Matrix();
Matrix mat=img.getImageMatrix();
mMatrix.set(mat);
mMatrix.setRotate(-90);
bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(),
bitmap.getHeight(), mMatrix, false);
img.setImageBitmap(bitmap);
}
});
Kotlin answer
use:
implementation 'androidx.exifinterface:exifinterface:VERSION'
Get newest release here: https://developer.android.com/jetpack/androidx/releases/exifinterface
Function:
private fun adjustRotation(file: File): Bitmap{
lateinit var rotatedBitmap: Bitmap
val bitmap = BitmapFactory.decodeFile(file.absolutePath)
val exifInterface = ExifInterface(file)
val orientation: Int = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED)
fun rotateBitmap(source: Bitmap, angle: Int): Bitmap{
val matrix = Matrix()
matrix.postRotate(angle.toFloat())
return Bitmap.createBitmap(source, 0, 0, source.width, source.height, matrix, true)
}
when (orientation){
ExifInterface.ORIENTATION_ROTATE_90 ->
rotatedBitmap = rotateBitmap(bitmap, 90)
ExifInterface.ORIENTATION_ROTATE_180 ->
rotatedBitmap = rotateBitmap(bitmap, 180)
ExifInterface.ORIENTATION_ROTATE_270 ->
rotatedBitmap = rotateBitmap(bitmap, 270)
ExifInterface.ORIENTATION_NORMAL ->
rotatedBitmap = bitmap
else -> rotatedBitmap = bitmap
}
return rotatedBitmap
}
I captured image from camera and display image into imageview. It will display perfect but the captured image rotated 90 degrees automatically in some devices. I searched a lot about it but could not get proper solution. Please tell me the solution for it. Thanks in advance.
try this code
public Bitmap adjustImageOrientation(Bitmap image, File f) {
int rotate = 0;
try {
ExifInterface exif = new ExifInterface(f.getAbsolutePath());
int orientation = exif.getAttributeInt(
ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL);
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_270:
rotate = 270;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
rotate = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_90:
rotate = 90;
break;
case ExifInterface.ORIENTATION_NORMAL:
rotate = 0;
break;
}
} catch (Exception e) {
e.printStackTrace();
}
if (rotate != 0) {
Matrix matrix = new Matrix();
matrix.postRotate(rotate);
image = Bitmap.createBitmap(image, 0, 0, image.getWidth(),
image.getHeight(), matrix, true);
}
return image;
}
Use this method to determine image rotation.
public int getCameraPhotoOrientation(Uri imageUri, String imagePath) {
int rotate = 0;
try {
_context.getContentResolver().notifyChange(imageUri, null);
File imageFile = new File(imagePath);
ExifInterface exif = new ExifInterface(
imageFile.getAbsolutePath());
int orientation = exif.getAttributeInt(
ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL);
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_270:
rotate = 270;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
rotate = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_90:
rotate = 90;
break;
}
} catch (Exception e) {
}
return rotate;
}
And if the method wouldn't return Zero rotated the image.
int degree=getCameraPhotoOrientation(Uri.fromFile(tempFile), fPath);
if (degree!= 0) {
bitmap = tools.rotateOrientationCall(bitmap, degree);
}
Rotate your bitmap.
public Bitmap rotateOrientationCall(Bitmap src, float degree) {
Matrix matrix = new Matrix();
matrix.postRotate(degree);
return Bitmap.createBitmap(src, 0, 0, src.getWidth(), src.getHeight(), matrix, true);
}
In my app, the image is captured from the camera and then it displays in a ImageView I've done this approach successfully, but when my image is displayed in Imageview, Image display after rotate. I want to rotate Image and then Display in ImageView. When I click image from front camera then image is display proper with the help of bellow code
Matrix matrix = new Matrix();
matrix.postRotate(90);
Bitmap rotate = Bitmap.createBitmap(scale,0,0,scale.getWidth(),scale.getHeight(),matrix,true);
displayImage.setImageBitmap(rotate);
But when I click from back camera Image will display opposite to front camera.
One more thing when I click image from camera from different angle then image will display in ImageView in different angle.
I use following code in my application.
It works for me...!!!
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;
}
hey every one I am Trying to Load Large Images to BackGround of my App Using This Code :
final Drawable drawable =new BitmapDrawable(colorResource,decodeFile(new File(LMApplication.sharedpreferences.getString(path,""))));
new Handler(Looper.getMainLooper()).post(new Runnable() {
#Override
public void run() {
if(LMApplication.CurrentSDK < android.os.Build.VERSION_CODES.JELLY_BEAN) {
view.setBackgroundDrawable(drawable);
}else{
view.setBackground(drawable);
}
}
});
public Bitmap decodeFile(File input){
Bitmap bmpCompressed = null;
try {
//Decode image size
BitmapFactory.Options o11 = new BitmapFactory.Options();
o11.inJustDecodeBounds = true;
BitmapFactory.decodeStream(new FileInputStream(input),null,o11);
//The new size we want to scale to
final int REQUIRED_SIZE=500;
//Find the correct scale value. It should be the power of 2.
int scale=1;
while(o11.outWidth/scale/2>=REQUIRED_SIZE && o11.outHeight/scale/2>=REQUIRED_SIZE)
scale*=2;
//Decode with inSampleSize
BitmapFactory.Options o22 = new BitmapFactory.Options();
o22.inSampleSize=scale;
BitmapFactory.decodeStream(new FileInputStream(input), null, o22);
bmpCompressed = BitmapFactory.decodeFile(input.toString(), o22);
// FileOutputStream out = null;
try {
// out = new FileOutputStream(file);
// bmpCompressed.compress(CompressFormat.JPEG, 100, out);
} catch (Exception e) {
e.printStackTrace();
} finally {
try{
// out.close();
} catch(Throwable ignore) {}
}
} catch (FileNotFoundException e) {}
return bmpCompressed;
}
But Some Images are Rotated 90 degree to the left after the decoding, is there any Problem here or is there any way i can prevent this?
UPDATE :
Changed the Code like This and now prepared for every thing :
public Bitmap decodeFile(File input){
Bitmap bmpCompressed = null;
try {
//Decode image size
BitmapFactory.Options o11 = new BitmapFactory.Options();
o11.inJustDecodeBounds = true;
BitmapFactory.decodeStream(new FileInputStream(input),null,o11);
//The new size we want to scale to
// final int REQUIRED_SIZE=500;
int width = getDimensions.WIDTH;
int height = getDimensions.HEIGHT;
//Find the correct scale value. It should be the power of 2.
int scale=1;
while(o11.outWidth/scale/2>=width && o11.outHeight/scale/2>=height)
scale*=2;
//Decode with inSampleSize
BitmapFactory.Options o22 = new BitmapFactory.Options();
o22.inSampleSize=scale;
BitmapFactory.decodeStream(new FileInputStream(input), null, o22);
bmpCompressed = BitmapFactory.decodeFile(input.toString(), o22);
ExifInterface exif = new ExifInterface(input.getAbsolutePath());
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 1);
if(orientation != ExifInterface.ORIENTATION_NORMAL){
int rotatesize;
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
rotatesize = -90;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
rotatesize = -180;
break;
case ExifInterface.ORIENTATION_ROTATE_270:
rotatesize = -270;
break;
default:
break;
}
Matrix matrix = new Matrix();
matrix.postRotate(90);
bmpCompressed = Bitmap.createBitmap(bmpCompressed, 0, 0, bmpCompressed.getWidth(), bmpCompressed.getHeight(), matrix, true);
}
// FileOutputStream out = null;
try {
// out = new FileOutputStream(file);
// bmpCompressed.compress(CompressFormat.JPEG, 100, out);
} catch (Exception e) {
e.printStackTrace();
} finally {
try{
// out.close();
} catch(Throwable ignore) {}
}
} catch (IOException e) {}
return bmpCompressed;
}
Use ExifInterface for rotate like this
picturePath = getIntent().getStringExtra("path");
Bitmap bitmap = BitmapFactory.decodeFile(picturePath);
ExifInterface exif = new ExifInterface(picturePath);
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED);
Matrix matrix = new Matrix();
switch (orientation) {
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;
}
myImageView.setImageBitmap(bitmap);
bitmap.recycle();
Note : Here picturePath is selected Image's path from Gallery
I was facing a problem image capture from camera it was showing image in landscape even though i capture that image in portrait then i found code online. But i think there is some problem with this code it sometimes didn't work (show image in landscape). So what's wrong there
private void adjustImageOrientation()
{
ExifInterface exif;
int rotate = 0;
try
{
exif = new ExifInterface(filepath);
int exifOrientation = exif.getAttributeInt(
ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL);
switch (exifOrientation)
{
case ExifInterface.ORIENTATION_ROTATE_90:
rotate = 90;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
rotate = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_270:
rotate = 270;
break;
}
if (rotate != 0)
{
int w = bitmap.getWidth();
int h = bitmap.getHeight();
// Setting pre rotate
Matrix mtx = new Matrix();
mtx.preRotate(rotate);
// Rotating Bitmap & convert to ARGB_8888, required by tess
try
{
bitmap = Bitmap.createBitmap(bitmap, 0, 0, w, h, mtx, false);
}
catch(OutOfMemoryError e)
{
e.printStackTrace();
//image = Bitmap.createBitmap(image, 0, 0, w/2, h/2, mtx, false);
}
}
}
catch(Exception ex)
{
ex.printStackTrace();
}
// return image.copy(Bitmap.Config.ARGB_8888, true);
}