【问题标题】:difference between methods to scale a bitmap缩放位图的方法之间的区别
【发布时间】:2023-03-05 20:09:01
【问题描述】:

在Android中至少有两种缩放位图的方法, 一种是在解码位图源时使用“BitmapFactory.Options”中的“inScaled, inDensity, inTargetDensity”。 另一种是在“Bitmap.createBitmap”中使用“矩阵”。

我很好奇这两种方法有什么区别? 生成的位图质量如何?那么内存使用情况呢? 等等……

【问题讨论】:

    标签: android matrix bitmap scale


    【解决方案1】:

    BitmapFactory 与适当的inScale 选项一起使用将比使用Bitmap.createScaledBitmap()Bitmap.createBitmap() 与矩阵比例更节省内存。但是,它更复杂。

    查看How do I scale a streaming bitmap in-place without reading the whole image first?了解详情。

    【讨论】:

      【解决方案2】:

      我发现的一个区别是使用 BitmapFactory 的 options.inSampleSize 来缩放位图并不那么精细,因为比例将是 1/inSampleSize,并且因为 inSampleSize 必须是整数,所以您最终会像 1 一样缩放/2、1/3、1/4 等,但没有比这更精细的了。

      Bitmap.createScaledBitmap() 虽然占用更多内存,但允许更精细的缩放,分辨率最高可达 1dp。

      【讨论】:

      • 您忘记了允许细粒度缩放的 inScaled + inDensity + inTargetDensity 方法。您只需要知道缩放幅度并使用 inSampleSize。
      【解决方案3】:

      没有“大”的区别。虽然,使用BitmapFactory.Options 的一个好处是您可以检查Bitmap 的宽度/高度,而无需为实际Bitmap 的像素分配内存。

      此外,您还可以轻松查看 options BitmapFactory.Options 拥有的名称,并将其与 Bitmap.createBitmap() 进行比较。总的来说,BitmapFactory.Options 就像一个“工具”API,用于简化对Bitmaps 的解码和采样。

      【讨论】:

        【解决方案4】:

        使用Bitmap.createBitmap () 比使用Bitmap.createScaledBitmap () 更快。

        使用Bitmap.createBitmap ()我们已经通过了位图创建设置,而使用Bitmap.createScaledBitmap ()动态计算高度和宽度。

        看例子:

        /**
         * Return a [Bitmap] representation of this [Drawable].
         *
         * If this instance is a [BitmapDrawable] and the [width], [height], and [config] match, the
         * underlying [Bitmap] instance will be returned directly. If any of those three properties differ
         * then a new [Bitmap] is created. For all other [Drawable] types, a new [Bitmap] is created.
         *
         * @param width Width of the desired bitmap. Defaults to [Drawable.getIntrinsicWidth].
         * @param height Height of the desired bitmap. Defaults to [Drawable.getIntrinsicHeight].
         * @param config Bitmap config of the desired bitmap. Null attempts to use the native config, if
         * any. Defaults to [Config.ARGB_8888] otherwise.
         */
        fun Drawable.toBitmap(
            @Px width: Int = intrinsicWidth,
            @Px height: Int = intrinsicHeight,
            config: Config? = null
        ): Bitmap {
            if (this is BitmapDrawable) {
                if (config == null || bitmap.config == config) {
                    // Fast-path to return original. Bitmap.createScaledBitmap will do this check, but it
                    // involves allocation and two jumps into native code so we perform the check ourselves.
                    if (width == intrinsicWidth && height == intrinsicHeight) {
                        return bitmap
                    }
                    return Bitmap.createScaledBitmap(bitmap, width, height, true)
                }
            }
        
            val (oldLeft, oldTop, oldRight, oldBottom) = bounds
        
            val bitmap = Bitmap.createBitmap(width, height, config ?: Config.ARGB_8888)
            setBounds(0, 0, width, height)
            draw(Canvas(bitmap))
        
            setBounds(oldLeft, oldTop, oldRight, oldBottom)
            return bitmap
        }
        

        Source

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-08-14
          • 1970-01-01
          • 1970-01-01
          • 2014-02-04
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多