I'm trying to set a wallpaper but I get banding. I have a large gradient JPG which is saved on my device. I read it from file, scale it so that its height matches the height of the device then I set the wallpaper and the wallpaper hints. The scaling step seems to be converting it to a RGB565 format rather than the original ARGB888 format. Also, I dont seem to have any dither which might help aleviate the banding.
Here is my code:
public class WallpaperSetter {
public static void setWallpaper(String url, Context context) throws IOException {
FileCache cache = new FileCache(context);
File f = cache.getFile(url);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
options.inDither = true;
Bitmap bmp = BitmapFactory.decodeStream(new FileInputStream(f), null, options);
Display display = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
int targetHeight = display.getHeight() > display.getWidth() ? display.getHeight() : display.getWidth() - 10;
int targetWidth = (int) ((float) targetHeight / (float) bmp.getHeight() * (float) bmp.getWidth());
Bitmap resizedBitmap = resize(bmp, targetHeight, targetWidth);
WallpaperManager manager = (WallpaperManager) context.getSystemService(Context.WALLPAPER_SERVICE);
manager.setBitmap(resizedBitmap);
int displayHeight = display.getHeight() > display.getWidth() ? display.getHeight() : display.getWidth();
int displayWidth = display.getHeight() > display.getWidth() ? display.getWidth() : display.getHeight();
int height = resizedBitmap.getHeight() > displayHeight ? resizedBitmap.getHeight() : displayHeight;
int width = resizedBitmap.getWidth() < displayWidth ? displayWidth : resizedBitmap.getWidth();
manager.suggestDesiredDimensions(width, height);
}
private static Bitmap resize(Bitmap bitmap, int targetHeight, int targetWidth) {
System.out.println("config start: " + bitmap.getConfig().name().toString());
Bitmap b = Bitmap.createScaledBitmap(bitmap, targetWidth, targetHeight, false);
System.out.println("config: " + b.getConfig().name().toString());
return b;
}
}
I'm developing on a SGS2 with CyanogenMod if that makes a difference.
I found that adding some noise or subtle randomness to a gradient image helps reduce banding, but I suspect using a .png containing at least a pixel of alpha (weird but works) and RGB565 format is the way to go. Also I found that using the 'raw' resources folder instead of 'drawable' folder prevented Android assuming it could compress the image internally. Here's the code I used anyway:
private void generateBackgroundGraphic() {
background = BitmapFactory.decodeResource(res, R.raw.gradient);
//create local copy of 'background' bitmap size
Bitmap tempB = Bitmap.createBitmap(background.getWidth(), background.getHeight(), Bitmap.Config.RGB_565);
backgroundPaint.setDither(true);
//wrap a canvas around 'background' bitmap
Canvas tempC = new Canvas (tempB);
tempC.drawBitmap(background, 0, 0, null);
background = Bitmap.createScaledBitmap(tempB, globalCanvasSize.x, globalCanvasSize.y, false);
tempB.recycle();
tempB = null;
tempC = null;
}
I hope this is of some use to you... Android deals with images strangely sometimes :-/
Chris
My final code which works even though I suspect there is a much simpler way to do this:
public class WallpaperSetter {
public static void setWallpaper(String url, Context context) throws IOException {
FileCache cache = new FileCache(context);
File f = cache.getFile(url);
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeStream(new FileInputStream(f), null, o);
// Find the correct scale value. It should be the power of 2.
int width_tmp = o.outWidth, height_tmp = o.outHeight;
int scale = 1;
Display display = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
int targetHeight = display.getHeight() > display.getWidth() ? display.getHeight() : display.getWidth() - 10;
int targetWidth = (int) ((float) targetHeight / (float) o.outHeight * (float) o.outWidth);
while (true) {
if (width_tmp / 2 < targetWidth || height_tmp / 2 < targetHeight)
break;
width_tmp /= 2;
height_tmp /= 2;
scale++;
}
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
o2.inPreferredConfig = Bitmap.Config.ARGB_8888;
o2.inDither = false;
Bitmap b = BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
Bitmap b565 = Bitmap.createBitmap(b.getWidth(), b.getHeight(), Bitmap.Config.RGB_565);
Canvas c = new Canvas(b565);
c.drawBitmap(b, 0, 0, null);
b = Bitmap.createScaledBitmap(b565, targetWidth, targetHeight, false);
b565.recycle();
b565 = null;
c = null;
WallpaperManager manager = (WallpaperManager) context.getSystemService(Context.WALLPAPER_SERVICE);
manager.setBitmap(b);
int displayHeight = display.getHeight() > display.getWidth() ? display.getHeight() : display.getWidth();
int displayWidth = display.getHeight() > display.getWidth() ? display.getWidth() : display.getHeight();
int height = b.getHeight() > displayHeight ? b.getHeight() : displayHeight;
int width = b.getWidth() < displayWidth ? displayWidth : b.getWidth();
manager.suggestDesiredDimensions(width, height);
}
}
Related
im trying to get imageview from drawable and resize it my current code is working on all devices except on oppo devices it crash inside crop() method
the crash im getting is on the first line in crop() method you can find below
Caused by: java.lang.NullPointerException:
my current code is:
public Bitmap getTileBitmap(int id, int size) {
String string = tileUrls.get(id);
if (string.contains(Themes.URI_DRAWABLE)) {
String drawableResourceName = string.substring(Themes.URI_DRAWABLE.length());
int drawableResourceId = Shared.context.getResources().getIdentifier(drawableResourceName, "drawable", Shared.context.getPackageName());
Bitmap bitmap = Utils.scaleDown(drawableResourceId, size, size);
return Utils.crop(bitmap, size, size);
}
return null;
}
public static Bitmap crop(Bitmap source, int newHeight, int newWidth) {
int sourceWidth = source.getWidth();
int sourceHeight = source.getHeight();
float xScale = (float) newWidth / sourceWidth;
float yScale = (float) newHeight / sourceHeight;
float scale = Math.max(xScale, yScale);
float scaledWidth = scale * sourceWidth;
float scaledHeight = scale * sourceHeight;
float left = (newWidth - scaledWidth) / 2;
float top = (newHeight - scaledHeight) / 2;
RectF targetRect = new RectF(left, top, left + scaledWidth, top + scaledHeight);
Bitmap dest = Bitmap.createBitmap(newWidth, newHeight, source.getConfig());
Canvas canvas = new Canvas(dest);
canvas.drawBitmap(source, null, targetRect, null);
return dest;
}
EDIT: added scale method which may cause the issue
public static Bitmap scaleDown(int resource, int reqWidth, int reqHeight) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(Shared.context.getResources(), resource);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(Shared.context.getResources(), resource, options);
}
and so far im not sure what is causing the crash only on oppo devices
Try this:
options.inJustDecodeBounds = true;
options.inScaled = false;
options.inDensity = 0;
options.inMutable = true; //API 11. Pass to canvas? Might crash without this.
//Load the image here... BitmapFactory.decodeResource()...
... //Some calculations.
options.inJustDecodeBounds = false;
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
All I have used to get the image as the background on canvas
canvas.drawBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.help_4, 0, 0, null);
And I get a large image. So can anyone pls. provide me a solution to get the Image set according to the Device size. As I'm new to coding a detailed explanation would be appreciated :)
Thank You
You're almost there. You just need to configure the BitmapFactory.Options variable by setting the output width and height (based on the screen size):
BitmapFactory.Options options = new BitmapFactory.Options();
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
options.outHeight = size.x;
options.outWidth = size.y;
canvas.drawBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.help_4, options));
Determine the device width and height and scale it:
int deviceWidth = getWindowManager().getDefaultDisplay()
.getWidth();
int deviceHeight = getWindowManager().getDefaultDisplay()
.getHeight();
So in complete you can use the following ready-to-use snippet taken from here:
public Bitmap scaleToActualAspectRatio(Bitmap bitmap) {
if (bitmap != null) {
boolean flag = true;
int deviceWidth = getWindowManager().getDefaultDisplay()
.getWidth();
int deviceHeight = getWindowManager().getDefaultDisplay()
.getHeight();
int bitmapHeight = bitmap.getHeight();
int bitmapWidth = bitmap.getWidth();
if (bitmapWidth > deviceWidth) {
flag = false;
// scale According to WIDTH
int scaledWidth = deviceWidth;
int scaledHeight = (scaledWidth * bitmapHeight) / bitmapWidth;
try {
if (scaledHeight > deviceHeight)
scaledHeight = deviceHeight;
bitmap = Bitmap.createScaledBitmap(bitmap, scaledWidth,
scaledHeight, true);
} catch (Exception e) {
e.printStackTrace();
}
}
if (flag) {
if (bitmapHeight > deviceHeight) {
// scale According to HEIGHT
int scaledHeight = deviceHeight;
int scaledWidth = (scaledHeight * bitmapWidth) / bitmapHeight;
try {
if (scaledWidth > deviceWidth)
scaledWidth = deviceWidth;
bitmap = Bitmap.createScaledBitmap(bitmap, scaledWidth,
scaledHeight, true);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
return bitmap;
}
So finaly use:
myCanvas.drawBitmap(scaleToActualAspectRatio(myBitmap), X, Y, null)
The process would look something like this:
Get screen size
Calculate new image size (keeping aspect ratio)
Decode bitmap to new size.
Get screen size
To get the exact screen size of a device, use DisplayMetrics...
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
The metrics variable will now contain the screen dimensions in pixels. You can get the values by using metrics.widthPixels and metrics.heightPixels.
Calculate new image size (keeping aspect ratio)
To calculate new image size, we can use BitmapFactory.Options and tell it to scale the image down by a factor of x. To calculate that factor (also referred as inSampleSize), use the following method...
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) {
// Calculate ratios of height and width to requested height and width
final int heightRatio = Math.round((float) height / (float) reqHeight);
final int widthRatio = Math.round((float) width / (float) reqWidth);
// Choose the smallest ratio as inSampleSize value, this will guarantee
// a final image with both dimensions larger than or equal to the
// requested height and width.
inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
}
return inSampleSize;
}
Decode Bitmap to new size
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(getResources(), R.drawable.help_4, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, metrics.widthPixels, metrics.heightPixels);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(getResources(), R.drawable.help_4, options);
The inJustDecodeBounds option tells the framework to null out the Bitmap to prevent OOM exceptions, since we are only interested in the dimensions, and not the actual image.
This method will ensure that the Bitmap is scaled efficiently. Read more here: http://developer.android.com/training/displaying-bitmaps/load-bitmap.html
I have tried setting dithering everywhere I can find. I also tried setting everything to ARGB_8888 and STILL there is very bad banding on my background image. My background image is 640x960 and it works fine on my physical phone that is 720x1280 but on an emulator running at 320x480 I get the bad color banding. I put my code below. If you have any suggestions please help!
public void onCreate(Bundle instanceBundle) {
super.onCreate(instanceBundle);
Window window = getWindow();
window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
window.setFormat( PixelFormat.RGBA_8888 );
surfaceView = new SurfaceView(this);
setContentView(surfaceView);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.setFormat( PixelFormat.RGBA_8888 );
Display display = getWindowManager().getDefaultDisplay();
int width = display.getWidth();
int height = display.getHeight();
if(width > height) {
setOffscreenSurface(height, width);
} else {
setOffscreenSurface(width, height);
}
surfaceView.setFocusableInTouchMode(true);
surfaceView.requestFocus();
surfaceView.setOnKeyListener(this);
background = decodeSampledBitmapFromResource( getResources(), R.drawable.background );
}
public Bitmap decodeSampledBitmapFromResource( Resources res, int resId )
{
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res, resId, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options );
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
options.inDither = true;
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
return BitmapFactory.decodeResource(res, resId, options);
}
public int calculateInSampleSize( BitmapFactory.Options options )
{
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
int reqWidth = Math.round( width * vertDispRatio );
int reqHeight = Math.round( height * horiDispRatio );
if( height > reqHeight || width > reqWidth )
{
// Calculate ratios of height and width to requested height and width
final int heightRatio = Math.round( (float) height / (float) reqHeight );
final int widthRatio = Math.round( (float) width / (float) reqWidth );
// Choose the smallest ratio as inSampleSize value, this will guarantee
// a final image with both dimensions larger than or equal to the
// requested height and width.
inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
}
return inSampleSize;
}
#Override
public void onAttachedToWindow() {
super.onAttachedToWindow();
Window window = getWindow();
window.setFormat(PixelFormat.RGBA_8888);
}
public void setOffscreenSurface(int width, int height) {
if(offscreenSurface != null) offscreenSurface.recycle();
offscreenSurface = Bitmap.createBitmap(width, height, Config.ARGB_8888);
canvas = new Canvas(offscreenSurface);
}
Paint paint = new Paint();
public void drawBitmap(Bitmap bitmap, float x, float y)
{
if(canvas != null)
{
int pixelX = (int)( x * getFramebufferWidth() );
int pixelY = (int)( y * getFramebufferHeight() );
paint.setDither(true);
canvas.drawBitmap(bitmap, pixelX, pixelY, paint);
}
}
public void run() {
int frames = 0;
long startTime = System.nanoTime();
long lastTime = System.nanoTime();
while(true) {
if( state == State.Running )
{
if( !surfaceHolder.getSurface().isValid() )
continue;
Canvas canvas = surfaceHolder.lockCanvas();
long currTime = System.nanoTime();
float deltaTime = (currTime - lastTime) / 1000000000.0f;
if( deltaTime > 0.1f )
deltaTime = 0.1f;
clearFramebuffer( Color.BLACK );
drawBitmap( background, 0, 0 );
src.left = 0;
src.top = 0;
src.right = offscreenSurface.getWidth() - 1;
src.bottom = offscreenSurface.getHeight() - 1;
dst.left = 0;
dst.top = 0;
dst.right = surfaceView.getWidth();
dst.bottom = surfaceView.getHeight();
canvas.drawBitmap(offscreenSurface, src, dst, null);
surfaceHolder.unlockCanvasAndPost(canvas);
}
}
}
I dont see anywhere in your code where your trying to set anti aliasing. You can also do that with the paint you use in your canvas. that should help and if not maybe the device you are using just sucks? :P
Edit:
I swore that you could set anti-aliasing through bitmapfactory but I guess not. You can definitely do it from paint though. You can set it by using the paint.setAntiAlias(aa) method.
I have an image view and I want to set an image on it. The size of the image is 7,707,446 bytes. Whenever I try to set the layout, the app crashes and the error is out of memory error.can anyone suggest me how to solve it.The xml is:-
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<ScrollView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:scrollbars="none">
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#drawable/image" >
</RelativeLayout>
</ScrollView>
Bitmap picture=BitmapFactory.decodeFile("/sdcard...");
int width = picture.getWidth();
int height = picture.getWidth();
float aspectRatio = (float) width / (float) height;
int newWidth = 70;
int newHeight = (int) (70 / aspectRatio);
picture= Bitmap.createScaledBitmap(picture, newWidth, newHeight, true);
public static Bitmap decodeImage(String arrayList_image) {
URL aURL;
try {
aURL = new URL(arrayList_image);
URLConnection conn = aURL.openConnection();
conn.connect();
InputStream is = conn.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is);
bm = BitmapFactory.decodeStream(bis);
bis.close();
is.close();
return bm;
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
See Loading Large Bitmaps Effectively.
You could create a function to calculate a downscaling factor:
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) {
if (width > height) {
inSampleSize = Math.round((float)height / (float)reqHeight);
} else {
inSampleSize = Math.round((float)width / (float)reqWidth);
}
}
return inSampleSize;
}
And then use this to load a scaled Bitmap:
public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res, resId, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(res, resId, options);
}
Thus if you wanted to load a 100x100 pixel thumbnail into your ImageView, you'd just use:
mImageView.setImageBitmap(
decodeSampledBitmapFromResource(getResources(), R.id.myimage, 100, 100)
);
Hi i suggest u to try this and display your image according the Device.
Bitmap bmp = BitmapFactory.decodeResource(myContext.getResources(),drawableId);
int w = bmp.getWidth();
int h = bmp.getHeight();
System.out.println("OrgWidth : " + w);
System.out.println("orgHeight : " + h);
int targetWidth = (screenWidth * w)/iPadWidth;
int targetHeight = (screenHeight * h)/iPadHeight;
System.out.println("TargetWidth : " + targetWidth);
System.out.println("TargetHeight : " + targetHeight);
int[] arrWidthHeight = {targetWidth,targetHeight};
// This for Slove the out of Memory problem
int newWidth = 110;
int newHeight = 110;
float scaleWidth = ((float) newWidth) / w;
float scaleHeight = ((float) newHeight) / h;
Matrix bMatrix = new Matrix();
bMatrix.postScale(scaleWidth, scaleHeight);
Bitmap resizedBitmap = Bitmap.createBitmap(bmp, 0, 0, w, h , bMatrix, true);
First fetch the Image from resources and find new height and width of image according to device and after scale this image as purpose for solve the out of memory here.
This for find height and width according to device height and width..
WindowManager winManager = (WindowManager) myContext.getSystemService(Context.WINDOW_SERVICE);
screenWidth = winManager.getDefaultDisplay().getWidth();
screenHeight = winManager.getDefaultDisplay().getHeight();
System.out.println("Screen Width : " + screenWidth);
System.out.println("Screen Height : " + screenHeight);
and use bitmap to get image height and width witch like a ipathwidth and ipathHeight ok now
Happy
How to get thumbnails from sdcard with the given URI ??
I have tried using bitmapfactory but the performance is bad or OutOfMemoryError
I am going to put the thumbnails to the listview with a lot of data
should I use thumbnails or any suggestions?
if thumbnails are to be used then how to do it...?
Thanks in advance for the help
The following method can be used to get the thumbnail of image:
private Bitmap getBitmap(String path) {
Uri uri = getImageUri(path);
InputStream in = null;
try {
final int IMAGE_MAX_SIZE = 1200000; // 1.2MP
in = mContentResolver.openInputStream(uri);
// Decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeStream(in, null, o);
in.close();
int scale = 1;
while ((o.outWidth * o.outHeight) * (1 / Math.pow(scale, 2)) > IMAGE_MAX_SIZE) {
scale++;
}
Log.d(TAG, "scale = " + scale + ", orig-width: " + o.outWidth + ", orig-height: " + o.outHeight);
Bitmap b = null;
in = mContentResolver.openInputStream(uri);
if (scale > 1) {
scale--;
// scale to max possible inSampleSize that still yields an image
// larger than target
o = new BitmapFactory.Options();
o.inSampleSize = scale;
b = BitmapFactory.decodeStream(in, null, o);
// resize to desired dimensions
int height = b.getHeight();
int width = b.getWidth();
Log.d(TAG, "1th scale operation dimenions - width: " + width + ", height: " + height);
double y = Math.sqrt(IMAGE_MAX_SIZE
/ (((double) width) / height));
double x = (y / height) * width;
Bitmap scaledBitmap = Bitmap.createScaledBitmap(b, (int) x, (int) y, true);
b.recycle();
b = scaledBitmap;
System.gc();
} else {
b = BitmapFactory.decodeStream(in);
}
in.close();
Log.d(TAG, "bitmap size - width: " +b.getWidth() + ", height: " + b.getHeight());
return b;
} catch (IOException e) {
Log.e(TAG, e.getMessage(),e);
return null;
}
}
And always call bitmap.recycle() method after using bitmaps. It will clear the bitmap from memory. Also avoid memory leaks in your code. This will solve your OOME.
// Parameters
int w,h;
// First only decode image size
BitmapFactory.Options opt = new BitmapFactory.Options();
opt.inJustDecodeBounds = true;
Bitmap bmp = BitmapFactory.decodeFile(file, opt);
// Decode small enough image
int heightRatio = (int)opt.outHeight/h;
int widthRatio = (int)opt.outWidth/w;
if (heightRatio > 1 || widthRatio > 1)
{
if (heightRatio > widthRatio)
opt.inSampleSize = heightRatio;
else
opt.inSampleSize = widthRatio;
}
opt.inJustDecodeBounds = false;
bmp = BitmapFactory.decodeFile(file, opt);
Use ThumbnailUtils class to get the thumb of the image/video.
Try with this code, it fix the Out of memory error. Change the height and width as yours. Here intent_data2 is file path.
public Bitmap custom_SizedImage(String intent_data2) {
int targetHeight = 534, targetWidth = 534;
Options options = new Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(intent_data2, options);
double sampleSize = 0;
Boolean scaleByHeight = Math.abs(options.outHeight - targetHeight) >= Math
.abs(options.outWidth - targetWidth);
if (options.outHeight * options.outWidth * 2 >= 1638) {
sampleSize = scaleByHeight ? options.outHeight / targetHeight
: options.outWidth / targetWidth;
sampleSize = (int) Math.pow(2d,
Math.floor(Math.log(sampleSize) / Math.log(2d)));
}
options.inJustDecodeBounds = false;
options.inTempStorage = new byte[128];
while (true) {
try {
options.inSampleSize = (int) sampleSize;
mBitmap = BitmapFactory.decodeFile(intent_data2, options);
Display display = getWindowManager().getDefaultDisplay();
int width = display.getWidth();
int height = display.getHeight();
int screenDiff = height - width;
int screenRatio = screenDiff / 3;
float scaleFactor = mBitmap.getWidth() / width;
float y_Pos = scaleFactor * screenRatio;
Matrix matrix = new Matrix();
matrix.postScale(0.5f, 0.5f);
croppedBitmap = Bitmap.createBitmap(mBitmap, 0, (int) y_Pos,
mBitmap.getWidth(), mBitmap.getWidth(), matrix, true);
scaledBitmap = Bitmap.createBitmap(targetWidth, targetHeight,
Config.RGB_565);
float ratioX = targetWidth / (float) croppedBitmap.getWidth();
float ratioY = targetHeight / (float) croppedBitmap.getHeight();
float middleX = targetWidth / 2.0f;
float middleY = targetHeight / 2.0f;
Matrix scaleMatrix = new Matrix();
scaleMatrix.setScale(ratioX, ratioY, middleX, middleY);
Canvas canvas = new Canvas(scaledBitmap);
canvas.setMatrix(scaleMatrix);
canvas.drawBitmap(croppedBitmap,
middleX - croppedBitmap.getWidth() / 2, middleY
- croppedBitmap.getHeight() / 2, new Paint(
Paint.FILTER_BITMAP_FLAG));
//saveImage(scaledBitmap);
break;
} catch (Exception ex) {
try {
sampleSize = sampleSize * 2;
} catch (Exception ex1) {
}
}
}
return scaledBitmap;
}