2012-08-23 49 views
2

我想簡單地調整我的位圖的大小,這是我從名爲Image Loader的以下類(使用Lazy Loadng方案)獲取的。我想簡單地將我的圖像尺寸縮小至60 * 60尺寸。但是當我使用 -在Android中調整位圖的大小

bitmap = Bitmap.createScaledBitmap(bitmap, 20, 25, false); 
imageView.setImageBitmap(bitmap); 

它與我想要的一樣,但出來的位圖非常非常模糊。有沒有其他的方式來實現相同的。

這是我在BITMAP displayer(iNNER cLASS)中的圖像加載器類我在上面顯示的代碼中設置圖像的位置。

package com.irant.LazyLoading; 

import java.io.ByteArrayOutputStream; 
import java.io.File; 
import java.io.FileInputStream; 
import java.io.FileNotFoundException; 
import java.io.FileOutputStream; 
import java.io.InputStream; 
import java.io.OutputStream; 
import java.net.HttpURLConnection; 
import java.net.URL; 
import java.util.Map; 
import java.util.Stack; 
import java.util.concurrent.ConcurrentHashMap; 

import com.irant.a1techno.R; 

import android.app.Activity; 
import android.content.Context; 
import android.graphics.Bitmap; 
import android.graphics.BitmapFactory; 
import android.graphics.Color; 
import android.graphics.Matrix; 
import android.widget.ImageView; 



public class ImageLoader { 

    MemoryCache memoryCache=new MemoryCache(); 
    FileCache fileCache; 
    private Map<ImageView, String> imageViews = new ConcurrentHashMap<ImageView, String>(); 

    public ImageLoader(Context context){ 
     //Make the background thead low priority. This way it will not affect the UI performance 
     photoLoaderThread.setPriority(Thread.NORM_PRIORITY-1); 

     fileCache=new FileCache(context); 
    } 

    final int stub_id=R.drawable.ic_launcher; 
    public void displayImage(String url, Activity activity, ImageView imageView) 
    { 
     imageViews.put(imageView, url); 
     Bitmap bitmap=memoryCache.get(url); 
     if(bitmap!=null) 
     { 
      //bitmap = Bitmap.createScaledBitmap(bitmap, 25, 25, true); 
      imageView.setImageBitmap(bitmap); 

     } 
     else 
     { 

      queuePhoto(url, activity, imageView); 
      imageView.setImageResource(stub_id); 
     }  
    } 

    private void queuePhoto(String url, Activity activity, ImageView imageView) 
    { 
     //This ImageView may be used for other images before. So there may be some old tasks in the queue. We need to discard them. 
     photosQueue.Clean(imageView); 
     PhotoToLoad p=new PhotoToLoad(url, imageView); 
     synchronized(photosQueue.photosToLoad){ 
      photosQueue.photosToLoad.push(p); 
      photosQueue.photosToLoad.notifyAll(); 
     } 

     //start thread if it's not started yet 
     if(photoLoaderThread.getState()==Thread.State.NEW) 
      photoLoaderThread.start(); 
    } 

    private Bitmap getBitmap(String url) 
    { 
     File f=fileCache.getFile(url); 
     InputStream is; 
     //from SD cache 
     Bitmap bitmap=null; 
     Bitmap b = decodeFile(f); 
     if(b!=null) 
      return b; 

     //from web 
     try { 

      System.out.println("---------------------IMAGE URL: "+url); 

      URL imageUrl = new URL(url); 
      HttpURLConnection conn = (HttpURLConnection)imageUrl.openConnection(); 
      conn.setConnectTimeout(30000); 
      conn.setReadTimeout(30000); 
      is=conn.getInputStream(); 
      OutputStream os = new FileOutputStream(f); 
      Utils.CopyStream(is, os); 
      os.close(); 
      bitmap = ShrinkBitmap(url, 60, 60); 
      bitmap = decodeFile(f); 
      ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
      bitmap.compress(Bitmap.CompressFormat.JPEG, 40, baos); 
      return bitmap; 
     } catch (Exception ex){ 
      System.out.println("---------------------IMAGE URL: "+url); 
      ex.printStackTrace(); 
      //stopThread(); 
      return null; 

     } 
     finally{ 
      bitmap = null; 
      is=null; 
     } 
    } 

    Bitmap ShrinkBitmap(String file, int width, int height){ 

     BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options(); 
     bmpFactoryOptions.inJustDecodeBounds = true; 
     Bitmap bitmap = BitmapFactory.decodeFile(file, bmpFactoryOptions); 

     int heightRatio = (int)Math.ceil(bmpFactoryOptions.outHeight/(float)height); 
     int widthRatio = (int)Math.ceil(bmpFactoryOptions.outWidth/(float)width); 

     if (heightRatio > 1 || widthRatio > 1) 
     { 
      if (heightRatio > widthRatio) 
      { 
       bmpFactoryOptions.inSampleSize = heightRatio; 
      } else { 
       bmpFactoryOptions.inSampleSize = widthRatio; 
      } 
     } 

     bmpFactoryOptions.inJustDecodeBounds = false; 
     bitmap = BitmapFactory.decodeFile(file, bmpFactoryOptions); 
     return bitmap; 
    } 

