2010-11-17 72 views
27

我需要縮小來自網絡流的圖像而不會丟失質量。Android:高質量圖像大小調整/縮放

我知道這個解決方案Strange out of memory issue while loading an image to a Bitmap object,但它太粗糙 - inSampleSize是一個整數,不允許更好地控制生成的維度。也就是說,我需要將圖像縮放到特定的h/w尺寸(並保持寬高比)。

我不具有我的代碼DIY雙三次/ lancoz算法的頭腦,但我不能找到,將在Android上工作,因爲他們都依賴於Java2D的(JavaSE的)任何例子。編輯: 我附上了一個快速的來源。原來是720x402高清屏幕捕捉。請忽略前兩個縮略圖。頂部大圖像由android(作爲佈局的一部分)自動調整大約130x72。它很好,很脆。底部的圖像的大小與API和有嚴重的僞像

alt text

我使用BitmapFactory和也試過,正如我剛纔所說,它有兩個問題 - 沒有辦法擴展到精確的尺寸和比例圖像模糊。

任何想法如何解決artifcating?

謝謝,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); 
    } 

} 

並且佈局

<?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

我不要認爲頂部圖像實際上是130px寬。 http://icons-search.com/img/fasticon/fast_emoticons_lnx.zip/fast_emoticons_lnx-Icons-128X128-smile_1.png-128x128.png是128像素寬.... – Quamis 2011-04-20 09:20:03

+0

檢查出[本教程](http:///developer.android.com/training/displaying-bitmaps/index.html)解碼圖像。 – 2013-01-18 14:14:48

+0

嗨!面對同樣的問題,你找到解決方案嗎? – Dehimb 2016-08-11 16:35:12

回答

8

頂部大的圖像被簡單地由佈局按比例縮小到450像素,從而沒有僞影。

底部大的圖像結果的從再升比例縮小以130px寬,然後由佈局大約450像素的僞影。所以工件是由你的縮放製成的。嘗試

Bitmap resized = getResizedBitmap(original, 450); 
在你的代碼

,它應該是罰款。但是,您需要將其適應手機的實際屏幕寬度。

9

您可以使用BitmapFactory.Options使用inDensityinTargetDensity

BitmapFactory.decode功能(S),
:你有1600x1200的大小的圖片,並希望調整到640×480
然後'inDensity'=5'inTargetDensity'=2(1600x2等於640x5)。

希望這幫助。

+0

不幸的是,這會產生最近鄰居的降尺度。正如我想到的,爲了保持雙三次降尺度,只允許改變inSampleSize。 – goRGon 2014-04-19 00:22:25

4

簡言之,良好縮小算法(未近鄰等)由2個步驟:

  1. 縮減使用BitmapFactory.Options :: inSampleSize-> BitmapFactory。decodeResource()儘可能接近到你所需要的分辨率,但不低於其
  2. 得到精確的分辨率,通過縮減使用帆布:: drawBitmap()有點

下面是詳細的解釋SonyMobile如何解決這個任務:http://developer.sonymobile.com/2011/06/27/how-to-scale-images-for-your-android-application/

下面是SonyMobile規模utils的源代碼:http://developer.sonymobile.com/downloads/code-example-module/image-scaling-code-example-for-android/