【问题标题】:Android - Trying to display bitmaps efficiently for wallpaper app which are currently 0.5MB in size eachAndroid - 尝试为当前大小为 0.5MB 的壁纸应用程序有效地显示位图
【发布时间】:2014-09-21 05:17:49
【问题描述】:

更新

我正在尝试为一个拥有 50 张壁纸的壁纸应用程序有效地显示位图。

我使用的图像每个 400kb @ 1080x1920

我已经研究并阅读了我应该在应用加载时将每个壁纸的缩小版本加载到内存中,而不是在按下每个壁纸时加载它。

我读过这个http://developer.android.com/training/displaying-bitmaps/load-bitmap.html#read-bitmap

如何使用我当前的代码实现这一点?我从 YouTube 上的本教程获得了这里 http://www.youtube.com/watch?v=SxGYGYBFrOM

这是更新后的代码,我包含了整个 MainActivity 类

package com.example.ultimateabstractwallpaperhd;

import java.io.IOException;

public class MainActivity extends Activity implements OnClickListener {
// Two classes you mentioned I put here.

ImageView display;
int toPhone;

@Override
protected void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);
    // check if next two lines are necessary
    requestWindowFeature(Window.FEATURE_NO_TITLE); // gets rid of app title
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,       WindowManager.LayoutParams.FLAG_FULLSCREEN);

    if (android.os.Build.VERSION.SDK_INT>=11) {
           getWindow().setFlags(
                WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
                WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
        }

    setContentView(R.layout.wallpaper);
    toPhone = R.drawable.one;

display = (ImageView) findViewById(R.id.IVdisplay);
ImageView one = (ImageView) findViewById(R.id.IVimage1);
ImageView two = (ImageView) findViewById(R.id.IVimage2);
ImageView three = (ImageView) findViewById(R.id.IVimage3);
ImageView four = (ImageView) findViewById(R.id.IVimage4);
ImageView five = (ImageView) findViewById(R.id.IVimage5);
Button setWall = (Button) findViewById(R.id.BsetWallpaper);


one.setOnClickListener(this);
two.setOnClickListener(this);
three.setOnClickListener(this);
four.setOnClickListener(this);
five.setOnClickListener(this);
setWall.setOnClickListener(this);

}

@Override
public void onClick(View v) {
    // TODO Auto-generated method stub
    switch (v.getId()){
    case R.id.IVimage1:
        display.setImageResource(R.drawable.one);
        toPhone = R.drawable.one;
        break;
    case R.id.IVimage2:
        display.setImageResource(R.drawable.two);
        toPhone = R.drawable.two;
        break;
    case R.id.IVimage3:
        display.setImageResource(R.drawable.three);
        toPhone = R.drawable.three;
        break;
    case R.id.IVimage4:
        display.setImageResource(R.drawable.four);
        toPhone = R.drawable.four;
        break;
    case R.id.IVimage5:
        display.setImageResource(R.drawable.five);
        toPhone = R.drawable.five;
        break;

    case R.id.BsetWallpaper:
        InputStream yeaaaa  = getResources().openRawResource(toPhone);

        Bitmap whatever = decodeSampledBitmapFromResource(getResources(), R.id.IVimage1, 1080, 1500)

        try {
            getApplicationContext().setWallpaper(whatever);
        }catch(IOException e){
            e.printStackTrace();
        }
        break;

    }
}

}

编辑:

好的,我的资源在 drawable-hpdi 文件夹中。

我仍然有一些错误,eclipse 已经标记了这些错误。我把它们加粗了。

1)

public static Bitmap decodeSampledBitmapFromResource(**Resources** res, int resId,
int reqWidth, int reqHeight) {

Eclipse 解释:说资源无法解析为类型

2)

int resId = getResources().**getIdentifier**(R.drawable.one, "drawable", getPackageName());
        Bitmap whatever = **decodeSampledBitmapFromResource**(getResources(), R.id.IVimage1, 1080, 1500);

Eclipse 解释:

方法 getIdentifier 不适用于参数列表(对不起,如果我简单地错误地引用了可绘制对象)

MainActivity 类型的方法 decodeSampledBitmapFromResource 引用缺失的类型资源。

非常感谢您迄今为止的帮助,能得到如此快速的回复真是太好了。

