OutOfMemory issue loading several pictures - java

I have nine pictures that I want to load at the start of an activity, and I'm getting problems of OutOfMemory exceptions. At first I loaded them directly in the xml setting its src. So after getting java.lang.OutOfMemory I realized that maybe I needed to load the pictures more efficiently and I created this loop to be executed at the begining of the activity:
for(int i=0;i<9;i++){
String background = "background"+(i+1);
int idDrawable = getResources().getIdentifier(background, "drawable", getPackageName());
int idPicture = getResources().getIdentifier(background, "id", getPackageName());
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(getResources(), idDrawable, options);
options.inJustDecodeBounds = false;
ImageView image = (ImageView) findViewById(idPicture);
image.setImageBitmap(BitmapFactory.decodeResource(getResources(), idDrawable, options));
}
But I still have the same OutOfMemory issue, any ideas on what am I doing wrong?

Use following code.
Change this code
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(getResources(), idDrawable, options);
to
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
options.inSampleSize = 4;
BitmapFactory.decodeResource(getResources(), idDrawable, options);
and remove this line
options.inJustDecodeBounds = false;

Little bit of googeling and searching by yourself would lead you to that Android Developers HowTo
http://developer.android.com/training/displaying-bitmaps/load-bitmap.html

Related

How to load sampled image from Uri?

I need to load image with reduced resolution. How can I do this?
I tired next code:
public Bitmap decodeSampledBitmapFromUri(#NonNull Uri Uri, int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
try {
InputStream is = getContentResolver().openInputStream(Uri);
BitmapFactory.decodeStream(is, null, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight); // I can read width and height from options
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeStream(is, null, options);
} catch (Exception ignored)
{
}
return null;
}
And I even can see the width and height of loaded image. But BitmapFactory.decodeStream returns null when I turned inJustDecodeBounds to false. Whats wrong?
The image selected by user from gallery. All permissions granted.
Your InputStream was closed by the first decodeStream(). Open a fresh InputStream for use with the second decodeStream().

Large scrolled image android studio

I have a problem with loading a large image.
I have to make a map/background with a size of 3556 x 2000 pixels.
I try this:
https://developer.android.com/topic/performance/graphics/load-bitmap.html
But it looks like it does not work properly for me. (Exception: out of memory)
This is my background:
scr.hu/8p0mdz - Screenshooter
I marked with black square the area that is visible on the phone for user. Of course, user can zoom in or out the visible area.
I can't use libgdx. I want to use only android libraries. I have no idea how i should start my work. I don't ask for a code(i will gladly accept the code), but i want to find out what i should start with.
In this background, will be drawn other images(buildings). When game will be start, resources need to be loaded into memory. In libgdx i can use AssetManager. In my case when i use
https://developer.android.com/reference/android/content/res/AssetManager.html
it should be enough?
I hope you understand my problem.
This is not a trivial problem, so I think there is no easy solution. But there're few things which could help:
You can control amount of allocated memory for your bitmap:
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
options.inPreferredConfig = Bitmap.Config.RGB_565;
//RGB_565 color format requires way less memory than ARGB_8888
There is BitmapRegionDecoder class which loads just a part of bitmap.
BitmapRegionDecoder decoder = BitmapRegionDecoder.newInstance("path", false);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.RGB_565;
Bitmap partOfBitmap = decoder.decodeRegion(new Rect(0, 0, 100, 100), options);
Using BitmapRegionDecoder you can develop your custom View which handles user scroll events and loads into memory only visible image regions and destroys not visible.
I try to solve this as above:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_planet);
int WIDTH = 0;
int HEIGHT = 0;
backgroundJungle = (ImageView)findViewById(R.id.backgroundJungle);
InputStream is = null;
try {
Drawable drawable = getResources().getDrawable(R.drawable.junglemap);
BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
Bitmap bitmap = bitmapDrawable.getBitmap();
WIDTH = bitmap.getWidth();
HEIGHT = bitmap.getHeight();
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
is = new ByteArrayInputStream(stream.toByteArray());
} catch (Exception ex) {
ManagerException(ex);
}
try {
if (is != null) {
BitmapRegionDecoder decoder = BitmapRegionDecoder.newInstance(is, false);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.RGB_565;
Bitmap partOfBitmap = decoder.decodeRegion(new Rect(0,0,2500,2500),options);
backgroundJungle.setImageBitmap(partOfBitmap);
Toast.makeText(getApplicationContext(), WIDTH + " " + HEIGHT, Toast.LENGTH_SHORT).show();
}
} catch (IOException ex) {
ManagerException(ex);
}
}
But bitmap has size 9335 x 5250, but my image has 3556 x 2000.

