2

I am still pretty new to programming, and I want to import images into my app and show them there. The Problem is, whenever I am adding photos into my app, the app crashes shortly after due to an outOfMemory Error in Java. I need to compress the Image before adding it in, but I absoloutly don't know how, can anyone help me?

My Code:

MainActivity:

import android.content.ClipData;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.net.Uri;
import android.provider.MediaStore;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {

    private Button btn;
    int PICK_IMAGE_MULTIPLE = 1;
    String imageEncoded;
    List<String> imagesEncodedList;
    private GridView gvGallery;
    private GalleryAdapter galleryAdapter;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    btn = findViewById(R.id.btn);
    gvGallery = (GridView)findViewById(R.id.gv);

    btn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent intent = new Intent();
            intent.setType("image/*");
            intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
            intent.setAction(Intent.ACTION_GET_CONTENT);
            startActivityForResult(Intent.createChooser(intent,"Bild(er) wählen"), PICK_IMAGE_MULTIPLE);
        }
    });

}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    if (id == R.id.action_camera) {

        Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
            startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
        }

        return true;
    }

    return super.onOptionsItemSelected(item);
}

static final int REQUEST_IMAGE_CAPTURE = 1;

static final int PICK_IMAGE = 1;

//private void dispatchTakePictureIntent() {
//    Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
//    if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
//        startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
//    }
//}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    try {
        // When an Image is picked
        if (requestCode == PICK_IMAGE_MULTIPLE && resultCode == RESULT_OK
                && null != data) {
            // Get the Image from data

            String[] filePathColumn = { MediaStore.Images.Media.DATA };
            imagesEncodedList = new ArrayList<String>();
            if(data.getData()!=null){

                Uri mImageUri=data.getData();

                // Get the cursor
                Cursor cursor = getContentResolver().query(mImageUri,
                        filePathColumn, null, null, null);
                // Move to first row
                cursor.moveToFirst();

                int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
                imageEncoded  = cursor.getString(columnIndex);
                cursor.close();

                ArrayList<Uri> mArrayUri = new ArrayList<Uri>();
                mArrayUri.add(mImageUri);
                galleryAdapter = new GalleryAdapter(getApplicationContext(),mArrayUri);
                gvGallery.setAdapter(galleryAdapter);
                gvGallery.setVerticalSpacing(gvGallery.getHorizontalSpacing());
                ViewGroup.MarginLayoutParams mlp = (ViewGroup.MarginLayoutParams) gvGallery
                        .getLayoutParams();
                mlp.setMargins(0, gvGallery.getHorizontalSpacing(), 0, 0);

            } else {
                if (data.getClipData() != null) {
                    ClipData mClipData = data.getClipData();
                    ArrayList<Uri> mArrayUri = new ArrayList<Uri>();
                    for (int i = 0; i < mClipData.getItemCount(); i++) {

                        ClipData.Item item = mClipData.getItemAt(i);
                        Uri uri = item.getUri();
                        mArrayUri.add(uri);
                        // Get the cursor
                        Cursor cursor = getContentResolver().query(uri, filePathColumn, null, null, null);
                        // Move to first row
                        cursor.moveToFirst();

                        int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
                        imageEncoded  = cursor.getString(columnIndex);
                        imagesEncodedList.add(imageEncoded);
                        cursor.close();

                        galleryAdapter = new GalleryAdapter(getApplicationContext(),mArrayUri);
                        gvGallery.setAdapter(galleryAdapter);
                        gvGallery.setVerticalSpacing(gvGallery.getHorizontalSpacing());
                        ViewGroup.MarginLayoutParams mlp = (ViewGroup.MarginLayoutParams) gvGallery
                                .getLayoutParams();
                        mlp.setMargins(0, gvGallery.getHorizontalSpacing(), 0, 0);

                    }
                    Log.v("LOG_TAG", "Selected Images" + mArrayUri.size());
                }
            }
        } else {
            Toast.makeText(this, "Keine Bilder ausgewählt!",
                    Toast.LENGTH_LONG).show();
        }
    } catch (Exception e) {
        Toast.makeText(this, "Fehler", Toast.LENGTH_LONG)
                .show();
    }

    //if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
    //    Bundle extras = data.getExtras();
    //    Bitmap imageBitmap = (Bitmap) extras.get("data");
    //    ImageView mImageView = new ImageView(this);
    //    mImageView.setImageBitmap(imageBitmap);
    //}

    super.onActivityResult(requestCode, resultCode, data);

}
}

GalleryAdapter:

import android.content.Context;
import android.net.Uri;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;

import java.util.ArrayList;

public class GalleryAdapter extends BaseAdapter {

private Context ctx;
private int pos;
private LayoutInflater inflater;
private ImageView ivGallery;
ArrayList<Uri> mArrayUri;
public GalleryAdapter(Context ctx, ArrayList<Uri> mArrayUri) {

    this.ctx = ctx;
    this.mArrayUri = mArrayUri;
}

@Override
public int getCount() {
    return mArrayUri.size();
}

@Override
public Object getItem(int position) {
    return mArrayUri.get(position);
}

@Override
public long getItemId(int position) {
    return 0;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {

    pos = position;
    inflater = (LayoutInflater) ctx
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

    View itemView = inflater.inflate(R.layout.gv_item, parent, false);

    ivGallery = (ImageView) itemView.findViewById(R.id.ivGallery);

    ivGallery.setImageURI(mArrayUri.get(position));

    return itemView;
}


}

If you need further Information, feel free to ask! And thanks for helping me out!

Macario
  • 21
  • 1
  • 2

2 Answers2

2

Problem: Issue with you application is that the android system is unable to properly load the relatively large bitmap on the screen and while trying to do so it exceeds the memory limit that was assigned to this loading process.

Solution:

For quick solution: How to resize Image in Android?

For detailed understanding:

Note: There are several libraries that follow best practices for loading images. You can use these libraries in your app to load images in the most optimized manner. We recommend the Glide library, which loads and displays images as quickly and smoothly as possible. Other popular image loading libraries include Picasso from Square and Fresco from Facebook. These libraries simplify most of the complex tasks associated with bitmaps and other types of images on Android.

Follow this link here : https://developer.android.com/topic/performance/graphics/load-bitmap

Muhammad waris
  • 314
  • 1
  • 10
0

Try getting the Bitmap directly yourself and then scaling it.

Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), mArrayUri.get(position));

That should get the Bitmap.

Then you can scale it to something smaller. I won't give an implementation for scaling, but you'll want this method:

Bitmap.createScaledBitmap(Bitmap src, int dstWidth, int dstHeight, boolean filter)
TheWanderer
  • 16,775
  • 6
  • 49
  • 63