"Bitmapa zbyt duża, aby można ją było wgrać do tekstury"

Ładuję bitmapę do ImageView i widzę ten błąd. Domyślam się, że limit ten odnosi się do limitu rozmiaru dla tekstur sprzętowych OpenGL (2048x2048). Obraz, który muszę załadować, to obraz z pinch-zoomem o wysokości około 4000 pikseli.

Próbowałem wyłączyć akcelerację sprzętową w manifeście, ale bez radości.
    <application
        android:hardwareAccelerated="false"
        ....
        >

Czy można załadować obraz większy niż 2048 pikseli do ImageView?

Author: Jonik, 2012-04-22

17 answers

Wszystkie renderowanie jest oparte na OpenGL, więc nie możesz przekroczyć tego limitu (GL_MAX_TEXTURE_SIZE zależy od urządzenia, ale minimum to 2048x2048, więc każdy obraz niższy niż 2048x2048 będzie pasował).

Z tak dużymi obrazami, jeśli chcesz powiększyć, a w telefonie komórkowym, powinieneś skonfigurować system podobny do tego, co widzisz na przykład w google maps. Z obrazem podzielonym na kilka części i kilka definicji.

Lub możesz przeskalować obraz przed wyświetlaniem (zobacz user1352407 ' s ODPOWIEDŹ na to pytanie).

A także uważaj, w którym folderze umieścisz obraz, Android może automatycznie skalować obrazy. Zobacz odpowiedź Pilot_51 poniżej na to pytanie.

 43
Author: jptsetung,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-01 10:41:22

To nie jest bezpośrednia odpowiedź na pytanie (ładowanie obrazów >2048), ale możliwe rozwiązanie dla każdego, kto doświadczy błędu.

W moim przypadku obraz był mniejszy niż 2048 w obu wymiarach (dokładnie 1280x727) i problem był szczególnie doświadczony na Galaxy Nexus. Obraz był w folderze drawable i żaden z zakwalifikowanych folderów. Android zakłada, że drawables bez kwalifikatora gęstości to mdpi i skaluje je w górę lub w dół dla innych gęstości, w tym przypadku skalowane 2x dla xhdpi. Przesunięcie obrazu winowajcy do drawable-nodpi, aby zapobiec skalowaniu rozwiązało problem.

 379
Author: Pilot_51,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-14 14:57:56

Przeskalowałem obraz w ten sposób:

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);
 97
Author: user1352407,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-27 17:57:55

Zamiast spędzać godziny próbując ręcznie napisać/debugować cały ten downsampling kodu, dlaczego nie użyć Picasso? Został stworzony do obsługi bitmaps wszystkich typów i / lub rozmiarów.

Użyłem tej pojedynczej linii kodu, aby usunąć moją "bitmapę zbyt dużą...." problem:

Picasso.with(context).load(resourceId).fit().centerCrop().into(imageView);
 32
Author: Phileo99,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-12 10:05:52

Zmiana pliku obrazu na folder drawable-nodpi z folderu drawable zadziałała dla mnie.

 16
Author: Asha Antony,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-02 01:59:43

Używałem Picassa i miałem ten sam problem. obraz był zbyt duży przynajmniej w rozmiarze, szerokości lub wysokości. w końcu znalazłem rozwiązanie tutaj. możesz skalować duży obraz w dół zgodnie z rozmiarem wyświetlacza, a także zachować proporcje:

    public Point getDisplaySize(Display display) {
    Point size = new Point();

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
        display.getSize(size);
    } else {
        int width = display.getWidth();
        int height = display.getHeight();
        size = new Point(width, height);
    }

    return size;
}

I użyj tej metody do ładowania obrazu Picassa:

    final Point displySize = getDisplaySize(getWindowManager().getDefaultDisplay());
        final int size = (int) Math.ceil(Math.sqrt(displySize.x * displySize.y));
        Picasso.with(this)
                .load(urlSource)
                .resize(size, size)
                .centerInside()
                .into(imageViewd);

