How to set width and height auto when rotated image? - android

When i capture photo in portrait mode, it is landscaped and I use this function to rotate image
private Bitmap rotateImage(String mCurrentPhotoPath, String rotationAngle){
//Set hardCode size imageView 300dp
int targetW = CommonUtils.ConvertDpTPpx(mContext, 300);
int targetH = CommonUtils.ConvertDpTPpx(mContext, 300);
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inJustDecodeBounds = true;
BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
int photoW = bmOptions.outWidth;
int photoH = bmOptions.outHeight;
int scaleFactor = Math.min(photoW / targetW, photoH / targetH);
bmOptions.inJustDecodeBounds = false;
bmOptions.inSampleSize = scaleFactor;
bmOptions.inPurgeable = true;
Bitmap bitmap = BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
Matrix matrix = new Matrix();
matrix.setRotate(Float.parseFloat(rotationAngle), (float) bitmap.getWidth() / 2, (float) bitmap.getHeight() / 2);
return Bitmap.createBitmap(bitmap, 0, 0, photoW/2, photoH/2, matrix, true);
}
When I build on device on S4, it runs right, but when it run on Sony Docomo (SO-04E) and LG LTE2, after capture photo and app crash. A bug is x + width (image) < bitmap.width. And then i edit photoW/4 and photoH/4 so Sony and LG run right but S4 image is cropped. So, at the return line, how i should fix the width and height to run right on all device.

Related

Getting Full sized image from camera, Memory Issue

I am using this line of code for getting the full sized image, i am not setting this image on any view, still this line when executed takes a lot of ram, around 110-120m, any solutions ? I even tried running this code in Backgroung thread using Async Task. The picture resolution is 4008*5344.
Bitmap image = MediaStore.Images.Media.getBitmap(getContentResolver(),Uri.parse(mCurrentPhotoPath));
And the below method given in developers site, gives me Null bitmap.
private void setPic() {
// Get the dimensions of the View
int targetW = mImageView.getWidth();
int targetH = mImageView.getHeight();
// Get the dimensions of the bitmap
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inJustDecodeBounds = true;
BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
int photoW = bmOptions.outWidth;
int photoH = bmOptions.outHeight;
// Determine how much to scale down the image
int scaleFactor = Math.min(photoW/targetW, photoH/targetH);
// Decode the image file into a Bitmap sized to fill the View
bmOptions.inJustDecodeBounds = false;
bmOptions.inSampleSize = scaleFactor;
bmOptions.inPurgeable = true;
Bitmap bitmap = BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
mImageView.setImageBitmap(bitmap);
}

Scale bitmap around center pivot

I need to make an icon on Home screen from image. I use the standart code for this:
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inJustDecodeBounds = true;
BitmapFactory.decodeFile(imagePath, bmOptions);
int photoW = bmOptions.outWidth;
int photoH = bmOptions.outHeight;
// Determine how much to scale down the image
final int scaleFactor = (int) Math.max(photoW/app_icon_size, photoH/app_icon_size);
// Decode the image file into a Bitmap sized to fill needed sizes
bmOptions.inJustDecodeBounds = false;
bmOptions.inSampleSize = scaleFactor;
Bitmap bitmap = BitmapFactory.decodeFile(imagePath, bmOptions);
return bitmap;
But because of using integer rather than float for inSampleSize i have to downscale bitmap a little more to fit it exactly to sizes i need:
final float aspectRatio = (float) bitmap.getWidth()/bitmap.getHeight();
final int finalW = (aspectRatio < 1 ? (int) (app_icon_size*aspectRatio) : app_icon_size);
final int finalH = (aspectRatio > 1 ? (int) (app_icon_size/aspectRatio) : app_icon_size);
bitmap = Bitmap.createScaledBitmap(bitmap, finalW, finalH, false);
Everything is nice exept it is scaled from its 0,0 point. So i tried to use createBitmap with Matrix instead of createScaledBitmap:
Matrix scaleMatrix = new Matrix();
scaleMatrix.setScale((float) finalW/bitmap.getWidth(), (float) finalH/bitmap.getHeight(), (float) bitmap.getWidth()/2, (float) bitmap.getHeight()/2);
bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), scaleMatrix, false);
But nothing changed, it still scales from 0,0. This is banal question i guess, but most solutions on Stack and other resources concern Canvas and View but i need to scale Bitmap itslef.