编辑

资源名称:多个资源,命名为一、二、三、四、五,均带有 jpg 扩展名。

资源位置: res/drawable-hdpi/one.jpg res/drawable-hdpi/two.jpg .. res/drawable-hdpi/two.jpg

【问题讨论】:

    标签: android eclipse caching memory bitmap


    【解决方案1】:

    替代答案:

    InputStream yeaaaa  = getResources().openRawResource(toPhone)
    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inSampleSize = 2; \\1 would be the full resolution, 2 is half the size, 4 a quarter etc..
    Bitmap whatever = BitmapFactory.decodeStream(inputStream, null, options);
    

    【讨论】:

    • 啊!它工作得很好。我不想这么说,但我没有问正确的问题。目前您给我的精彩帮助意味着设置壁纸后,它以(1/x)*原始分辨率显示。我应该问的是如何在应用程序中以较低的分辨率显示图像以及如何有效地做到这一点(比如在启动时加载所有图像),这样在使用应用程序时就没有延迟。我很抱歉在这方面没有直接。任何想法将不胜感激。
    • ?? “我应该怎么做”??应该怎么做?
    • 您应该考虑将图像解码移动到 AsyncTask:developer.android.com/training/displaying-bitmaps/… 以帮助释放应用程序的 UI。上面的答案向您展示了如何下采样.. inSampleSize。请支持我的答案并接受一个作为答案。我为代表点工作:)
    【解决方案2】:

    因此,如果您查看您提到的文档,您想在您的类中创建这两个方法:

       public static int calculateInSampleSize(
                    BitmapFactory.Options options, int reqWidth, int reqHeight) {
            // Raw height and width of image
            final int height = options.outHeight;
            final int width = options.outWidth;
            int inSampleSize = 1;
    
            if (height > reqHeight || width > reqWidth) {
    
                final int halfHeight = height / 2;
                final int halfWidth = width / 2;
    
                // Calculate the largest inSampleSize value that is a power of 2 and keeps both
                // height and width larger than the requested height and width.
                while ((halfHeight / inSampleSize) > reqHeight
                        && (halfWidth / inSampleSize) > reqWidth) {
                    inSampleSize *= 2;
                }
            }
    
            return inSampleSize;
        }
    
    public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
            int reqWidth, int reqHeight) {
    
        // First decode with inJustDecodeBounds=true to check dimensions
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeResource(res, resId, options);
    
        // Calculate inSampleSize
        options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
    
        // Decode bitmap with inSampleSize set
        options.inJustDecodeBounds = false;
        return BitmapFactory.decodeResource(res, resId, options);
    }
    

    然后代替:

    Bitmap whatever = BitmapFactory.decodeStream(yeaaaa);
    

    使用

    Bitmap whatever = decodeSampledBitmapFromResource(getResources(), resourceID, width, height)
    

    不要将资源放在 raw 中,把它放在你的 drawables 文件夹中,这样你就可以使用资源 ID

    你可以像这样获取resourceID:

    getResources().getIdentifier([what ever your named your drawable] , "drawable", getPackageName());
    

    编辑

    根据您调整后的代码,需要注意一些事项..

    看起来您传递的是 ImageView 而不是位图的实际资源..

    这一行:

     Bitmap whatever = decodeSampledBitmapFromResource(getResources(), R.id.IVimage1, 1080, 1500)
    

    应该是:

    int resId = getResources().getIdentifier([what ever your named your drawable] , "drawable", getPackageName());
    
     Bitmap whatever = decodeSampledBitmapFromResource(getResources(), resId, 1080, 1500)
    

    【讨论】:

    • 啊,好吧,现在问题是因为我有这段代码(如下),每次按下图像时,resourceID 都会发生变化。
    • 我在关于如何从可绘制文件夹中获取资源 ID 的答案中添加了一行代码
    • 啊,好吧,现在是因为我有这段代码(如下),每次按下图像时,resourceID 都会发生变化。 (this) 是我用来更改它的变量。另外,我收到一条错误消息,说资源无法解析为类型。感谢您的快速回复!!非常感谢。
    • 你能更新你的代码,这样我才能更好地理解你在说什么
    • 添加了您的建议,但仍然无法正常工作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-18
    • 1970-01-01
    相关资源
    最近更新 更多