    //decodes image and scales it to reduce memory consumption 
    private Bitmap decodeFile(File f){ 
     try { 
      //decode image size 
      BitmapFactory.Options o = new BitmapFactory.Options(); 

      o.inJustDecodeBounds = true; 
      BitmapFactory.decodeStream(new FileInputStream(f),null,o); 

      //Find the correct scale value. It should be the power of 2. 
      final int REQUIRED_SIZE=70; 
      int width_tmp=o.outWidth, height_tmp=o.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 o2 = new BitmapFactory.Options(); 
      o2.inSampleSize=scale; 
      return BitmapFactory.decodeStream(new FileInputStream(f), null, o2); 
     } 
     catch(OutOfMemoryError e) 
     { 
      e.printStackTrace(); 
     }catch (FileNotFoundException e) {} 
     return null; 
    } 

    //Task for the queue 
    private class PhotoToLoad 
    { 
     public String url; 
     public ImageView imageView; 
     public PhotoToLoad(String u, ImageView i){ 
      url=u; 
      imageView=i; 
     } 
    } 

    PhotosQueue photosQueue=new PhotosQueue(); 

    public void stopThread() 
    { 
     photoLoaderThread.interrupt(); 
    } 

    //stores list of photos to download 
    class PhotosQueue 
    { 
     private Stack<PhotoToLoad> photosToLoad=new Stack<PhotoToLoad>(); 

     //removes all instances of this ImageView 
     public void Clean(ImageView image) 
     { 
      for(int j=0 ;j<photosToLoad.size();){ 
       if(photosToLoad.get(j).imageView==image) 
        photosToLoad.remove(j); 
       else 
        ++j; 
      } 
     } 
    } 

    public class PhotosLoader extends Thread { 
     public void run() { 
      try { 
       while(true) 
       { 
        //thread waits until there are any images to load in the queue 
        if(photosQueue.photosToLoad.size()==0) 
         synchronized(photosQueue.photosToLoad){ 
          photosQueue.photosToLoad.wait(); 
         } 
        if(photosQueue.photosToLoad.size()!=0) 
        { 
         PhotoToLoad photoToLoad; 
         synchronized(photosQueue.photosToLoad){ 
          photoToLoad=photosQueue.photosToLoad.pop(); 
         } 
         Bitmap bmp=getBitmap(photoToLoad.url); 
         memoryCache.put(photoToLoad.url, bmp); 
         String tag=imageViews.get(photoToLoad.imageView); 
         if(tag!=null && tag.equals(photoToLoad.url)){ 
          BitmapDisplayer bd=new BitmapDisplayer(bmp, photoToLoad.imageView); 
          Activity a=(Activity)photoToLoad.imageView.getContext(); 
          a.runOnUiThread(bd); 
         } 
        } 
        if(Thread.interrupted()) 
         break; 
       } 
      } catch (InterruptedException e) { 
       //allow thread to exit 
       System.out.println("This is the Exit Point............"); 
      } 
     } 
    } 

    PhotosLoader photoLoaderThread=new PhotosLoader(); 

    //Used to display bitmap in the UI thread 
    class BitmapDisplayer implements Runnable 
    { 
     Bitmap bitmap; 
     ImageView imageView; 
     public BitmapDisplayer(Bitmap b, ImageView i){bitmap=b;imageView=i;} 
     public void run() 
     { 
      if(bitmap!=null) 
      { 
       bitmap = Bitmap.createScaledBitmap(bitmap, 20, 25, false); 
       imageView.setImageBitmap(bitmap); 
      } 
      else 
       imageView.setImageResource(stub_id); 
     } 
    } 

    public void clearCache() { 
     memoryCache.clear(); 
     fileCache.clear(); 
    } 



} 

請回復我。 在此先感謝

如果你不明白,請不要投票。只要有人能幫助我,請幫助我。

感謝

+0

如果你希望它是60 * 60,爲什麼你將它縮放到20 * 25?也許這就是爲什麼它是模糊的? – JRaymond

+0

我只是試着用20 * 25,如果它仍然模糊不清。即使我將它縮放到10 * 10。它顯示模糊的圖像。 –

+0

我只是說這取決於Imageview的scaleType,如果你放入一個比imageview本身小的圖像,它會拉伸該圖像以填滿它的邊界 - 只要確保你已經嘗試了60 * 60或實際上你的imageview實際上很大是 – JRaymond

回答

2

ImageView的默認scaleTypeFIT_CENTER,這意味着,無論圖片你給ImageView將被縮小,使得軸之一將是(你的情況)110dp。所以傳遞一個縮小到10 * 10的位圖將會擴展該位圖來填充110 * 110的空間,而10 * 10的拉伸將確實非常模糊。嘗試使用其他scaleType S的一個,具體CENTER看到圖像的非模糊,正常大小的版本:

imageView.setScaleType(ImageView.ScaleType.CENTER); 

如果這不是你想要的效果,知道,無論你做什麼,一個萎縮圖像,然後再將其拉伸出來會使其質量低於開始時的質量。在上面的代碼示例中您似乎正在嘗試做的很多工作都是由ImageView課程自己完成的 - 我鼓勵您仔細看看ScaleType和他們可以爲您做些什麼

+0

現在我按照您的建議使用此代碼.. imageView.setScaleType(ImageView.ScaleType.CENTER); bitmap = Bitmap.createScaledBitmap(bitmap,20,25,false); imageView.setImageBitmap(bitmap); 使用後,我得到ImageView沒有圖像,只有背景框架,我已經在imageview背景中添加。請幫我雷蒙德。關於同樣的問題,我也有很大的問題。謝謝 –

+0

謝謝雷蒙德:)它爲我工作。非常感謝 –

+0

@GauravArora很高興幫助! – JRaymond