2013-03-27 22 views
14

Bir Android uygulamasında biraz büyük görüntüler gösterme zorunluluğum var. Şu anda bir kaynak Bitmap ile bir ImageView kullanıyorum. OpenGL'nin, ile ilgili belirli bir aygıttan bağımsız sınırlamanın, görüntü boyutlarının işleyebilmesi için ne kadar büyük olabileceğini anlıyorum. Android'in doku boyut sınırlaması ile ilgileniyor

Bu görüntüleri görüntülemek için HERHANGİ yolu birden ImageView elemanları içine görüntüyü bölme daha diğer bakılmaksızın bu limitin (sabit genişlikte Kırpma olmadan) var mı?

Teşekkür ederiz.

GÜNCELLEME 01 Nis 2013 Şimdiye kadar yapılan hiçbir şans, görüntü kalitesini düşürmek değildi. Biri, GPU'yu kullanmak yerine işlem yapmak için CPU kullanarak bu sınırlamayı atlamanın mümkün olabileceğini gösterdi (yine de daha fazla zaman alabilir). Anlamıyorum, görüntü kalitesini düşürmeden uzun bir görüntüyü sabit genişlikte görüntülemenin gerçekten bir yolu yok mu? Bahse girerim, en azından beni en doğru yöne yönlendirirse sevinirim.

Herkese teşekkürler.

+1

Bunun hakkında emin değilim, ancak bunun yerine bir WebView kullanmayı denediniz mi? –

+1

Gerçekten de, bir liste görünümünde rastgele yerleştirilmiş çok sayıda çok sayıda imge var. Performansı dikkate almalıyım ve bu oldukça kötü bir fikir gibi geliyor .. – woot

+0

Bu güzel projeye bir göz atın: https://github.com/ened/Android-Tiling-ScrollView –

cevap

9

Büyük bitmap'leri parçalamak için BitmapRegionDecoder'u kullanabilirsiniz (API düzeyi 10 gerektirir). Bu sınıf kullanmak ve içine konabilir tek Drawable dönecektir bir yöntem yazdı ettik bir ImageView: yöntem çekilebilir kaynak hem de MAX_SIZE (1024) daha küçük olup olmadığını görmek için kontrol eder

private static final int MAX_SIZE = 1024; 

private Drawable createLargeDrawable(int resId) throws IOException { 

    InputStream is = getResources().openRawResource(resId); 
    BitmapRegionDecoder brd = BitmapRegionDecoder.newInstance(is, true); 

    try { 
     if (brd.getWidth() <= MAX_SIZE && brd.getHeight() <= MAX_SIZE) { 
      return new BitmapDrawable(getResources(), is); 
     } 

     int rowCount = (int) Math.ceil((float) brd.getHeight()/(float) MAX_SIZE); 
     int colCount = (int) Math.ceil((float) brd.getWidth()/(float) MAX_SIZE); 

     BitmapDrawable[] drawables = new BitmapDrawable[rowCount * colCount]; 

     for (int i = 0; i < rowCount; i++) { 

      int top = MAX_SIZE * i; 
      int bottom = i == rowCount - 1 ? brd.getHeight() : top + MAX_SIZE; 

      for (int j = 0; j < colCount; j++) { 

       int left = MAX_SIZE * j; 
       int right = j == colCount - 1 ? brd.getWidth() : left + MAX_SIZE; 

       Bitmap b = brd.decodeRegion(new Rect(left, top, right, bottom), null); 
       BitmapDrawable bd = new BitmapDrawable(getResources(), b); 
       bd.setGravity(Gravity.TOP | Gravity.LEFT); 
       drawables[i * colCount + j] = bd; 
      } 
     } 

     LayerDrawable ld = new LayerDrawable(drawables); 
     for (int i = 0; i < rowCount; i++) { 
      for (int j = 0; j < colCount; j++) { 
       ld.setLayerInset(i * colCount + j, MAX_SIZE * j, MAX_SIZE * i, 0, 0); 
      } 
     } 

     return ld; 
    } 
    finally { 
     brd.recycle(); 
    } 
} 

eksenleri. Öyleyse, sadece çekilebilir. Değilse, görüntüyü parçalayacak ve görüntünün parçalarını çözecek ve bunları LayerDrawable'a yerleştirecektir.

