2

I've created this demo that retrieve an image from the gallery and show it in an ImageView (after resampling the image itself) https://github.com/svappdroid/BitmapDemo

On a Galaxy Nexus I'm not able to open an image with dimension 4307x2894, logcat says "Bitmap Too Large to be uploaded in a texture"; the weird thing is that emulating the Galaxy Nexus I'm able to open the same image; why this behavior and how to solve it on the actual device?

The activity code is:


    package com.example.bitmapdemo;

    import java.io.FileNotFoundException;

    import android.app.Activity;
    import android.content.Intent;
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.net.Uri;
    import android.os.Bundle;
    import android.util.DisplayMetrics;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.Button;
    import android.widget.ImageView;
    import android.widget.LinearLayout;
    import android.widget.Toast;

    public class MainActivity extends Activity {
        public ImageView canvasImageView;
        public Button selectImageButton;
        public LinearLayout ll;
        public Bitmap image;

        //REQUEST CODE
        public static final int SELECT_IMAGE_REQ_CODE = 1;

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            ll = (LinearLayout) this.findViewById(R.id.LinearLayout1);
            canvasImageView = (ImageView) this.findViewById(R.id.canvasImageView);
            selectImageButton = (Button) this.findViewById(R.id.selectImageButton);

            selectImageButton.setOnClickListener(new OnClickListener(){

                @Override
                public void onClick(View v)
                {
                    Intent selectImageIntent = new Intent(Intent.ACTION_GET_CONTENT);
                    selectImageIntent.setType("image/*");
                    startActivityForResult(selectImageIntent, SELECT_IMAGE_REQ_CODE);
                }
            });
        }

        @Override
        protected void onActivityResult(int requestCode, int resultCode, Intent data) {
            super.onActivityResult(requestCode, resultCode, data);
            if(requestCode == SELECT_IMAGE_REQ_CODE)
            {
                switch(resultCode)
                {
                    case(RESULT_OK):
                        Uri imageUri = data.getData();

                        try
                        {
                            int inSampleSize = calculateInSampleSize(imageUri);
                            image = resampleImage(imageUri, inSampleSize);
                            canvasImageView.setImageBitmap(image);

                        }
                        catch(FileNotFoundException e){}
                }
            }
        }

        public int calculateInSampleSize(Uri imageUri) throws FileNotFoundException
        {
            BitmapFactory.Options opts = new BitmapFactory.Options();
            opts.inJustDecodeBounds = true;
            BitmapFactory.decodeStream(getContentResolver().openInputStream(imageUri), null, opts);
            int imageWidth = opts.outWidth;
            int imageHeight = opts.outHeight;
            int inSampleSize = 4;

            //Get display dimension in order to calculate image ratio
            DisplayMetrics displayMetrics = new DisplayMetrics();
            getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);

            int reqWidth = displayMetrics.widthPixels;
            int reqHeight = displayMetrics.heightPixels;

            if(imageHeight > reqHeight || imageWidth > reqWidth)
            {
                final int heightRatio = Math.round((float)imageHeight / (float) reqHeight);
                final int widthRatio = Math.round((float) imageWidth / (float) reqWidth);

                inSampleSize = heightRatio 

And here is the xml code for the layout:



<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/LinearLayout1"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <ImageView
        android:id="@+id/canvasImageView"
        android:layout_width="wrap_content"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:layout_gravity="center"
        android:src="@drawable/ic_launcher" />

    <Button
        android:id="@+id/selectImageButton"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/select_image_button" />

</LinearLayout>

basteez
  • 477
  • 1
  • 5
  • 15

2 Answers2

4

You need to resize the bitmap to be shown on the view.

Bitmap b = BitmapFactory.decodeByteArray(imageAsBytes, 0, imageAsBytes.length)
profileImage.setImageBitmap(Bitmap.createScaledBitmap(sourceBitmap, width, height, false));

There is a good documentation available for handling bitmaps in adnroid. Please refer: http://developer.android.com/training/displaying-bitmaps/index.html

On SO too you can find a number of explanation. Refer below, this will help: https://stackoverflow.com/a/10703256/2035885 https://stackoverflow.com/a/4837803/2035885

Community
  • 1
  • 1
Bette Devine
  • 1,196
  • 1
  • 9
  • 23
  • I already resized images into code, but it works on the emulator and not on the actual device, I can't explain myself this behavior – basteez Oct 27 '13 at 13:09
0

Try this code

public static Bitmap getImageFromFile(String filePath) {

        try {
            File file = new File(filePath);
            if (!file.exists()) {
                return null;
            }
            // decode image size
            BitmapFactory.Options bitmapTempOption = new BitmapFactory.Options();
            bitmapTempOption.inJustDecodeBounds = true;
            BitmapFactory.decodeStream(new FileInputStream(file), null, bitmapTempOption);

            // Find the correct scale value. It should be the power of 2.
            final int REQUIRED_SIZE = 200;
            int width_tmp = bitmapTempOption.outWidth, height_tmp = bitmapTempOption.outHeight;
            int scale = 1;
            while (true) {
                if (width_tmp / 2 < REQUIRED_SIZE || height_tmp / 2 < REQUIRED_SIZE)
                    break;
                width_tmp /= 2;
                height_tmp /= 2;
                scale *= 2;
            }

            // decode with inSampleSize
            BitmapFactory.Options bitmapOption = new BitmapFactory.Options();
            bitmapOption.inSampleSize = scale;

            try {
                return BitmapFactory.decodeStream(new FileInputStream(file), null, bitmapOption);
            } catch (OutOfMemoryError e) {
                DebugHelper.printError(e);
            } catch (Error e) {
                DebugHelper.printError(e);
            }
        } catch (Exception exception) {
            DebugHelper.printException(exception);
        }
        return null;
    }

You can also use this code to scale down the image

ImageView iv  = (ImageView)waypointListView.findViewById(R.id.waypoint_picker_photo);
Bitmap d = new BitmapDrawable(ctx.getResources() , w.photo.getAbsolutePath()).getBitmap();
int nh = (int) ( d.getHeight() * (512.0 / d.getWidth()) );
Bitmap scaled = Bitmap.createScaledBitmap(d, 512, nh, true);
iv.setImageBitmap(scaled);
Arslan Anwar
  • 18,746
  • 19
  • 76
  • 105
  • This code returns the same result of mine; That's a very weird behavior because on the actual galaxy Nexus the Logcat shows "Bitmap too large to be uploaded into texture (max 2048x2048)" but it works on an emulated Galaxy Nexus (and I'm using the same image on both devices) – basteez Oct 28 '13 at 18:33
  • okay did you try in your AndroidMenifest.xml under – Arslan Anwar Oct 28 '13 at 18:42
  • it works only if I disable Hardware Acceleration, but I'm not sure it's a good practice – basteez Oct 28 '13 at 18:45
  • final int REQUIRED_SIZE = 70; Try this last time – Arslan Anwar Oct 28 '13 at 18:55
  • I got big values of inSampleSize (i.e 16) and still have that warning – basteez Oct 28 '13 at 19:50
  • I am having very similar problems on Nexus. It doesn't matter whether I set the background image (Windows.Background in my case using Xamarin) in style or in code. From what I read in logcat it says, that the resulting image is too large for max 2048x2048. In truth it isn't, the Android is multiplying it x4 (my image is 1280x720 but Android is trying with 2560x1440 for some reason). Somehow I smell a bug in Nexus. – Miha Markic Mar 09 '14 at 11:36
  • And here is the explanation of why this is happening, hopefully it'll help somebody. https://stackoverflow.com/questions/14967408/bitmap-to-large-error-is-complaining-about-twice-the-image-size?rq=1 – Miha Markic Mar 09 '14 at 11:41