I am developing a camera application,my problem is that ,On some devices the images taken by the camera is rotating, when setting it to an imageview ,So that i have searched for a solution ,and i found a solution from this link.camera intent auto rotate to 90 degree. My problem is when i call the method to generate rotated bitmap image ,it shows a NPE on the following line
Bitmap rotatedBitmap = Bitmap.createBitmap( bitencoded, 0, 0, bitencoded.getWidth(),
bitencoded.getHeight(), matrix, true);
Full code
private Bitmap rotateCam()
{
Matrix matrix = new Matrix();
matrix.postRotate(getImageOrientation(picturePath));
Bitmap rotatedBitmap = Bitmap.createBitmap( bitencoded, 0, 0, bitencoded.getWidth(),
bitencoded.getHeight(), matrix, true);
imageView.setImageBitmap(rotatedBitmap);
return rotatedBitmap;
}
LogCat
java.lang.NullPointerException
at project1.me.com.update.ImageUploadActivity.rotateCam(ImageUploadActivity.java:235)
at project1.me.com.update.ImageUploadActivity.onCreate(ImageUploadActivity.java:182)
at android.app.Activity.performCreate(Activity.java:5206)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1094)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2074)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2135)
at android.app.ActivityThread.access$700(ActivityThread.java:140)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1237)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4921)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1027)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:794)
at dalvik.system.NativeStart.main(Native Method)
onCreate
byte[] data = picturePath.getBytes("UTF-8");
String base64PicPath = Base64.encodeToString(data, Base64.DEFAULT);
bitencoded= stringToBitMap(base64PicPath);
try
{
rotateCam();
Log.e(" Rotated", "Method called");
}
catch(Exception e)
{
Log.e("Not Rotated","Method not called");
e.printStackTrace();
Log.e(e.getClass().getName(), e.getMessage(), e);
}
getImageOrientation()
public static int getImageOrientation(String imagePath){
int rotate = 0;
try {
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 (IOException e) {
e.printStackTrace();
}
return rotate;
}
I am a beginner ,i could not find reason for NPE.Can anybode help me out?.Thanx in advance.
Use this Method to convert bitmap.
private Bitmap decodeFile(String filePath) {
// Decode image size
try {
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeFile(filePath, o);
final int REQUIRED_SIZE = 1024;
int width_tmp = o.outWidth, height_tmp = o.outHeight;
int scale = 1;
while (true) {
if (width_tmp < REQUIRED_SIZE && height_tmp < REQUIRED_SIZE)
break;
width_tmp /= 2;
height_tmp /= 2;
scale *= 2;
}
o.inJustDecodeBounds = false;
// Decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
bitmap = BitmapFactory.decodeFile(filePath, o2);
}
catch (Exception e) {
Log.e(e.getClass().getName(), e.getMessage(), e);
}
return bitmap;
}
And onCreate():
bitmap = decodeFile(picturePath);
rotateCam();
Set the ImageView in rotateCam():
public void rotateCam() {
Matrix matrix = new Matrix();
matrix.postRotate(getImageOrientation(picturePath));
Bitmap rotatedBitmap = Bitmap.createBitmap(bitmap, 0, 0,
bitmap.getWidth(),
bitmap.getHeight(), matrix, true);
imageView = (ImageView) findViewById(R.id.imgView);
imageView.setImageBitmap(rotatedBitmap);
}
Bitmap bitencoded=null;
bitencode.getWidth();
You are calling method getWidth() on a null reference bitencoded.
Should be doing this instead,
Bitmap bitencode = BitmapFactory.decodeResource(getResources(), R.drawable.yourBitmap);
then,
bitencode.getWidth();
Related
I am using the following method to get the Bitmap from a Uri :
private static Bitmap getBitmapFromUri(#NonNull Context context, #NonNull Uri uri) throws IOException {
ParcelFileDescriptor parcelFileDescriptor =
context.getContentResolver().openFileDescriptor(uri, "r");
assert parcelFileDescriptor != null;
FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor();
Bitmap image = BitmapFactory.decodeFileDescriptor(fileDescriptor);
parcelFileDescriptor.close();
return image;
}
The problem is, I am sometimes getting OOM errors in the return statement from Crashlytics. I assume it is happening because the selected image is of a large size. How do modify it so as to return the best quality scaled down version of Bitmap so that it does not cause Out of memory error?
Edit I have posted an answer myself. Please have a look and let me know it is the correct way to do it.
You have to resize your image before decode. Here is my code to decode an image and display it in an image view.
private void loadImage(Uri u, String path) {
try {
ContentResolver cr = context.getContentResolver();
InputStream in;
in = cr.openInputStream(u);
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeStream(in, null, o);
in.close();
int scale = 1;
if (o.outHeight > IMAGE_MAX_SIZE || o.outWidth > IMAGE_MAX_SIZE) {
scale = (int) Math.pow(2, (int) Math.round(Math.log(IMAGE_MAX_SIZE / (double) Math.max(o.outHeight, o.outWidth)) / Math.log(0.5)));
}
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
in = cr.openInputStream(u);
Bitmap bitmap = BitmapFactory.decodeStream(in, null, o2);
in.close();
Bitmap rotatedBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), getRotation(path), true);
int nh = (int) ( rotatedBitmap.getHeight() * (512.0 / rotatedBitmap.getWidth()) );
Bitmap scaled = Bitmap.createScaledBitmap(rotatedBitmap, 512, nh, true);
String pathTest = MediaStore.Images.Media.insertImage(context.getContentResolver(), scaled, "Title", null);
ImageLoader imageLoader = ImageLoader.getInstance();
imageLoader.displayImage(Uri.decode(Uri.parse(pathTest).toString()), mPicture, new ImageLoadingListener() {
#Override
public void onLoadingStarted(String imageUri, View view) {
}
#Override
public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
}
#Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
mPicture.setImageBitmap(loadedImage);
}
#Override
public void onLoadingCancelled(String imageUri, View view) {
}
});
} catch (Exception e) {
//Toast.makeText(context, context.getString(R.string.fail_to_load_image), Toast.LENGTH_SHORT).show();
Log.e("TAG", e.toString());
}
}
private Matrix getRotation(String pathPetPicture) {
Matrix matrix = new Matrix();
try {
ExifInterface exif = new ExifInterface(pathPetPicture);
int rotation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED);
switch (rotation) {
case ExifInterface.ORIENTATION_FLIP_HORIZONTAL:
matrix.setScale(-1, 1);
break;
case ExifInterface.ORIENTATION_ROTATE_180:
matrix.setRotate(180);
break;
case ExifInterface.ORIENTATION_FLIP_VERTICAL:
matrix.setRotate(180);
matrix.postScale(-1, 1);
break;
case ExifInterface.ORIENTATION_TRANSPOSE:
matrix.setRotate(90);
matrix.postScale(-1, 1);
break;
case ExifInterface.ORIENTATION_ROTATE_90:
matrix.setRotate(90);
break;
case ExifInterface.ORIENTATION_TRANSVERSE:
matrix.setRotate(-90);
matrix.postScale(-1, 1);
break;
case ExifInterface.ORIENTATION_ROTATE_270:
matrix.setRotate(-90);
break;
case ExifInterface.ORIENTATION_NORMAL:
default:
break;
}
} catch (Exception e) {
Log.e("TAG", e.toString());
}
return matrix;
}
Try something like this...
// decode image
public Bitmap decodeFile(String filePath) {
// Decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeFile(filePath, o);
// The new size we want to scale to
final int REQUIRED_SIZE = 1024;
// Find the correct scale value. It should be the power of 2.
int width_tmp = o.outWidth, height_tmp = o.outHeight;
int scale = 1;
while (true) {
if (width_tmp < REQUIRED_SIZE && height_tmp < REQUIRED_SIZE)
break;
width_tmp /= 2;
height_tmp /= 2;
scale *= 2;
}
// Decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
bitmap = BitmapFactory.decodeFile(filePath, o2);
return bitmap;
}
May it help.
and if you want Loading Large Bitmaps Efficiently then follow this
Bitmap bm;
bm = Bitmap.createScaledBitmap(BitmapFactory.decodeFile(filepath), 100, 100, true);
mPicture = new ImageView(context);
mPicture.setImageBitmap(bm);
Use this and replace your code with this in getBitmapFromUri()
I read all the answers and this is what I am planning to do, tell me if it will work or not. In my Application class, in onCreate(), I store the device width and height in pixels in the SharedPreferences. In the modified code, I scale the bitmap according to the device pixels. Hope it will spare me the OOM error.
private static Bitmap getBitmapFromUri(#NonNull Context context, #NonNull Uri uri) throws IOException {
ParcelFileDescriptor parcelFileDescriptor =
context.getContentResolver().openFileDescriptor(uri, "r");
assert parcelFileDescriptor != null;
FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor();
Bitmap image = BitmapFactory.decodeFileDescriptor(fileDescriptor);
parcelFileDescriptor.close();
TinyDB tinyDB = new TinyDB(context);
int maxSize = Math.min(tinyDB.getInt(AppConstants.DEVICE_WIDTH, 720), tinyDB.getInt(AppConstants.DEVICE_HEIGHT, 1080));
int outWidth;
int outHeight;
int inWidth = image.getWidth();
int inHeight = image.getHeight();
if(inWidth > inHeight){
outWidth = maxSize;
outHeight = (inHeight * maxSize) / inWidth;
} else {
outHeight = maxSize;
outWidth = (inWidth * maxSize) / inHeight;
}
return Bitmap.createScaledBitmap(image, outWidth, outHeight, false);
}
Use Glide or Picasso libraries:
Replace path with local folder path or server url
Glide.with (context).load (path).asBitmap().into(imageView);
On Android, i'm trying to crop an image bitmap taken from camera to a fixed width / width which is smaller than the original photo taken, but when I create the cropped image the result always gets rotated (even if no matrix is defined) see http://i.imgur.com/MppWH69l.png
as original and http://i.imgur.com/C4WVtwZl.png as the cropped Image, which is being rotated and shows up incorrectly.
Why does the createBitmap method rotates the bitmap to be drawn in the destination bitmap.
Relevant code as follows
try { int dstWidth = params[0].intValue();
int dstHeight = params[1].intValue();
int targetSize = Math.min(dstWidth, dstHeight);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeStream(getActivity().getContentResolver().openInputStream(mPhotoUri), null, options);
//calculate min inSampleSize for avoiding memory problems
options.inSampleSize = calculateImageInSampleSize(options, targetSize, targetSize);
options.inJustDecodeBounds = false;
Bitmap originalPhotoBitmap = BitmapFactory.decodeStream(getActivity().getContentResolver()
.openInputStream(mPhotoUri), null, options);
mOriginalBitmap = Bitmap.createBitmap(originalPhotoBitmap, originalPhotoBitmap.getWidth() - targetSize,
originalPhotoBitmap.getHeight() - targetSize, targetSize, targetSize);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
//codefor inSampleSize calculation from http://developer.android.com/training/displaying-bitmaps/load-bitmap.html#load-bitmap
private int calculateImageInSampleSize(BitmapFactory.Options originalSize, int targetWidth, int targetHeight) {
final int width = originalSize.outWidth;
final int height = originalSize.outHeight;
int inSampleSize = 1;
if (height > targetHeight || width > targetWidth) {
final int halfHeight = height /2;
final int halfWidth = width /2;
while ((halfHeight /inSampleSize) > targetHeight &&
(halfWidth / inSampleSize) > targetWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
every device followed different orientation in camera so you followed this example solve your problem
private Bitmap imageRotating(String filePath){
try{
ExifInterface exif = new ExifInterface(filePath);
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED);
return rotateBitmap(decodeSampledBitmapFromResource(filePath,150,224), orientation);
}
catch(Exception e){
e.printStackTrace();
return null;
}
}
public static Bitmap rotateBitmap(Bitmap bitmap, int orientation) {
try{
Matrix matrix = new Matrix();
switch (orientation) {
case ExifInterface.ORIENTATION_NORMAL:
return bitmap;
case ExifInterface.ORIENTATION_FLIP_HORIZONTAL:
matrix.setScale(-1, 1);
break;
case ExifInterface.ORIENTATION_ROTATE_180:
matrix.setRotate(180);
break;
case ExifInterface.ORIENTATION_FLIP_VERTICAL:
matrix.setRotate(180);
matrix.postScale(-1, 1);
break;
case ExifInterface.ORIENTATION_TRANSPOSE:
matrix.setRotate(90);
matrix.postScale(-1, 1);
break;
case ExifInterface.ORIENTATION_ROTATE_90:
matrix.setRotate(90);
break;
case ExifInterface.ORIENTATION_TRANSVERSE:
matrix.setRotate(-90);
matrix.postScale(-1, 1);
break;
case ExifInterface.ORIENTATION_ROTATE_270:
matrix.setRotate(-90);
break;
default:
return bitmap;
}
try {
Bitmap bmRotated = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
bitmap.recycle();
return bmRotated;
}
catch (OutOfMemoryError e) {
e.printStackTrace();
return null;
}
}
catch (Exception e) {
e.printStackTrace();
return null;
}
}
Hello I am working on one android app where I need to capture the image using camera intent and set the bitmap in the imageview but here bitmap is rotated by 90 degree. I have checked many threads of stackoverflow like Photo rotate 90 degree while capture in some phones but did not work for me.
Here when I am executing this exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 1); then it is returning 0 ORIENTATION_UNDEFINED and in my getImage function no condition is satisfying.
Intent cameraIntent = new Intent(
android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
capturedPhotoName = System.currentTimeMillis() + ".png";
File photo = new File(Environment.getExternalStorageDirectory(),
capturedPhotoName);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photo));
imageUri = Uri.fromFile(photo);
startActivityForResult(cameraIntent, CAMERA_INTENT_REQUEST);
onActivityResult
Uri selectedImage = imageUri;
getContentResolver().notifyChange(selectedImage, null);
ContentResolver cr = getContentResolver();
Bitmap bitmap;
try {
bitmap = android.provider.MediaStore.Images.Media.getBitmap(cr,
selectedImage);
bitmap = Util.getImage(bitmap, selectedImage.toString());
mPictureImageView.setImageBitmap(bitmap);
} catch (Exception e) {
Log.e("New Issue Activity", e.toString());
}
/**
* Get the image orientation
*
* #param imagePath
* #return orietation angle
* #throws IOException
*/
public static Bitmap getImage(Bitmap bitmap, String path) throws IOException {
Matrix m = new Matrix();
ExifInterface exif = new ExifInterface(path);
int orientation = exif
.getAttributeInt(ExifInterface.TAG_ORIENTATION, 1);
if ((orientation == ExifInterface.ORIENTATION_ROTATE_180)) {
m.postRotate(180);
bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(),
bitmap.getHeight(), m, true);
return bitmap;
} else if (orientation == ExifInterface.ORIENTATION_ROTATE_90) {
m.postRotate(90);
bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(),
bitmap.getHeight(), m, true);
return bitmap;
} else if (orientation == ExifInterface.ORIENTATION_ROTATE_270) {
m.postRotate(270);
bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(),
bitmap.getHeight(), m, true);
return bitmap;
}
return bitmap;
}
I implemented one photo take activity which you can take the photo and set the orientation of the photo. It is supported by every device I tested including Samsung galaxy series, tablets, sony xperia series, tablets.
You can check out my accepted answer about rotation of images on this topic:
Camera capture orientation on samsung devices in android
If you also need to save and use that image that you have rotated, saving and using the photo functions additional to my answer I gave above:
savePhoto function:
public void savePhoto(Bitmap bmp) {
imageFileFolder = new File(Environment.getExternalStorageDirectory(),
cc.getDirectoryName());
imageFileFolder.mkdir();
FileOutputStream out = null;
Calendar c = Calendar.getInstance();
String date = fromInt(c.get(Calendar.MONTH))
+ fromInt(c.get(Calendar.DAY_OF_MONTH))
+ fromInt(c.get(Calendar.YEAR))
+ fromInt(c.get(Calendar.HOUR_OF_DAY))
+ fromInt(c.get(Calendar.MINUTE))
+ fromInt(c.get(Calendar.SECOND));
imageFileName = new File(imageFileFolder, date.toString() + ".jpg");
try {
out = new FileOutputStream(imageFileName);
bmp.compress(Bitmap.CompressFormat.JPEG, 70, out);
out.flush();
out.close();
scanPhoto(imageFileName.toString());
out = null;
} catch (Exception e) {
e.printStackTrace();
}
}
scanPhoto function:
public void scanPhoto(final String imageFileName) {
geniusPath = imageFileName;
msConn = new MediaScannerConnection(MyClass.this,
new MediaScannerConnectionClient() {
public void onMediaScannerConnected() {
msConn.scanFile(imageFileName, null);
}
#Override
public void onScanCompleted(String path, Uri uri) {
msConn.disconnect();
}
});
msConn.connect();
}
SavePhotoTask class:
class SavePhotoTask extends AsyncTask<byte[], String, String> {
#Override
protected String doInBackground(byte[]... jpeg) {
File photo = new File(Environment.getExternalStorageDirectory(),
"photo.jpg");
if (photo.exists()) {
photo.delete();
}
try {
FileOutputStream fos = new FileOutputStream(photo.getPath());
fos.write(jpeg[0]);
fos.close();
} catch (java.io.IOException e) {
}
return (null);
}
}
Try below code:-
Uri selectedImageURI = data.getData();
imageFile = new File(getRealPathFromURI(selectedImageURI));
ExifInterface exif = new ExifInterface(imageFile.toString());
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED);
Bitmap bitmap = Utility.getOrientationFromExif(new Utility().compressImage1(imageFile.toString(),((Activity)context)),orientation);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG , 50 , bos);
Utility.java
public class Utility
{
public Bitmap compressImage1(String imageUri, Activity act)
{
String filePath = getRealPathFromURI(imageUri, act);
BitmapFactory.Options options = new BitmapFactory.Options();
// by setting this field as true, the actual bitmap pixels are not
// loaded in the memory. Just the bounds are loaded. If
// you try the use the bitmap here, you will get null.
options.inJustDecodeBounds = true;
// Bitmap bmp = decodeBitmap(Uri.parse(imageUri), 612, 816, act);
Bitmap bmp = BitmapFactory.decodeFile(filePath, options);
// setting inSampleSize value allows to load a scaled down version of
// the original image
options.inSampleSize = calculateInSampleSize(options, 612, 816);
// inJustDecodeBounds set to false to load the actual bitmap
options.inJustDecodeBounds = false;
// this options allow android to claim the bitmap memory if it runs low
// on memory
options.inPurgeable = true;
options.inInputShareable = true;
options.inTempStorage = new byte[16 * 1024];
// load the bitmap from its path
bmp = BitmapFactory.decodeFile(filePath, options);
return bmp;
}
public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight)
{
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth)
{
final int halfHeight = height / 2;
final int halfWidth = width / 2;
// Calculate the largest inSampleSize value that is a power of 2 and
// keeps both
// height and width larger than the requested height and width.
while ((halfHeight / inSampleSize) > reqHeight && (halfWidth / inSampleSize) > reqWidth)
{
inSampleSize *= 2;
}
}
return inSampleSize;
}
public static Bitmap getOrientationFromExif(Bitmap bitmap, int orientation)
{
int width = bitmap.getWidth();
int height = bitmap.getHeight();
int newWidth = 612;
int newHeight = 816;
// calculate the scale - in this case = 0.4f
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;
Matrix matrix = new Matrix();
switch (orientation)
{
case ExifInterface.ORIENTATION_NORMAL:
return bitmap;
case ExifInterface.ORIENTATION_FLIP_HORIZONTAL:
// matrix.setScale(-1, 1);
matrix.postScale(scaleWidth, scaleHeight);
break;
case ExifInterface.ORIENTATION_ROTATE_180:
matrix.setRotate(180);
break;
case ExifInterface.ORIENTATION_FLIP_VERTICAL:
matrix.setRotate(180);
// matrix.postScale(-1, 1);
matrix.postScale(scaleWidth, scaleHeight);
break;
case ExifInterface.ORIENTATION_TRANSPOSE:
matrix.setRotate(90);
// matrix.postScale(-1, 1);
matrix.postScale(scaleWidth, scaleHeight);
break;
case ExifInterface.ORIENTATION_ROTATE_90:
matrix.setRotate(90);
break;
case ExifInterface.ORIENTATION_TRANSVERSE:
matrix.setRotate(-90);
// matrix.postScale(-1, 1);
matrix.postScale(scaleWidth, scaleHeight);
break;
case ExifInterface.ORIENTATION_ROTATE_270:
matrix.setRotate(-90);
break;
default:
return bitmap;
}
try
{
Bitmap bmRotated = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
bitmap.recycle();
return bmRotated;
}
catch (OutOfMemoryError e)
{
e.printStackTrace();
return null;
}
}
}
This function worked for me, try your luck.
public static Bitmap rotateImage(Bitmap bmp, String imageUrl) {
if (bmp != null) {
ExifInterface ei;
int orientation = 0;
try {
ei = new ExifInterface(imageUrl);
orientation = ei.getAttributeInt(ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL);
} catch (IOException e) {
// TODO Auto-generated catch block
// e.printStackTrace();
}
int bmpWidth = bmp.getWidth();
int bmpHeight = bmp.getHeight();
Matrix matrix = new Matrix();
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
matrix.postRotate(90);
break;
case ExifInterface.ORIENTATION_ROTATE_180:
matrix.postRotate(180);
break;
default:
break;
// etc.
}
Bitmap resizedBitmap = Bitmap.createBitmap(bmp, 0, 0, bmpWidth,
bmpHeight, matrix, true);
return resizedBitmap;
} else {
return bmp;
}
}
I tried loading images from sdcard camera folder,after loading I created bitmap by using scaled bitmap,in that I want to show only some portions of image so I tried using createBitmap() to create a new bitmap,but it is still getting blurred, how can i solve this problem?
File[] files = targetDirector.listFiles();
for (File file : files) {
String path = file.getAbsolutePath();
itemList.add(path);
if (myBitmap != null) {
myBitmap = null;
}
myBitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
System.out.println("thumbnails1 width: " + myBitmap.getWidth());
System.out.println("thumbnails1 height: " + myBitmap.getHeight());
myBitmap = Bitmap.createScaledBitmap(myBitmap, 150, 150, false);
ExifInterface exif;
try {
exif = new ExifInterface(file.getAbsolutePath());
String orientString = exif
.getAttribute(ExifInterface.TAG_ORIENTATION);
int orientation = orientString != null ? Integer
.parseInt(orientString)
: ExifInterface.ORIENTATION_NORMAL;
int rotationAngle = 0;
if (orientation == ExifInterface.ORIENTATION_ROTATE_90) {
System.out.println("photopotart");
rotationAngle = 90;
System.out.println("myBitmap" + myBitmap.getWidth());
System.out.println("myBitmap" + myBitmap.getHeight());
myBitmap = Bitmap.createScaledBitmap(myBitmap, 150, 150,
false);
Matrix matrix = new Matrix();
matrix.postRotate(90);
myBitmap = Bitmap.createBitmap(myBitmap, 0, 0,
150, 150, matrix,
true);
myBitmap = Bitmap.createBitmap(myBitmap, 0, 0, 150, 100 );
myBitmap = highlightImage(myBitmap);
photsList.add(myBitmap);
}
else if (orientation == ExifInterface.ORIENTATION_ROTATE_180) {
System.out.println("180 angle");
rotationAngle = 180;
} else if (orientation == ExifInterface.ORIENTATION_ROTATE_270) {
System.out.println("other 270");
rotationAngle = 270;
} else {
System.out.println("photolandscape");
myBitmap = Bitmap.createScaledBitmap(myBitmap, 150, 150,
false);
myBitmap = Bitmap.createBitmap(myBitmap, 30, 0, 120, 150);
photsList.add(myBitmap);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
My xml file is:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<ImageView
android:id="#+id/img"
android:layout_width="150dip"
android:layout_height="150dip" />
</LinearLayout>
Use the following method for decoding your file path.
public void decodeFile(String filePath) {
// Decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeFile(filePath, o);
// The new size we want to scale to
final int REQUIRED_SIZE = 1024;
// Find the correct scale value. It should be the power of 2.
int width_tmp = o.outWidth, height_tmp = o.outHeight;
int scale = 2;
while (true) {
if (width_tmp < REQUIRED_SIZE && height_tmp < REQUIRED_SIZE)
break;
width_tmp /= 2;
height_tmp /= 2;
scale *= 2;
}
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
bmp = BitmapFactory.decodeFile(filePath, o2); // this bmp object of Bitmap is global and you can set it to your ImageView.
}
Now you can call this function replace with this one
myBitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
to
decodeFile(file.getAbsolutePath());
You can set your scale variable according to your requirement that you can get your image with very good clarity.
public Bitmap RotationPic(Bitmap tmpBitmap){
int x = tmpBitmap.getWidth();
int y = tmpBitmap.getHeight();
if(x > y){
Matrix matrix = new Matrix();
matrix.reset();
matrix.setRotate(90);
return Bitmap.createBitmap(tmpBitmap,0,0, x, y,matrix, true);
}
return tmpBitmap;
}
The sentence Bitmap.createBitmap(tmpBitmap,0,0, x, y,matrix, true); has the error.
I read the network picture and the picture size is large, about 100k~300k.
How to solve this problem? Is there any other way to rotate picture?
try this
but you need the path of pic to use this.
if you do not like resolution increase REQUIRED_SIZE value
public static Bitmap DecodeFileToBitmap (String path)
{
try
{
File f = new File(path);
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeStream(new FileInputStream(f),null,o);
final int REQUIRED_SIZE=500;
int scale=1;
while(o.outWidth/scale/2>=REQUIRED_SIZE && o.outHeight/scale/2>=REQUIRED_SIZE)
scale*=2;
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize=scale;
Bitmap bm = BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
Bitmap bitmap = bm;
ExifInterface exif = null;
try
{
exif = new ExifInterface(path);
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 1);
Matrix m = new Matrix();
if ((orientation == 3))
{
m.postRotate(180);
m.postScale((float) bm.getWidth(), (float) bm.getHeight());
bitmap = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(),bm.getHeight(), m, true);
return bitmap;
}
else if (orientation == 6)
{
m.postRotate(90);
bitmap = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(),bm.getHeight(), m, true);
return bitmap;
}
else if (orientation == 8)
{
m.postRotate(270);
bitmap = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(),bm.getHeight(), m, true);
return bitmap;
}
return bitmap;
}
catch(Exception ex) {}
}
catch (FileNotFoundException e) {}
return null;
}
Substitute Bitmap.createBitmap(tmpBitmap,0,0, x, y,matrix, true); to Bitmap.createBitmap(tmpBitmap,0,0, y, x,matrix, true); when you rotating image on 90 degree width=height and height=width