Image scaling approach

I want to show 4 images in 2 x 2 grid format on the screen. Images are sourced from google image search and images are square of 200 X 200
This is my approach to scale them. RelativeLayout with 4 nested RelativeLayout and each layout has imageView in it. and this is how I get screen width to scale images. Setting internal layoutparams height and width to screenWidth/2 and then scaling images.
this is what I am doing to get the image height and width for particular screen. e.g if screen width is 550 then my image size would be 275 x 275.
public static int getOptionWidth(Context context) {
DisplayMetrics metrics = context.getResources().getDisplayMetrics();
return metrics.widthPixels;
}
optionWidth = (getOptionWidth(context) / 2)
This is for unscaled bitmap
public static Bitmap resourceDecoder(byte[] imgBytes, int destWidth, int destHeight) {
Options options = new Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeByteArray(imgBytes, 0, imgBytes.length, options);
options.inJustDecodeBounds = false;
float srcAspect = (float) srcWidth / (float) srcHeight;
float dstAspect = (float) dstWidth / (float) dstHeight;
if (srcAspect > dstAspect) {
options.inSampleSize = srcHeight / dstHeight;
} else {
options.inSampleSize = srcWidth / dstWidth;
}
Bitmap unscaledBitmap = BitmapFactory.decodeByteArray(imgBytes, 0, imgBytes.length, options);
return unscaledBitmap;
}
This will be my destination width and height because I need images in square. I have implemented basic method to get source rectangle (getSrcRect) and get destination rectangle (getDstRect)
Rect srcRect = getSrcRect(unscaledBitmap.getWidth(), unscaledBitmap.getHeight(), dstWidth, dstHeight);
Rect dstRect = getDstRect(unscaledBitmap.getWidth(), unscaledBitmap.getHeight(), dstWidth, dstHeight);
Bitmap scaledBitmap = Bitmap.createBitmap(dstRect.width(), dstRect.height(), Config.ARGB_8888);
Canvas canvas = new Canvas(scaledBitmap);
canvas.drawBitmap(unscaledBitmap, srcRect, dstRect, new Paint(Paint.FILTER_BITMAP_FLAG));
return scaledBitmap;
This is working fine and results are coming as expected (tested on hdpi, xhdpi and mdpi). But now I am confused as I am no using dxtopx or pxTodX conversion. Am I missing something? though results are as expected I am little worried about the approach. I don't know should I use pxToDx or vice-versa. If I do how does it affect my result and how should I use these.
You don't have to use PX to DP conversion for this, because you already set all of your size variables relative to screen width by using getOptionWidth(context).

How to resize bitmap to maximum available size?

