Android中的抖动解码(inDither)

本文详细介绍了Android中BitmapFactory.Options的inDither属性作用,即抖动解码技术。通过对比展示,阐述了在颜色模式较低时,如何利用抖动解码减少图像中的断裂色带现象,提高图片质量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在Android中的BitmapFactory.Options中有一个属性值是inDither,这个值表示是否采用抖动解码,那什么叫抖动解码呢,今天我们就来详细解说一下。


Bitmap的解码是根据它所记录的节点,依照一定算法,来补充两个节点之间的数据,可以理解为补充其中像素点的颜色,那么在解码的时候肯定会和当前所采用的颜色模式有关,很直观的说,采用32位的肯定比16位的颜色要多,自然展现的图像会看起来更好。


如果一张颜色很丰富的图,用一个位数比较低的颜色模式来解码的话,那么一个直观的感觉就是颜色不够用,那么这张图解出来之后,在一些颜色渐变的区域上就会有一些很明显的断裂色带,这个很好解释,因为一些丰富的颜色在位数较低的颜色模式下并没有,那么只能用相近的填充,可能一大片都没有,那么一大片都用这一个颜色填充,就形成了断裂色带。


如果采用抖动解码,那么就会在这些色带上采用随机噪声色来填充,目的是让这张图显示效果更好,色带不那么明显。


看下面的例子:


很明显,左边的更平滑一点,右边的会有一些色带,如果不想有这些色带,那么就需要采用抖动解码。

Android 中将 byte[] 类型的图片数据压缩通常是为了减少存储空间或在网络传输中减小数据量。你可以使用 Java 的 BitmapFactory 或者第三方库如 CompressingBitmapUtils、Glide 或 Picasso 来实现这个功能。下面是简要步骤: 1. 首先,创建一个 BitmapFactory.Options 对象,设置需要的解码参数,如 inJustDecodeBounds 参数用于获取原图尺寸以便调整压缩比例。 ```java BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; ``` 2. 使用原图的 bounds 获取合适的压缩质量(quality)或宽度高度比(inSampleSize),这取决于需求。例如,设置合适的压缩比率: ```java int targetWidth = ...; // 目标宽度 int targetHeight = ...; // 目标高度 options.inSampleSize = calculateInSampleSize(options, targetWidth, targetHeight); ``` 3. 再次创建 BitmapFactory.Options 并去掉 inJustDecodeBounds 参数,然后用压缩后的尺寸解析图片数据: ```java options.inJustDecodeBounds = false; options.inDither = false; // 可选,减少颜色抖动 options.inPreferredConfig = Bitmap.Config.ARGB_8888; // 配置位图格式 // 如果图片过大,这里需要创建一个新的 bitmap if (options.outWidth > targetWidth || options.outHeight > targetHeight) { options.inMutable = true; // 允许修改原始字节数组 byte[] compressedData = compressByteArray(options, byteArray); // 然后可以使用 BitmapFactory.decodeByteArray 创建新的 Bitmap Bitmap compressedBitmap = BitmapFactory.decodeByteArray(compressedData, 0, compressedData.length, options); } else { Bitmap compressedBitmap = BitmapFactory.decodeByteArray(byteArray, 0, byteArray.length, options); } ``` 4. `compressByteArray` 函数是一个自定义函数,可以使用像 ZLib 或 NineOldAndroids 这样的库来进行实际的数据压缩,将 byte[] 缩小到目标大小: ```java public static byte[] compressByteArray(BitmapFactory.Options options, byte[] data) { ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); try { if (options.inPreferredConfig != Bitmap.Config.RGB_565) { // 如果不需要转换格式,则无需再进行 Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length, options); bitmap.compress(Bitmap.CompressFormat.JPEG, 75, outputStream); // 设置压缩质量 } else { outputStream.write(data); } } catch (Exception e) { Log.e("Error", "Failed to compress image"); } return outputStream.toByteArray(); } ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值