Również dla lepszej wydajności można pobrać obraz w zależności od szerokości i wysokości ekranu wyświetlacza, a nie całego obrazu:

    public String reviseImageUrl(final Integer displayWidth,     final Integer displayHeight,
        final String originalImageUrl) {
    final String revisedImageUrl;

    if (displayWidth == null && displayHeight == null) {
        revisedImageUrl = originalImageUrl;
    } else {
        final Uri.Builder uriBuilder = Uri.parse(originalImageUrl).buildUpon();

        if (displayWidth != null && displayWidth > 0) {
            uriBuilder.appendQueryParameter(QUERY_KEY_DISPLAY_WIDTH, String.valueOf(displayWidth));
        }

        if (displayHeight != null && displayHeight > 0) {
            uriBuilder.appendQueryParameter(QUERY_KEY_DISPLAY_HEIGHT, String.valueOf(displayHeight));
        }

        revisedImageUrl = uriBuilder.toString();
    }

    return revisedImageUrl;
}

    final String newImageUlr = reviseImageUrl(displySize.x, displySize.y, urlSource);

I wtedy:

    Picasso.with(this)
                .load(newImageUlr)
                .resize(size, size)
                .centerInside()
                .into(imageViewd);

EDIT: getDisplaySize()

display.getWidth()/getHeight() jest przestarzały. Zamiast Display użyj DisplayMetrics.

public Point getDisplaySize(DisplayMetrics displayMetrics) {
        int width = displayMetrics.widthPixels;
        int height = displayMetrics.heightPixels;
        return new Point(width, height);
}
 9
Author: Sherry,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-29 08:12:18

Dodanie następujących 2 atrybutów w (AndroidManifest.xml) zadziałało dla mnie:

android:largeHeap="true"
android:hardwareAccelerated="false"
 6
Author: Sachin Lala,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-12 10:37:06

BitmapRegionDecoder wystarczy.

Możesz nadpisać onDraw(Canvas canvas), rozpocząć nowy wątek i dekodować obszar widoczny dla użytkownika.

 6
Author: Larcho,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-12 12:04:33

Jak zauważył Larcho, począwszy od poziomu API 10, możesz użyć BitmapRegionDecoder do załadowania określonych regionów z obrazu i dzięki temu możesz pokazać duży obraz w wysokiej rozdzielczości, przydzielając w pamięci tylko potrzebne regiony. Niedawno opracowałem lib, który zapewnia wizualizację dużych obrazów z obsługą gestów dotykowych. Kod źródłowy i próbki są dostępne tutaj .

 5
Author: diegocarloslima,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-02 02:39:16

Miałem ten sam problem, Oto moje rozwiązanie. ustaw szerokość obrazu taką samą jak szerokość ekranu Androida, a następnie skaluj wysokość

Bitmap myBitmap = BitmapFactory.decodeFile(image.getAbsolutePath());
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int width = size.x;
int height = size.y;
Log.e("Screen width ", " "+width);
Log.e("Screen height ", " "+height);
Log.e("img width ", " "+myBitmap.getWidth());
Log.e("img height ", " "+myBitmap.getHeight());
float scaleHt =(float) width/myBitmap.getWidth();
Log.e("Scaled percent ", " "+scaleHt);
Bitmap scaled = Bitmap.createScaledBitmap(myBitmap, width, (int)(myBitmap.getWidth()*scaleHt), true);
myImage.setImageBitmap(scaled);

Jest to lepsze dla każdego rozmiaru ekranu Androida. daj znać, jeśli ci się uda.

 3
Author: Abhijit Gujar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-04 13:08:30

Skaluj obraz w dół:

BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;

// Set height and width in options, does not return an image and no resource taken
BitmapFactory.decodeStream(imagefile, null, options);

int pow = 0;
while (options.outHeight >> pow > reqHeight || options.outWidth >> pow > reqWidth)
    pow += 1;
options.inSampleSize = 1 << pow; 
options.inJustDecodeBounds = false;
image = BitmapFactory.decodeStream(imagefile, null, options);

Obraz zostanie pomniejszony o rozmiar reqHeight i reqWidth. Jak rozumiem inSampleSize przyjmuje tylko moc 2 wartości.

 1
Author: vtlinh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-27 12:39:24

Poziom widoku

Możesz wyłączyć akcelerację sprzętową dla poszczególnych widoków w czasie wykonywania za pomocą następującego kodu:

MyView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);

 1
Author: marveson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-05 10:51:43

[1]}próbowałem wszystkich powyższych rozwiązań, jeden po drugim, przez wiele godzin i żadne nie działało! Na koniec postanowiłem rozejrzeć się po oficjalnym przykładzie dotyczącym przechwytywania zdjęć aparatem Androida i wyświetlania ich. Oficjalny przykład ( Tutaj ) w końcu dał mi jedyną metodę, która zadziałała. Poniżej przedstawiam rozwiązanie, które znalazłem w tej przykładowej aplikacji:

