I need to load large image which has 2450 x 2450 pixels dimensions.
Bitmap bitmap = ImageLoader.getInstance().loadImageSync(url,
ImageConfig.getImageOptions());
The problem is, on low end device (phone with less than 1 GB RAM), got out of memory exception.
This is my DisplayImageOptions
public static DisplayImageOptions getImageOptions() {
DisplayImageOptions.Builder options = new DisplayImageOptions.Builder();
options.delayBeforeLoading(10)
//The reason I'm using ARGB_8888 because I need to load bitmap without losing it's quality
.bitmapConfig(Bitmap.Config.ARGB_8888)
.imageScaleType(ImageScaleType.NONE)
//I'm not using disk or memory cache
.cacheOnDisk(false)
.cacheInMemory(false);
return options.build();
}
I tried to add target size based on device resolution, but it's not working, loaded bitmap still has 2450 x 2450 pixels dimensions.
int height = orientation == Configuration.ORIENTATION_PORTRAIT ?
displaymetrics.heightPixels : displaymetrics.widthPixels;
Bitmap bitmap = ImageLoader.getInstance().loadImageSync(imageUri,
new ImageSize(height, height), ImageConfig.getImageOptions());
I tried to change imageScaleType to ImageScaleType.EXACTLY, loaded bitmap resized to 1225 x 1225 pixels, on all device, I need to get original dimensions for high end device, and resized dimensions for low end device.
The main problem is target size is not working
Any idea how should I load the image, especially for low end device?
try to use some library like Picasso.
It is really easy to use and it manage resize for you.
If you want to do this by yourself, I suggest to do it with NDK in c++, because there you have a better memory management and can help you with low end devices.
Simply change imageScaleType to ImageScaleType.EXACTLY_STRETCHED will fix the problem. Target size will works as supposed to be. Stangely UIL will try to maintain aspect ratio based on largest value between target width and target height.
DisplayImageOptions
public static DisplayImageOptions getImageOptions() {
DisplayImageOptions.Builder options = new DisplayImageOptions.Builder();
options.delayBeforeLoading(10)
//The reason I'm using ARGB_8888 because I need to load bitmap without losing it's quality
.bitmapConfig(Bitmap.Config.ARGB_8888)
.imageScaleType(ImageScaleType.EXACTLY_STRETCHED)
//I'm not using disk or memory cache
.cacheOnDisk(false)
.cacheInMemory(false);
return options.build();
}
Set target size based on device dimensions when loading bitmap
//In this case the device I'm using for testing has 2392 pixels height
int height = orientation == Configuration.ORIENTATION_PORTRAIT ?
displaymetrics.heightPixels : displaymetrics.widthPixels;
//In this case the device I'm using for testing has 1440 pixels width
int width = orientation == Configuration.ORIENTATION_PORTRAIT ?
displaymetrics.widthPixels : displaymetrics.heightPixels;
//Loaded bitmap will has 2392 x 2392 pixels dimensions
Bitmap bitmap = ImageLoader.getInstance().loadImageSync(imageUri,
new ImageSize(width, height), ImageConfig.getImageOptions());
Related
I'm doing a gallery image. I get path of image in device and parse to URI.
Then I use Picasso Android Lib to load image into Imageview in Gridview. It's work fine until have a large image. Picasso can not load large image. I got error Out Of Memory. Is there any suggestion to load large image into ImageView? And have any lib to load image into ImageView can instead Picasso?
I found ImageLoader lib for my problem. It works fine. I tested on my project, and then I saw that ImageLoader looks better than Picasso.
Learn how to use common techniques to process and load Bitmap objects in a way that keeps your user interface (UI) components responsive and avoids exceeding your application memory limit. If you're not careful, bitmaps can quickly consume your available memory budget leading to an application crash due to the dreaded exception:
java.lang.OutofMemoryError: bitmap size exceeds VM budget.
There are a number of reasons why loading bitmaps in your Android application is tricky:
Mobile devices typically have constrained system resources. Android devices can have as little as 16MB of memory available to a single application. The Android Compatibility Definition Document (CDD), Section 3.7. Virtual Machine Compatibility gives the required minimum application memory for various screen sizes and densities. Applications should be optimized to perform under this minimum memory limit. However, keep in mind many devices are configured with higher limits.
Bitmaps take up a lot of memory, especially for rich images like photographs. For example, the camera on the Galaxy Nexus takes photos up to 2592x1936 pixels (5 megapixels). If the bitmap configuration used is ARGB_8888 (the default from the Android 2.3 onward) then loading this image into memory takes about 19MB of memory (2592*1936*4 bytes), immediately exhausting the per-app limit on some devices.
Android app UI’s frequently require several bitmaps to be loaded at once. Components such as ListView, GridView and ViewPager commonly include multiple bitmaps on-screen at once with many more potentially off-screen ready to show at the flick of a finger.
Read More Regarding this issue
Here is an example I once used, but it is not perfect! (Sorry)
You can reduce the bitmap size:
public Bitmap resizeBitmap(Bitmap bitmap) {
if (bitmap.getHeight() > 4096 || bitmap.getWidth() > 4096) {
int width = (int) (bitmap.getWidth() * 0.9);
int height = (int) (bitmap.getHeight() * 0.9);
Bitmap resizedBitmap = Bitmap.createScaledBitmap(bitmap, width, height, false);
resizeBitmap(resizedBitmap);
returnresizedBitmap;
} else {
return bitmap;
}
}
If I should do it again: (not tested)
public Bitmap resizeBitmap(Bitmap bitmap) {
int originalWidth = bitmap.getWidth();
int originalHeight = bitmap.getHeight();
if (originalWidth > 4096 || originalHeight > 4096) {
int height;
int width;
if(originalHeight > originalWidth) {
height = 4096;
width = originalWidth / (originalHeight / 4096);
} else {
width = 4096;
height = originalHeight / (originalWidth / 4096);
}
Bitmap resizedBitmap = Bitmap.createScaledBitmap(bitmap, width, height, false);
return resizedBitmap;
} else {
return bitmap;
}
}
You can custom recent-images library for your purpose. It's very simple and easy to use library. It creates a thumbnail of image for showing in gridview and then in click opens the original.
I need to create a bitmap in android and draw some stuff on it using a canvas which will eventually be printed using a photo printer. Basically I'm trying to create a jpg of actual 5x7 size (5 inches X 7 inches). So if the bitmap is emailed or copied to a computer, it correctly fit into a 5X7 photo printing paper.
When specifying the height and width in the createbitmap method, what values do I need to specify to make the actual size of the bitmap 5x7. Is this dependent on the screen density etc., of the device?
Try this method:
public void setViewInInches(float width, float height, View v) {
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
int widthInches = Math.round(width * metrics.xdpi);
int heightInches = Math.round(height * metrics.ydpi);
v.setLayoutParams(new LinearLayout.LayoutParams(widthInches, heightInches));
v.requestLayout();
}
Pass in the width and height, followed by the view you want to set it to and it should work. Sample call to set image view to 5x7:
setViewInInches(5f, 7f, imageView);
How large the final image will be printed on paper is up to the printer, however you can give hints how large it should be with Bitmap.setDensity(). Note that image density is simply a numeric metadata embedded in the image file and it is up to the output device (i.e. the printer) to interpret or obey the hint.
The relationship between images size in pixel and the density you need to set to achieve a certain size is a fairly simple math, if you have an image whose pixel size is 360x504 pixels and you want to print it so the physical size of 5x7 inch, you'll need to set the density to be: 360px / 5 inch = 72ppi.
int IMAGE_WIDTH_IN_PIXEL = 360;
int IMAGE_HEIGHT_IN_PIXEL = 504;
float TARGET_WIDTH_IN_INCH = 5;
float TARGET_HEIGHT_IN_INCH = 7;
Bitmap bitmap = Bitmap.createBitmap(IMAGE_WIDTH_IN_PIXEL, IMAGE_HEIGHT_IN_PIXEL, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
... draw something ...
// you need make sure the Bitmap had the same aspect ratio as the target printing size
assert IMAGE_WIDTH_IN_PIXEL / TARGET_WIDTH_IN_INCH == IMAGE_HEIGHT_IN_PIXEL / TARGET_HEIGHT_IN_INCH;
bitmap.setDensity(IMAGE_WIDTH_IN_PIXEL / TARGET_WIDTH_IN_INCH);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outfile);
Note that how large the image is printed has nothing to do with the device's screen density, which determines how large the image will be viewed on screen.
If you have a predetermined printing density though, for example, most regular printers can print at least at 300ppi, as it's the lowest ppi which would not appear with pixelation at typical reading distance. If you have a preset ppi, what you need to control is then the image pixel size when you render the image to the Bitmap. The relationship is again pretty simple, to print an image at 5in wide at 300ppi you'll need 300ppi * 5 in = 1500 pixel wide image.
int TARGET_DENSITY = 300;
float PHYSICAL_WIDTH_IN_INCH = 5;
float PHYSICAL_HEIGHT_IN_INCH = 7;
Bitmap bitmap = Bitmap.createBitmap(PHYSICAL_WIDTH_IN_INCH * TARGET_DENSITY, PHYSICAL_HEIGHT_IN_INCH * TARGET_DENSITY, Bitmap.Config.ARGB_8888);
bitmap.setDensity(TARGET_DENSITY);
Canvas canvas = new Canvas(bitmap);
... draw something ...
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outfile);
Another possibility if the printer service supports it is to submit the intended physical size separately along with the printing request. The printer then will ignore the embedded density hint and calculate the image density required to print at that size.
I've researched at least 10 similar topics on SO, however, none have reached a definitive answer for me allowing me to avoid the Out of Memory error Bitmaps are known for.
Taking into consideration the advice from these previous questions, I constructed the following method setBipmapFromPath to produce an optimally sized (both in dimensions and kilobytes) wallpaper image from a file path. This method works fine on a large RAM device like my G2, however, it crashes in an emulator with 1.5GB of RAM using a 256kb picture.
I welcome any criticism that will help me prevent the Out of Memory error. My hope is to also ensure the image can still act as a proper background image, as in, fill the screen of the device reasonably without insane stretch marks.
My methods:
public void recycleWallpaperBitmap() {
if (mBitmap != null) {
mBitmap.recycle();
mBitmap = null;
}
}
private void setBitmapFromPath() {
// Recycle the bitmap just in case.
recycleWallpaperBitmap();
String path = mProfileManager.getWallpaperPath();
if (path != null) {
WindowManager wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
int displayWidth = display.getWidth(); // deprecated
int displayHeight = display.getHeight(); // deprecated
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = false;
mBitmap = ThumbnailUtils.extractThumbnail(BitmapFactory.decodeFile(path, options),
displayWidth, displayHeight);
}
}
This method works fine on a large RAM device like my G2, however, it crashes in an emulator with 1.5GB of RAM using a 256kb picture.
It will fail on the G2 as well, depending on where and when you call this method. Your "256kb" picture will take up several MB of heap space, and there is no assurance that you have that amount of heap space available in a single contiguous block.
Also, I would not use a class and method designed for creating thumbnails will be suitable for creating wallpaper-sized images.
I welcome any criticism that will help me prevent the Out of Memory error.
Use inSampleSize on your BitmapFactory.Options to downsample the image to closer to the right size while it is being read in.
Then, dump your use of ThumbnailUtils and allow your ImageView to scale it the rest of the way, to avoid making yet another copy of the image.
Bonus points for using inBitmap instead of junking and re-allocating your Bitmap every time, since the screen size is not changing, and therefore your wallpaper dimensions are not changing.
These techniques and more are covered in the developer documentation.
I have published my app in play store. Now In Crashes and ANRs I am getting following errors on 2 devices (Galaxy Note3 and Galaxy Note II). I dont know how to solve these errors and what type of error is this? So please help me to fix these errors. On other devices I am not getting any report there.
Errors-
java.lang.OutOfMemoryError
at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:677)
at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:507)
at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:872)
at android.content.res.Resources.loadDrawable(Resources.java:3022)
at android.content.res.Resources.getDrawable(Resources.java:1586)
at android.view.View.setBackgroundResource(View.java:16120)
at com.info.laughingbuddha.Buddha4.onCreateView(Buddha4.java:21)
at android.support.v4.app.Fragment.performCreateView(Fragment.java:1500)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:927)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1104)
at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:682)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1467)
at android.support.v4.app.FragmentManagerImpl.executePendingTransactions(FragmentManager.java:472)
at android.support.v4.app.FragmentStatePagerAdapter.finishUpdate(FragmentStatePagerAdapter.java:163)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1068)
at android.support.v4.view.ViewPager.populate(ViewPager.java:914)
at android.support.v4.view.ViewPager$3.run(ViewPager.java:244)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:803)
at android.view.Choreographer.doCallbacks(Choreographer.java:603)
at android.view.Choreographer.doFrame(Choreographer.java:572)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:789)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:157)
at android.app.ActivityThread.main(ActivityThread.java:5293)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1259)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1075)
at dalvik.system.NativeStart.main(Native Method)
Buddha4.java-
package com.info.laughingbuddha;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.text.method.ScrollingMovementMethod;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
public class Buddha4 extends Fragment{
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.buddha, container, false);
TextViewEx t = (TextViewEx) rootView.findViewById(R.id.textView2);
t.setText("The Standing Happy Buddha brings riches and happiness.",true);
t.setMovementMethod(new ScrollingMovementMethod());
ImageView iv = (ImageView) rootView.findViewById(R.id.image1);
iv.setBackgroundResource(R.drawable.buddha4);
return rootView;
}
}
I dont know what code I need to post so If anyone require any code related to this please comment. Thanks.
Try to create scaled bitmap using following line of the code:
Bitmap scaledBitmap = Bitmap.createScaledBitmap(myBitmap, width,
height, true);
Check the following links:
android - out of memory exception when creating bitmap
Android out of memory exception with bitmaps
Can I catch out of memory exception in Android in Bitmap allocation for decoding a picture file?
If you have high resolution image , you should scale them down to avoid different devices to load the image without facing a memory problem.
In your case, some phones may not exhibit the same behavior on the first run, but eventually, without handling an optimized image loading solution, app will crash.
Check more on the "memory problem":
Topic under Load a Scaled Down Version into Memory.
http://developer.android.com/training/displaying-bitmaps/load-bitmap.html
Out of memory error on Android
On how to avoid them:
How to avoid an out of memory error while using bitmaps in Android
For an overview:
http://blogs.innovationm.com/android-out-of-memory-error-causes-solution-and-best-practices/
http://android-developers.blogspot.de/2009/01/avoiding-memory-leaks.html
Before setting a drawable as the background for your imageview, i.e.:
iv.setBackgroundResource(R.drawable.buddha4);
as #rup35h suggested in the answer, get a scaled bitmap or try other options like inSampleSize, do check how your solution affects the quality of your image too.
Sometimes when we use so many images & backgrounds in applications, it takes lot of space on android RAM.
This leads to force close your application by “Out of memory Bound Exception”.
It seems from your crash logs that you have drawable which is quite large, so to avoid the OutOfMemory you have keep drawables that would not take much memory. You can scale down the drawable either as some guys suggested in the answers.
If you don't want go through that and you have not much large size drawable then you can opt to increase your application heap size to large that would increase the heap memory.
How to increase heap size
You can use android:largeHeap="true" in application tag of Android manifest(Reference here) to request a larger heap size, but this will not work on any pre
Honeycomb devices.
On pre 2.3 devices, you can use the VMRuntime class, but this will not work on Gingerbread and above See below how to do it.
VMRuntime.getRuntime().setMinimumHeapSize(BIGGER_SIZE);
Before Setting HeapSize make sure that you have entered the appropriate size which will not affect other application or OS functionality.
Before settings just check how much size your app takes & then set the size just to fulfill your job. Dont use so much of memory otherwise other apps might affect.
Update
Note : It is always best practice to free the allocated memory of the bitmaps when these wont longer required, you can this bitmap.recycle()
One problem I've had a couple of times is having a lot of MDPI drawable resources but no HDPI / XHDPI versions. When loading these on an HDPI or XHDPI device, Android will scale them up by loading the original, then making a a scaled up copy in memory, meaning you've got two copies in memory at once, the original and a scaled up version. If the drawable is being stretched by the renderer (e.g. If it's a background for a view), then there's no need for Android to scale it up when it's loaded, as the renderer does that anyway. So if you only have one MDPI copy of the image and don't want Android to scale it up, you should put it in the drawable-nodpi folder instead of the drawable or drawable-mdpi folders.
EDIT:
You can use the render time scaling available on an image view by setting the android:scaleType attribute. E.g. you could set the image view's width and height to match_parent, then set the scale type to centerCrop or centerInside to have the image scale up when it's drawn while maintaining its aspect ratio. centerCrop will totally fill the image view but potentially cut off some of the image, whereas centerInside ensures that the whole image is visible, but may leave some blank space. The scaling will be done at render time, so won't use any extra memory.
It can all be done in the layout XML like so:
android:layout_height="match_parent"
android:layout_width="match_parent"
android:scaleType="centerCrop"
To have the image displayed fully inside the image view without cropping, change the last line to:
android:scaleType="centerInside"
Finally, if you don't want to maintain the aspect ratio, you can use the following scale type:
android:scaleType="fitXY"
You have to scale down your image resource when loading it.
If you are loading the image, using a Bitmap variable, you can use the inSample option, using BitmapFactory.Options. Don't use the Bitmap.createScaledBitmap as it will create another bitmap besides the original one!
Try the following code to load the bitmap:
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true; //This will just get the size of your image
BitmapFactory.decodeFile(pictureFile.getAbsolutePath(), options);
//Get the downscale ratio
options.inJustDecodeBounds = false;
options.inSampleSize = calculateInSampleSize(options, widthOfTheImageView, heightOfTheImageView);
//Decode the bitmap using the downsampled image
Bitmap finalBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.image_name options);
//Finally, set the bitmap
imageView.setImageBitmap(finalBitmap);
Where widthOfTheImageView and heightOfTheImageView represent the size of your ImageView.
The calculateInSampleSize method (I got it from the Android developers tutorial):
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;
}
Do not load Bitmap directly if you are not sure about the size of the image. Sample it when the size is too large. At most time, the length of an image loaded should not exceed the length of your phone screen. Use code like this to sample image.
public static Bitmap loadImage(Context cx, Uri uri, int maxLength) {
InputStream is = cx.getContentResolver().openInputStream(uri);
Options opts = new Options();
opts.inJustDecodeBounds = true;
BitmapFactory.decodeStream(is, null, opts);
int length = Math.max(opts.outWidth, opts.outHeight);
int n = 1;
while (length > maxLength) {
maxLength /= 2;
n ++;
}
is = cx.getContentResolver().openInputStream(uri);
opts.inJustDecodeBounds = false;
opts.inPurgeable = true;
opts.inDither = true;
opts.inPurgeable = true;
opts.inSampleSize = sample;
Bitmap bm = BitmapFactory.decodeStream(is, null, opts);
return bm;
}
Remove all the views when you exit from an activity. Make it as null in OnDestroy().
if you are using Bitmaps
use
bitmap.recycle();
when you used it.
you may use
android:largeHeap="true"
in you manifest.xml to increase the heap size.
Thanks to Schermvlieger for asking this question on anddev.org,
I'm just copying his question to SO as nobody replied on the other site and I'm also facing the same problem.
I was wondering what would be the optimal use of BitmapFactory.Options.inSampleSize with regards to speed of displaying the image.
The documentation mentions using values that are a power of 2, so I am working with 2, 4, 8, 16 etc.
The things I am wondering about are:
Should I resample down to the smallest size that is still larger than the screen resolution, or should I sample down to the size just enough to avoid an OutOfMemoryError?
How would one calculate the maximum size of an image that could still be displayed without running out of memory? Does the color-depth of the image play a role as well, and the depth of the display?
Is it efficient to display images via two mechanisms (BitmapFactory for large files, setImageURI() for smaller ones) I am using an ImageSwitcher by the way.
Would it help creating the Bitmap, BitmapFactory.Options and inTempStorage in the beginning of the application or creating them only on the fly, when needed?
You should always try to load and pre-scale images so that they are as close as possible to their final displayed size. Scaling images at drawing time is extremely expensive and should be avoided at all cost.
Considering the memory cost of an image, yes, the color-deptch plays a very important role. Images in ALPHA_8 format use 1 byte per pixel, images in RGB_565 or ARGB_4444 use 2 bytes per pixel and images in ARGB_8888 use 4 bytes per pixel. The depth of the display does not matter at all. You should always try to use ARGB_8888 to get the best possible quality, but 565 can be good enough if your image is opaque.
You've asked good questions , but it all depends on your needs and how much memory you use.
I recommend checking out this link for many tips regarding bitmaps: http://developer.android.com/training/displaying-bitmaps/index.html .
In short , you should consider caching , downsampling , and using a good-enough bitmap format whenever you can.
Here's my answers to your questions:
Why not both? if you think there might be OOM , try to recycle old,unused bitmaps and then check again .
you can calculate the (estimated) size of the bitmap :
width*height*bytesPerPixel
where bytesPerPixel is usually 4 or 2 (depending on the bitmap format) .
Never used setImageURI , so I can't help you with that. I suggest downloading images in a background thread (using asyncTask is one way to do so) and showing them when it's ready.
If there are only a few that you know that won't take a lot of the memory , i guess it's ok. I still think caching could be better.
Here you can call the user defined method shrinkmehtod that actually send the string file path and the height and width to be reduce image to method.
Bitmap bit=shrinkmethod(arrpath1[position], 100, 100);
//iv.setImageURI(Uri.parse(arrpath1[position]));
iv.setImageBitmap(bit);
This is user defined method to reduce the size of image programmatically.
Bitmap shrinkmethod(String file,int width,int height){
BitmapFactory.Options bitopt=new BitmapFactory.Options();
bitopt.inJustDecodeBounds=true;
Bitmap bit=BitmapFactory.decodeFile(file, bitopt);
int h=(int) Math.ceil(bitopt.outHeight/(float)height);
int w=(int) Math.ceil(bitopt.outWidth/(float)width);
if(h>1 || w>1){
if(h>w){
bitopt.inSampleSize=h;
}else{
bitopt.inSampleSize=w;
}
}
bitopt.inJustDecodeBounds=false;
bit=BitmapFactory.decodeFile(file, bitopt);
return bit;
}
I hope this will help you to reduce size.
Hi try out calculating the inSampleSize using this logic
private fun calculateInSampleSize(options: BitmapFactory.Options, reqWidth: Int, reqHeight: Int): Int {
val (height: Int, width: Int) = options.run { outHeight to outWidth }
var inSampleSize = 1
if (height > reqHeight || width > reqWidth) {
val halfHeight: Int = height / 2
val halfWidth: Int = 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
}