Creating a mutable Bitmap from ByteArray... import not working?

I'm trying to do something like this:
Bitmap bmp;
BitmapFactory.Options.inMutable = true;
bmp = BitmapFactory.decodeByteArray(data, 0, data.length);
But I'm getting an error under BitmapFactory.Options.inMutable = true;
Cannot make a static reference to the non-static field BitmapFactory.Options.inMutable
I'm sure the solution is probably something simple, but I'm unsure of why it's not working.
You need to create an instance of the BitmapFactory.Options class. Something like:
BitmapFactory.Options options = new BitmapFactory.Options();
options.inMutable = true;
BitmapFactory.decodeByteArray(data, 0, data.lentgh, options);
inMutable is not static field. Try this:
BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inMutable = true;
BitmapFactory.decodeByteArray(data, 0, data.length(), opts);
or even better this:
Bitmap bmp;
bmp = BitmapFactory.decodeByteArray(data, 0, data.length);
Bitmap mutableBitmap = bmp.copy(Bitmap.Config.ARGB_8888, true);

Read an Image/file from External storage Android

I'm trying to load an image from external storage. I set the permissions, I tried different ways, but none of them works.
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
Bitmap bitmap = BitmapFactory.decodeFile(file.toString());
tv.setImageBitmap(bitmap);
and this one,
FileInputStream streamIn = new FileInputStream(file);
Bitmap bitmap = BitmapFactory.decodeStream(streamIn);
tv.setImageBitmap(bitmap);
streamIn.close();
If i have file abc.jpg on the sdcard then:
String photoPath = Environment.getExternalStorageDirectory() + "/abc.jpg";
and to get bitmap.
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
Bitmap bitmap = BitmapFactory.decodeFile(photoPath, options);
or
Bitmap bitmap1 = BitmapFactory.decodeFile(photoPath);
to avoide out of memory error I suggest you use the below code...
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 8;
final Bitmap b = BitmapFactory.decodeFile(photoPath, options);
To avoid above issue you can use Picasso (A powerful image downloading and caching library for Android)
Documentation
How To?
Picasso.with(context).load("file:///android_asset/DvpvklR.png").into(imageView2);
Picasso.with(context).load(new File(...)).into(imageView3);
File sdCard = Environment.getExternalStorageDirectory();
File directory = new File (sdCard.getAbsolutePath() + "/Pictures");
File file = new File(directory, "image_name.jpg"); //or any other format supported
FileInputStream streamIn = new FileInputStream(file);
Bitmap bitmap = BitmapFactory.decodeStream(streamIn); //This gets the image
streamIn.close();
Get the path of the image from your folder as below. And then decode the file as a bitmap.
File file= new File(android.os.Environment.getExternalStorageDirectory(),"Your folder");
Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath())
If you have a file path, just use BitmapFactory directly, but tell it to use a format that preserves alpha:
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
Bitmap bitmap = BitmapFactory.decodeFile(photoPath, options);
selected_photo.setImageBitmap(bitmap);
There is a function called
createFromPath(String)
in the Drawable class.
So the statement
String path="/storage/..<just type in the path>";
Drawable.createFromPath(path);
will return a drawable object

Display jpg from sdcard android

I cant get this to work anymore
Here is my code:
ImageView jpgView = (ImageView)findViewById(R.id.ImageView01);
String myJpgPath = "/sdcard/pic.jpg";
jpgView.setVisibility(View.VISIBLE);
//jpgView.setScaleType(ImageView.ScaleType.FIT_CENTER);
jpgView.setAdjustViewBounds(true);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 2;
Bitmap bm = BitmapFactory.decodeFile(myJpgPath, options);
jpgView.setImageBitmap(bm);
Can anyone help?
You can just use bitmapdrawable, e.g.
ImageView jpgView = (ImageView)findViewById(R.id.ImageView01);
String myJpgPath = "/sdcard/pic.jpg";
BitmapDrawable d = new BitmapDrawable(getResources(), myJpgPath);
jpgView.setImageDrawable(d);
The image won't be shown if you open the emulator directly from the eclipse, by clicking run. You'll be able to access the SD card if you start the emulator using the command line, then click your app on the emulator.

Categories