1024'ü seçtim çünkü çoğu telefonun görüntüleri en azından o kadar büyük ölçüde destekleyeceğine inanıyorum.Bir telefon için gerçek doku boyutu sınırını bulmak istiyorsanız, OpenGL ile bazı garip şeyler yapmalısınız, ve ben de içine dalmak istediğim bir şey değil.

Resimlerinize nasıl eriştiğinizden emin değildim, bu nedenle onların çekilebilir klasörünüzde olduğunu varsaydım. Durum böyle değilse, ihtiyacınız olan herhangi bir parametreyi almak için yöntemi yeniden düzenlemek oldukça kolay olmalıdır.

+0

Bu uygulamanın sadece bir satır değil, yalnızca satırlara bölündüğü unutulmamalıdır. Genişlik maksimum boyuttan daha büyükse, algoritmadan geçecektir ancak parçalar hala MAX_SIZE'dan daha büyük genişlikler içerecektir. Bunun için destek eklemek çok önemli bir çözümdür ve LayerDrawable'ı çizim tablosunu göstermek için kullanmayı hiç düşünmezdim. Mükemmel cevap. –

+0

Düzeltme işleminde, yalnızca satırlar yerine kare parçalara bölünecek şekilde düzenlenmiştir. –

+0

@DavidLiu eklemeleriniz için teşekkürler. Yaptığınız değişikliklerle ilgilendiğim birkaç hata vardı. Lütfen düzenlemelerimi inceleyin ve düzenlemenizin amacını ihlal etmediğime emin olun. Yöntem, yakalama gereği duyulmaması için IOException özelliğini atar. –

3

Böyle Somthing kullanabilirsiniz picture.You boyutunu azaltmak için BitmapFactoryOptions kullanabilirsiniz:

BitmapFactory.Options options = new BitmapFactory.Options(); 
options.inSampleSize = 3; //reduce size 3 times 
+0

Teşekkür ederim, ama hiç yok görüntü kalitesini düşürmeden istenilen sonucu elde edebildim mi? – woot

+0

Görüntü kalitesini düşürmeden herhangi bir çözüm olduğunu düşünmüyorum. Çünkü taşma hatası veriyor. – developerCoder

0

Bize bitmap boyutu kazandırdı yardımcı olurdu.

Lütfen OpenGL'nin doğal matematiksel sınırlara karşı çalıştığını unutmayın. Örneğin, OpenGL'deki bir doku x'in gücüne 2 olması için çok iyi bir neden vardır. Bu gerçekten herhangi bir ölçek küçültmenin matematiğinin kalan hiçbir şey olmadan temiz bir şekilde yapılabilmesi için tek yoldur.

Bize sorun veren en küçük bitmap boyutlarını bize verirseniz, bazılarınız size karşı karşıya kaldığınız gerçek sınırın ne olduğunu anlatabilir.

+0

Bitmapin boyutları dinamik, genişlik 480px kadar yüksek olabilir, yükseklik 1px ile 10000px arasında bir şey olabilir. Görüntülenecek olan istenen genişlik, ekranın genişliği ile birlikte bazı kenar boşluklarıdır. En üst soldan görünüm oranı korunurken, görüntü istenen genişliğe ölçeklendirilmelidir. – woot

+0

Ardından, bir OpenGL dokusu değil. Buna öyle davranma. OpenGL'de arka plan resimleri olabilir, bu iyi, dokular olarak davranmadığınız sürece, bunlar iyi olacak. –

+0

Bunları doku olarak görmemek ne demek istiyorsun? OpenGL'yi doğrudan kullanmıyorum, tek yaptığım bir ImageView için bir kaynak oluşturuyor, ardından cihazın doku boyutu sınırı nedeniyle görüntü gösterilmiyor. Örneğin: "Bir Nexus 10" üzerinde bir dokuya (480x5400, max = 4096x4096) yüklenecek kadar büyük bit eşlem. – woot

2

Haritalarınızın nasıl çalıştığını gördünüz mü? Bir kez haritalar için bir işleyici yapmıştım. Resminizi görüntülemek için aynı numarayı kullanabilirsiniz.

Görüntünüzü kare karolara bölün (ör. 128x128 piksel). Özel resim oluşturmaRayanstan render oluşturmayı destekleyin. ImageView, bitmap'in hangi bölümünü şimdi göstermesi gerektiğini ve yalnızca bunları SD kartınızdan yükleyen gerekli fayansların gösterildiğini bilir. Bu karo haritasını kullanarak sonsuz görüntüleri görüntüleyebilirsiniz.