2010-11-17 26 views
27

Kalite kaybı olmadan Ağ akışından gelen görüntüleri küçültmem gerekiyor.Android: yüksek kaliteli görüntü boyutlandırma/ölçekleme

Bu çözümün Strange out of memory issue while loading an image to a Bitmap object farkındayım, ancak çok kaba - inSampleSize bir tamsayıdır ve ortaya çıkan boyutlar üzerinde daha ince denetim yapılmasına izin vermez. Yani, görüntüleri belirli h/w boyutlarına (ve en boy oranını koruyarak) ölçeklendirmem gerekiyor.

Kodumda bir DIY bicubic/lancoz algoritmasına sahip olduğumu düşünmüyorum, ancak hepsi Java2D (JavaSE) 'ye bağlı olduğu için Android üzerinde çalışacak örnekler bulamıyorum.

DÜZENLEME: Hızlı bir kaynak ekledim. Orijinal 720x402 HD ekran yakalama. Lütfen ilk 2 küçük resmi göz ardı edin. En büyük resim, android tarafından (düzenin bir parçası olarak) yaklaşık 130x72'ye otomatik olarak yeniden boyutlandırılır. Güzel ve gevrek. alt görüntü API ile boyutlandırılır ve şiddetli artifacting

alt text

Ben de BitmapFactory ve kullanmayı denedik, vardır daha önce söylediğim gibi, bu iki sorun vardır - hayır boyutunu tam şekle ölçekli yolu ve ölçeklendirilebilir görüntü bulanık.

Resimlerin düzeltilmesiyle ilgili herhangi bir fikir var mı?

Teşekkürler, S.O.!

package qp.test; 

import android.app.Activity; 
import android.graphics.Bitmap; 
import android.graphics.BitmapFactory; 
import android.graphics.Matrix; 
import android.os.Bundle; 
import android.widget.ImageView; 

public class imgview extends Activity { 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 

     Bitmap original = BitmapFactory.decodeResource(getResources(), R.drawable.a000001570402); 
     Bitmap resized = getResizedBitmap(original, 130); 
     //Bitmap resized = getResizedBitmap2(original, 0.3f); 
     System.err.println(resized.getWidth() + "x" + resized.getHeight()); 

     ImageView image = (ImageView) findViewById(R.id.ImageViewFullManual); 
     image.setImageBitmap(resized); 

    } 

    private Bitmap getResizedBitmap(Bitmap bm, int newWidth) { 

     int width = bm.getWidth(); 

     int height = bm.getHeight(); 

    float aspect = (float)width/height; 

    float scaleWidth = newWidth; 

    float scaleHeight = scaleWidth/aspect;  // yeah! 

    // create a matrix for the manipulation 

    Matrix matrix = new Matrix(); 

    // resize the bit map 

    matrix.postScale(scaleWidth/width, scaleHeight/height); 

    // recreate the new Bitmap 

    Bitmap resizedBitmap = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, true); 

     bm.recycle(); 

     return resizedBitmap; 
    } 

    private Bitmap getResizedBitmap2(Bitmap bm, float scale) { 

    /* float aspect = bm.getWidth()/bm.getHeight(); 

     int scaleWidth = (int) (bm.getWidth() * scale); 
     int scaleHeight = (int) (bm.getHeight() * scale); 
*/ 
     // original image is 720x402 and SampleSize=4 produces 180x102, which is 
     // still too large 

     BitmapFactory.Options bfo = new BitmapFactory.Options(); 
     bfo.inSampleSize = 4; 

     return BitmapFactory.decodeResource(getResources(), R.drawable.a000001570402, bfo); 
    } 

} 

Ve üst geniş görüntü basitçe böylece düzen tarafından en fazla 450 piksel hiçbir eserler küçültülür

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:orientation="vertical" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    > 
<!-- <TextView 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="hullo" android:background="#00ff00" 
    /> 
    --> 
    <ImageView android:id="@+id/ImageViewThumbAuto" 
      android:layout_width="130dip" android:layout_height="72dip" 
      android:src="@drawable/a000001570402" /> 

    <ImageView android:id="@+id/ImageViewThumbManual" 
      android:layout_width="130dip" android:layout_height="72dip" 
      android:src="@drawable/a000001570402" 
      android:layout_toRightOf="@id/ImageViewThumbAuto" 
      /> 

<ImageView android:id="@+id/ImageViewFullAuto" android:layout_width="300dip" 
      android:layout_height="169dip" 
      android:scaleType="fitXY" 
      android:src="@drawable/a000001570402" 
      android:layout_below="@id/ImageViewThumbAuto" 
      /> 

<ImageView android:id="@+id/ImageViewFullManual" android:layout_width="300dip" 
      android:layout_height="169dip" 
      android:scaleType="fitXY" 
      android:src="@drawable/a000001570402" 
      android:layout_below="@id/ImageViewFullAuto" 
      /> 

</RelativeLayout> 
+0

i İşte SonyMobile bu görevi çözüme nasıl ayrıntılı açıklama En iyi görüntü aslında 130px genişliğinde olduğunu düşünmüyorum. http://icons-search.com/img/fasticon/fast_emoticons_lnx.zip/fast_emoticons_lnx-Icons-128X128-smile_1.png-128x128.png 128 px genişliğindedir .... – Quamis

+0

[bu eğitim] 'i inceleyin (http://developer.android.com/training/displaying-bitmaps/index.html) resimleri çözme hakkında. –

+0

Merhaba! Aynı sorunla karşılaştı, çözüm buldunuz mu? – Dehimb

cevap

8

düzeni.

Alttaki büyük görüntünün artifaktları, paftayla 130 piksel genişliğe ve daha sonra yaklaşık 450 piksele kadar ölçeklendirmenin sonucudur. Böylece eserler, ölçeklemeniz tarafından yapılır. Kodunuzda

Bitmap resized = getResizedBitmap(original, 450); 

deneyin ve iyi olmalıdır. Ancak, bunu telefonun harekete geçirme ekran genişliğine de uyarlamanız gerekir.

9

Sen inDensity ve inTargetDensity

Örnek kullanılarak BitmapFactory.decode fonksiyonu (ler),
ile BitmapFactory.Options kullanabilirsiniz: resmin 1600x1200 büyüklüğe sahip ve 640x480
için yeniden boyutlandırmak istediğiniz sonra 'inDensity'=5 ve 'inTargetDensity'=2 (1600x2, 640x5'e eşittir).

Bu yardımı bekliyoruz. İyi küçültme algoritması (değil yakın komşu gibi)

+0

Ne yazık ki, bu en yakın komşu küçültme oranını üretir. Anladığım gibi, bicubic ölçek küçültmeyi tutmak için sadece inSampleSize değiştirilmesine izin verilir. – goRGon

4

Kısaca 2 adımdan oluşur:

  1. BitmapFactory.Options :: inSampleSize-> BitmapFactory kullanarak Downscale.decodeResource() ihtiyacınız çözünürlüğe mümkün olduğunca yakın ama Tuval :: drawBitmap() kullanarak biraz ölçek küçültme tarafından o
  2. tam çözünürlükte olsun az olmayacak

İşte http://developer.sonymobile.com/2011/06/27/how-to-scale-images-for-your-android-application/

SonyMobile ölçekli Araçlarının kaynak kodu olan: http://developer.sonymobile.com/downloads/code-example-module/image-scaling-code-example-for-android/

İlgili konular