4

I'm working on a media player app and wish to load album art images to display in a ListView. Right now it works fine with the images I'm auto-downloading from last.fm which are under 500x500 png's. However, I recently added another panel to my app that allows viewing full screen artwork so I've replaced some of my artworks with large (1024x1024) png's instead.

Now when I scroll over several albums with high res artwork, I get a java.lang.OutOfMemoryError on my BitmapFactory.

    static public Bitmap getAlbumArtFromCache(String artist, String album, Context c)
    {
    Bitmap artwork = null;
    File dirfile = new File(SourceListOperations.getAlbumArtPath(c));
    dirfile.mkdirs();
    String artfilepath = SourceListOperations.getAlbumArtPath(c) + File.separator + SourceListOperations.makeFilename(artist) + "_" + SourceListOperations.makeFilename(album) + ".png";
    File infile = new File(artfilepath);
    try
    {
        artwork = BitmapFactory.decodeFile(infile.getAbsolutePath());
    }catch(Exception e){}
    if(artwork == null)
    {
        try
        {
            artwork = BitmapFactory.decodeResource(c.getResources(), R.drawable.icon);
        }catch(Exception ex){}
    }
    return artwork;
    }

Is there anything I can add to limit the size of the resulting Bitmap object to say, 256x256? That's all the bigger the thumbnails need to be and I could make a duplicate function or an argument to fetch the full size artwork for displaying full screen.

Also, I'm displaying these Bitmaps on ImageViews that are small, around 150x150 to 200x200. The smaller images scale down nicer than the large ones do. Is there any way to apply a downscaling filter to smooth the image (anti-aliasing perhaps)? I don't want to cache a bunch of additional thumbnail files if I don't have to, because it would make managing the artwork images more difficult (currently you can just dump new ones in the directory and they will automatically be used next time they get loaded).

The full code is at http://github.org/CalcProgrammer1/CalcTunes, in src/com/calcprogrammer1/calctunes/AlbumArtManager.java, though there's not much different in the other function (which falls back to checking last.fm if the image is missing).

4

4 に答える 4

2

このプライベート関数を使用して、サムネイルに必要なサイズを設定します。

//decodes image and scales it to reduce memory consumption
public static Bitmap getScaledBitmap(String path, int newSize) {
    File image = new File(path);

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

    BitmapFactory.decodeFile(image.getPath(), options);
    if ((options.outWidth == -1) || (options.outHeight == -1))
        return null;

    int originalSize = (options.outHeight > options.outWidth) ? options.outHeight
            : options.outWidth;

    BitmapFactory.Options opts = new BitmapFactory.Options();
    opts.inSampleSize = originalSize / newSize;

    Bitmap scaledBitmap = BitmapFactory.decodeFile(image.getPath(), opts);

    return scaledBitmap;     
}
于 2013-05-05T06:04:13.513 に答える
0

これはdroidQueryで簡単に実行できます:

final ImageView image = (ImageView) findViewById(R.id.myImage);
$.ajax(new AjaxOptions(url).type("GET")
                           .dataType("image")
                           .imageHeight(256)//set the output height
                           .imageWidth(256)//set the output width
                           .context(this)
                           .success(new Function() {
                               @Override
                               public void invoke($ droidQuery, Object... params) {
                                   $.with(image).val((Bitmap) params[0]);
                               }
                           })
                           .error(new Function() {
                               @Override
                               public void invoke($ droidQuery, Object... params) {
                                   droidQuery.toast("could not set image", Toast.LENGTH_SHORT);
                               }
                           }));

cacheおよびcacheTimeoutメソッドを使用して応答をキャッシュすることもできます。

于 2013-07-17T03:32:25.933 に答える
0

これを行う 1 つの方法は、AQuery ライブラリです。

これは、ローカル ストレージまたは URL から画像を遅延読み込みできるライブラリです。キャッシングやダウンスケーリングなどをサポートしています。

ダウンスケーリングせずにリソースを遅延ロードする例:

AQuery aq = new AQuery(mContext);
aq.id(yourImageView).image(R.drawable.myimage);

ダウンスケーリングを使用して File オブジェクトに画像を遅延ロードする例:

    InputStream ins = getResources().openRawResource(R.drawable.myImage);
    BufferedReader br = new BufferedReader(new InputStreamReader(ins));
    StringBuffer sb;
    String line;
    while((line = br.readLine()) != null){
        sb.append(line);
        }

    File f = new File(sb.toString());

    AQuery aq = new AQuery(mContext);
    aq.id(yourImageView).image(f,350); //Where 350 is the width to downscale to

ローカル メモリ キャッシング、ローカル ストレージ キャッシング、およびサイズ変更を使用して URL からダウンロードする方法の例。

AQuery aq = new AQuery(mContext);
aq.id(yourImageView).image(myImageUrl, true, true, 250, 0, null);

これにより、 で画像の非同期ダウンロードが開始されmyImageUrl、幅が 250 にサイズ変更され、メモリとストレージにキャッシュされます。次に、 yourImageView. のイメージがmyImageUrl以前にダウンロードされてキャッシュされている場合は常に、このコード行は代わりにメモリまたはストレージにキャッシュされたイメージをロードします。

通常、これらのメソッドgetViewは、リスト アダプターのメソッドで呼び出されます。

AQuery の画像読み込み機能に関する完全なドキュメントについては、 ドキュメントを確認してください。

于 2013-05-05T06:41:43.327 に答える