public void setThumbnailImageAndSave(final ImageView imgView, File imgFile) {

            /* There isn't enough memory to open up more than a couple camera photos */
    /* So pre-scale the target bitmap into which the file is decoded */

    /* Get the size of the ImageView */
    int targetW = imgView.getWidth();
    int targetH = imgView.getHeight();

    /* Get the size of the image */
    BitmapFactory.Options bmOptions = new BitmapFactory.Options();
    bmOptions.inJustDecodeBounds = true;
    BitmapFactory.decodeFile(imgFile.getAbsolutePath(), bmOptions);
    int photoW = bmOptions.outWidth;
    int photoH = bmOptions.outHeight;

    /* Figure out which way needs to be reduced less */
    int scaleFactor = 1;
    if ((targetW > 0) || (targetH > 0)) {
        scaleFactor = Math.min(photoW/targetW, photoH/targetH);
    }

    /* Set bitmap options to scale the image decode target */
    bmOptions.inJustDecodeBounds = false;
    bmOptions.inSampleSize = scaleFactor;
    bmOptions.inPurgeable = true;

    /* Decode the JPEG file into a Bitmap */
    Bitmap bitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath(), bmOptions);

    /* Associate the Bitmap to the ImageView */
    imgView.setImageBitmap(bitmap);
    imgView.setVisibility(View.VISIBLE);
}
 1
Author: nemesisfixx,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-12 09:02:23

UWAGA DLA TYCH, KTÓRZY CHCĄ UMIEŚCIĆ OBRAZY O MAŁYCH ROZMIARACH:

Rozwiązanie Pilot_51 (przeniesienie zdjęć do folderu drawable-nodpi) działa, ale ma inny problem: To sprawia, że obrazy zbyt małe na ekranie, chyba że obrazy są zmieniane do bardzo dużej (jak 2000 x 3800) rozdzielczości, aby dopasować ekran - to sprawia, że aplikacja jest cięższa .

Rozwiązanie : umieść swoje pliki graficzne w drawable-hdpi -- zadziałało jak urok dla mnie.

 0
Author: makeasy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-30 18:12:59

Użycie poprawnego podfolderu drawable rozwiązało to dla mnie. Moim rozwiązaniem było umieszczenie mojego obrazu w pełnej ROZDZIELCZOŚCI (1920x1200) w folderze drawable-xhdpi, zamiast folderu drawable.

Umieściłem również skalowany obraz (1280x800) w folderze drawable-hdpi .

Te dwie rozdzielczości pasują do tabletów Nexus 7 z 2013 i 2012 roku, które programuję. Przetestowałem również rozwiązanie na kilku innych tabletach.

 0
Author: steveputz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-21 21:24:51
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {

    super.onActivityResult(requestCode, resultCode, data);
    ///*
    if (requestCode == PICK_FROM_FILE && resultCode == RESULT_OK && null != data){



        uri = data.getData();

        String[] prjection ={MediaStore.Images.Media.DATA};

        Cursor cursor = getContentResolver().query(uri,prjection,null,null,null);

        cursor.moveToFirst();

        int columnIndex = cursor.getColumnIndex(prjection[0]);

        ImagePath = cursor.getString(columnIndex);

        cursor.close();

        FixBitmap = BitmapFactory.decodeFile(ImagePath);

        ShowSelectedImage = (ImageView)findViewById(R.id.imageView);

      //  FixBitmap = new BitmapDrawable(ImagePath);
        int nh = (int) ( FixBitmap.getHeight() * (512.0 / FixBitmap.getWidth()) );
        FixBitmap = Bitmap.createScaledBitmap(FixBitmap, 512, nh, true);

       // ShowSelectedImage.setImageBitmap(BitmapFactory.decodeFile(ImagePath));

        ShowSelectedImage.setImageBitmap(FixBitmap);

    }
}

This code is work

 0
Author: Alobaidi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-16 07:19:33

Użyj Biblioteki Glide zamiast bezpośrednio ładować do imageview

Glide: https://github.com/bumptech/glide

Glide.with(this).load(Uri.parse(filelocation))).into(img_selectPassportPic);
 0
Author: saigopi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-17 06:56:06