【问题标题】:createBitmap() returns a bitmap without drawncreateBitmap() 返回未绘制的位图
【发布时间】:2014-05-03 10:46:40
【问题描述】:

我想缩放现有位图。所以我使用 Bitmap.createBitmap(Bitmap b, int x, int y, int width, int height, Matrix m, boolean filter) 创建一个缩放位图。如果 Matrix 对象的缩放比例小于 1,则此方法效果很好。但是,如果比率等于或大于 1,则该方法返回一个具有我想要的宽度和高度但没有图像(透明)的位图。我想知道为什么以及如何解决这个问题。

    Bitmap imageBitmap;
    imageBitmap = weiboView.getDrawingCache();
    Log.d("cosmo", "bitmap generated: "+imageBitmap.getWidth()+" * "+imageBitmap.getHeight());

    //Init and configure and load the image view
    ImageView imageView = new ImageView(this);
    imageView.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
    imageView.setScaleType(ScaleType.FIT_CENTER);
    containerLayout.addView(imageView);

    //create a scaled bitmap to assign to the image view
    Bitmap scaledImageBitmap = MyBitmapUtils.getBitmapScaledToFitWidth(getWindowManager().getDefaultDisplay().getWidth(), imageBitmap);
    Log.d("cosmo", "scaled: "+scaledImageBitmap.getWidth()+" * "+scaledImageBitmap.getHeight());
    //Here if I set imageBitmap as the image of imageView it works well
    imageView.setImageBitmap(scaledImageBitmap);

这里是 MyBitmapUtils.getBitmapScaledToFitWidth:

public static Bitmap getBitmapScaledToFitWidth(int targetWidth, Bitmap bitmap) {
    float ratio = (float)targetWidth/(float)bitmap.getWidth();
    Log.d("cosmo", "ratio is "+ratio);
    //ratio = 0.5f;
    Matrix matrix = new Matrix();
    matrix.postScale(ratio, ratio);
    Bitmap target = Bitmap.createBitmap(bitmap,0,0,bitmap.getWidth(),bitmap.getHeight(),matrix,false);
    return target;
}

我知道这是怎么发生的。因为Image的高度大于2048,在android系统中创建大于2048*2048的位图会导致OOM(我的logcat没有报这个错误,奇怪)

【问题讨论】:

  • 为什么需要缩放位图?你想把它保存在 SD 卡上还是发送到某个地方?
  • 只是想缩放它以适应具有指定宽度的图像视图
  • 不,不,不,不要那样做,使用 scaleType="matrix" 并调用 setImageMatrix,或使用任何其他保留 scaleType 的纵横比

标签: android bitmap


【解决方案1】:

你为什么不直接使用createScaledBitmap

Bitmap scaledBitmap = Bitmap.createScaledBitmap(bitmap, targetWidth, targetHeight, true);

您可以直接提供 targetWidth 和 targetHeight,它应该比使用 Matrix 自己缩放位图更可靠。

如果您只是将 targetWidth 提供给您的方法,那么您必须计算 targetHeight,它看起来像这样:

float ratio = (float)targetWidth/(float)bitmap.getWidth();
int targetHeight = (int)((float)bitmap.getHeight * ratio);

如果你把它放在你的方法中,它会是这样的:

public static Bitmap getBitmapScaledToFitWidth(double targetWidth, Bitmap bitmap) {
    double bitmapWidth = bitmap.getWidth();
    double bitmapHeight = bitmap.getHeight();

    double widthRatio = targetWidth / bitmapWidth;
    double targetHeight = widthRatio * bitmapHeight;

    Bitmap target = Bitmap.createScaledBitmap(bitmap, (int)targetWidth, (int)targetHeight, true);
    return target;
}

也不要忘记尽快recycle() 不需要的位图。这可以防止您遇到内存问题,例如,如果您在缩放后不再需要未缩放的位图,您可以直接在您的辅助方法中回收它:

public static Bitmap getBitmapScaledToFitWidth(double targetWidth, Bitmap bitmap) {
    double bitmapWidth = bitmap.getWidth();
    double bitmapHeight = bitmap.getHeight();

    double widthRatio = targetWidth / bitmapWidth;
    double targetHeight = widthRatio * bitmapHeight;

    Bitmap target = Bitmap.createScaledBitmap(bitmap, (int)targetWidth, (int)targetHeight, true);

    // Recycle old bitmap to free up memory.
    bitmap.recycle();

    return target;
}

【讨论】:

  • 嗯..我不知道那种方法。我会考虑使用它。
  • 这可能与您的Matrix 有关。尝试在不调用postScale(...) 的情况下创建Bitmap。位图不会被缩放,但如果它显示正确,你就知道这是postScale(...)的错。
  • createScaledBitmap(...)createBitmap(...) 的结果相同?你确定原始位图没问题吗?尝试在不缩放的情况下显示它。
  • 我的意思是方法 createScaledBitmap 失败
  • 我已经尝试显示原始位图,我确定没问题
猜你喜欢
  • 2013-11-21
  • 1970-01-01
  • 1970-01-01
  • 2015-08-30
  • 2021-11-20
  • 2015-02-09
  • 1970-01-01
  • 2015-08-13
  • 1970-01-01
相关资源
最近更新 更多