【问题标题】:Resize Drawable in Android在 Android 中调整 Drawable 的大小
【发布时间】:2011-10-24 16:40:56
【问题描述】:

我正在为进度对话框 (pbarDialog) 设置可绘制对象,但我的问题是我想每次都调整可绘制对象的大小,但不知道怎么做。

这里有一些代码:

Handler progressHandler = new Handler() {

    public void handleMessage(Message msg) {
        switch (msg.what) {
            // some more code
            case UPDATE_PBAR:
                pbarDialog.setIcon(mAppIcon);
                pbarDialog.setMessage(mPbarMsg);
                pbarDialog.incrementProgressBy(mIncrement+1);
                break;
        }
    }
};

pbarDialog.show();

Thread myThread = new Thread(new Runnable() {

    public void run() {
        // some code
        for (int i = 0; i < mApps.size(); i++) {
            mAppIcon = mAdapter.getIcons().get(mApps.get(i).getPackageName());
            // need to resize drawable here
            progressHandler.sendEmptyMessage(UPDATE_PBAR);
        }
        handler.sendEmptyMessage(DISMISS_PBAR);
    }

});

myThread.start();

【问题讨论】:

  • 你必须调整哪个drawable的大小?
  • 使用 Bitmap.createScaledBitmap(src, dstWidth, dstHeight, filter)

标签: android image bitmap resize drawable


【解决方案1】:

以下内容对我有用:

private Drawable resize(Drawable image) {
    Bitmap b = ((BitmapDrawable)image).getBitmap();
    Bitmap bitmapResized = Bitmap.createScaledBitmap(b, 50, 50, false);
    return new BitmapDrawable(getResources(), bitmapResized);
}

【讨论】:

  • 我在第一行代码出现了这个错误:java.lang.ClassCastException: android.graphics.drawable.PictureDrawable cannot be cast to android.graphics.drawable.BitmapDrawable
  • 使用 Drawable 作为参数并将其转换为 BitmapDrawable !?如果您确定它始终是 BitmapDrawable,那么也将参数类型更改为 BitmapDrawable,如果不是,最好在转换之前检查可绘制类型。
【解决方案2】:

这就是我结束的地方,部分感谢 Saad 的回答:

public Drawable scaleImage (Drawable image, float scaleFactor) {

    if ((image == null) || !(image instanceof BitmapDrawable)) {
        return image;
    }

    Bitmap b = ((BitmapDrawable)image).getBitmap();

    int sizeX = Math.round(image.getIntrinsicWidth() * scaleFactor);
    int sizeY = Math.round(image.getIntrinsicHeight() * scaleFactor);

    Bitmap bitmapResized = Bitmap.createScaledBitmap(b, sizeX, sizeY, false);

    image = new BitmapDrawable(getResources(), bitmapResized);

    return image;

}

【讨论】:

  • 完美,这就是我走的路。
  • 不错的编码。正是我需要的。谢谢你,兄弟:)
  • 注意这一点:以前的可绘制“图像”包含尚未回收的位图。调用“image = scaleImage(image, 2)”会导致临时泄漏。因此 scaleImage 的调用者有责任回收原始图像和缩放后的图像......这在小型应用程序中可能不是问题,但它是在内存密集型应用中至关重要。
  • @JMLord 好点,更多内容在这里:developer.android.com/training/displaying-bitmaps/…
  • 任何可以避免内存泄漏的解决方案或替代方案
【解决方案3】:

对于调整大小,这很好而且很短(上面的代码对我不起作用),找到here

  ImageView iv = (ImageView) findViewById(R.id.imageView);
  Bitmap bMap = BitmapFactory.decodeResource(getResources(), R.drawable.picture);
  Bitmap bMapScaled = Bitmap.createScaledBitmap(bMap, newWidth, newHeight, true);
  iv.setImageBitmap(bMapScaled);

【讨论】:

  • 这适用于我想在将 Drawable 设置为 imageBitmap 到 ImageView 之前调整它的大小。谢谢
【解决方案4】:

这是上述答案的组合作为 Kotlin 扩展