I have very large bitmap image. My source
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeStream(new FileInputStream(f), null, o);
// The new size we want to scale to
final int REQUIRED_WIDTH = 1000;
final int REQUIRED_HIGHT = 500;
// Find the correct scale value. It should be the power of 2.
int scale = 1;
while (o.outWidth / scale / 2 >= REQUIRED_WIDTH
&& o.outHeight / scale / 2 >= REQUIRED_HIGHT)
scale *= 2;
// Decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
i want to resize image correctly, i need resize image to maximum available size
for example
i downloaded image size 4000x4000 px and my phone supported 2000x1500 px size
i need anderstend how size suported my phone?
then i resize image to 2000x1500 (for example)
Here you have good to resize bitmap to maximum avaliabe size :
public void onClick() //for example
{
/*
Getting screen diemesions
*/
WindowManager w = getWindowManager();
Display d = w.getDefaultDisplay();
int width = d.getWidth();
int height = d.getHeight();
// "bigging" bitmap
Bitmap nowa = getResizedBitmap(yourbitmap, width, height);
}
public Bitmap getResizedBitmap(Bitmap bm, int newHeight, int newWidth) {
int width = bm.getWidth();
int height = bm.getHeight();
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;
// create a matrix for the manipulation
Matrix matrix = new Matrix();
// resize the bit map
matrix.postScale(scaleWidth, scaleHeight);
// recreate the new Bitmap
Bitmap resizedBitmap = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, false);
return resizedBitmap;
}
I hope I helped
Not So Perfect But here is My solution to Do That,
fun setScaleImageWithConstraint(bitmap: Bitmap): Bitmap {
val maxWidth = 500 //max Height Constraint
val maxHeight = 500 //max Width Constraint
var width = bitmap.width
var height = bitmap.height
if (width > maxWidth || height > maxHeight) {
//If Image is still Large than allowed W/H Half the Size
val quarterWidth = ((width / 2).toFloat() + (width / 3).toFloat()).toInt()
val quarterHeight = ((height / 2).toFloat() + (height / 3).toFloat()).toInt()
val scaledBitmap = Bitmap.createScaledBitmap(bitmap, quarterWidth, quarterHeight, false)
//Recursive Call to Resize and return Resized One
return setScaleImageWithConstraint(scaledBitmap)
} else {
//This will be executed when Image is not violating the Constraints
return bitmap
}
}
Reduce Bitmap 1 Quarter Size Recursively Until the Allowed With And Height is reached.

image rotation not working on Samsung Galaxy Nexus android

I've tested this code snippet on about 25 devices and it works great on all of them except a Samsung Galaxy Nexus that I'm trying to test with now.
Here is the method and I apologize for not trimming it down to find the exact spot that's throwing the exception, but eclipse's debugging is doodoo.
private void setupImageView() {
imageLocation = currentPhotoPath;
// Get the dimensions of the View
Display display = getWindowManager().getDefaultDisplay();
Point size = getDisplaySize(display);
int targetW = size.x;
// Get the dimensions of the bitmap
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inJustDecodeBounds = true;
BitmapFactory.decodeFile(imageLocation, bmOptions);
int photoW = bmOptions.outWidth;
int photoH = bmOptions.outHeight;
// Determine how much to scale down the image
int scaleFactor = Math.min(photoW / targetW, photoH / targetW);
// Decode the image file into a Bitmap sized to fill the View
bmOptions.inJustDecodeBounds = false;
bmOptions.inSampleSize = scaleFactor;
bmOptions.inPurgeable = true;
Bitmap bitmap = BitmapFactory.decodeFile(imageLocation, bmOptions);
//int rotationForImage = getRotationForImage(imageLocation);
int rotationForImage = (whichCamera == 0 ? 90 : 270);
if (rotationForImage != 0) {
int targetWidth = rotationForImage == 90 || rotationForImage == 270 ? bitmap.getHeight() : bitmap.getWidth();
int targetHeight = rotationForImage == 90 || rotationForImage == 270 ? bitmap.getWidth() : bitmap.getHeight();
Bitmap rotatedBitmap = Bitmap.createBitmap(targetWidth, targetHeight, bitmap.getConfig());
Canvas canvas = new Canvas(rotatedBitmap);
Matrix matrix = new Matrix();
matrix.setRotate(rotationForImage, bitmap.getWidth() / 2, bitmap.getHeight() / 2);
canvas.drawBitmap(bitmap, matrix, new Paint());
bitmap.recycle();
bitmap = rotatedBitmap;
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 40, bytes);
try
{
File f = new File(imageLocation);
f.createNewFile();
//write the bytes in file
FileOutputStream fo = new FileOutputStream(f);
fo.write(bytes.toByteArray());
fo.close();
}
catch(java.io.IOException e){}
}
imageView.setImageBitmap(bitmap);
}
anyone know what Samsung does differently with the nexus that would cause this to throw an exception? It works fine on a Galaxy S III
It looks like something in the if block you mention is throwing an NPE - that's the real bug here. Don't worry about the Activity/ResultInfo stuff, that is downstream and triggered by the NPE. Go line by line and look for the null reference :-)
Regarding Eclipse - sadly I don't have much experience there. For Android I personally use IntelliJ and the debugging works well. Are you able to debug other Java code (even a simple Hello, World)?

Categories

Resources