fun Context.scaledDrawableResources(@DrawableRes id: Int, @DimenRes width: Int, @DimenRes height: Int): Drawable {
    val w = resources.getDimension(width).toInt()
    val h = resources.getDimension(height).toInt()
    return scaledDrawable(id, w, h)
}

fun Context.scaledDrawable(@DrawableRes id: Int, width: Int, height: Int): Drawable {
    val bmp = BitmapFactory.decodeResource(resources, id)
    val bmpScaled = Bitmap.createScaledBitmap(bmp, width, height, false)
    return BitmapDrawable(resources, bmpScaled)
}

用法:

val scaled = context.scaledDrawableResources(R.drawable.ic_whatever, R.dimen.width, R.dimen.height)
imageView.setImageDrawable(scaled)

val scaled = context.scaledDrawable(R.drawable.ic_whatever, 100, 50)
imageView.setImageDrawable(scaled)

【讨论】:

  • 这一款非常适合 Kotliner 同胞!
【解决方案5】:

也许我的解决方案没有完全涵盖这个问题,但我需要类似“CustomDrawable”的东西。

换句话说,我想在圆形前面设置一个标志。所以我创建了一个带有背景(只是一个彩色圆圈)的 FrameLayout,并在这个圆形的前面显示了徽标。

要调整徽标的大小,我通过缩放来缩小徽标 - 这是一些代码:

iv = new ImageView(mContext);

iv.setScaleX(0.75f); // <- resized by scaling 
iv.setScaleY(0.75f);

// loading the drawable from a getter (replace this with any drawable)
Drawable drawable = ML.loadIcon(mContext, Integer.parseInt(icon));

iv.setImageDrawable(drawable);

// icon get's shown inside a ListView
viewHolder.mIvIcon.addView(iv);

这是在 ListView 行内显示图标的 FrameLayout:

<FrameLayout
    android:id="@+id/iv_card_icon"
    android:layout_width="48dp"
    android:layout_height="48dp"
    android:src="@drawable/circle"
    android:layout_marginStart="16dp"
    />

将此解决方案视为一种选择/想法。

【讨论】:

    【解决方案6】:

    如果源 Drawable 不是 instanceof BitmapDrawable,那么投票最多的答案将不起作用,这可能是使用矢量、颜色可绘制对象等的情况......

    最合适的解决方案是把 Drawable 绘制到一个带有 set bitmap 的 Canvas 中,如下:

    @NonNull final Drawable drawable = yourSourceDrawable;
    
    // Define the Canvas and Bitmap the drawable will be drawn against
    final Canvas c = new Canvas();
    c.setBitmap(bitmap);
    
    // Draw the scaled drawable into the final bitmap
    if (yourSourceDrawable!= null) {
        yourSourceDrawable.setBounds(0, 0, newWidth, newHeight);
        yourSourceDrawable.draw(c);
    }
    

    奖励:计算要应用的比例(例如,将 Drawable 缩放到视图时):

    if (drawable != null && drawable.getIntrinsicWidth() > 0 && drawable.getIntrinsicHeight() > 0) {
        // the intrinsic dimensions can be -1 in some cases such as ColorDrawables which aim to fill 
        // the whole View
        previewWidth = drawable.getIntrinsicWidth();
        previewHeight = drawable.getIntrinsicHeight();
    }
    
    final float widthScale = mViewWidth / (float) (previewWidth);
    if (widthScale != 1f)
        newWidth = Math.max((int)(widthScale * previewWidth), 1);
    
    final float heightScale = mViewHeight / (float) (previewHeight);
    if (heightScale != 1f)
        newHeight = Math.max((int)(heightScale * previewHeight), 1);
    

    注意:始终在工作线程中执行此操作!

    【讨论】:

      【解决方案7】:

      科特林方式

      最终对我有用的是这个简单的解决方案

      fun resizeDrawable(width:Int, height:Int): Drawable {
              val drawable = ResourceUtils.getDrawable(R.drawable.ic_info)
              val bitmap = drawable.toBitmap(width, height) //here width and height are in px
              return bitmap.toDrawable(getResources())
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-10-08
        • 2013-07-04
        • 1970-01-01
        • 2012-02-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多