首页 > 其他分享 >WEBP中无损模式下的四种转换类型

WEBP中无损模式下的四种转换类型

时间:2024-11-20 09:46:35浏览次数:3  
标签:blue 颜色 uint8 像素 WEBP red 转换 无损 四种

四种转换类型应用于对图像数据熵编码之前,通过对空间和颜色相关性进行建模来降低图像数据的熵。
一张图片可以进行四种类型的转换,每个转换最多只能使用一次。

while (ReadBits(1)) {  // Transform present.  
// Decode transform type.  
enum TransformType transform_type = ReadBits(2);  
// Decode transform data.  
...}
// Decode actual image data (Section 5).

如果存在转换,则后两位指定转换类型。

enum TransformType {  
PREDICTOR_TRANSFORM             = 0,  
COLOR_TRANSFORM                 = 1,  
SUBTRACT_GREEN_TRANSFORM        = 2,  
COLOR_INDEXING_TRANSFORM        = 3,};

转换数据紧接着跟在转换类型之后
四种转换分别为:预测转换颜色转换减绿色转换颜色索引转换
下面将一一介绍。

1. 预测转换

预测转换的转换数据在WEBP中被称为“预测器图片”。其实可以视为将实际的图像数据按照区块(区块为正方形,并且所有区块的宽高相同)划分,并将区块视为一个像素点,这些像素点组成的图像即为预测器图,但是图片的颜色通道(绿色通道)存放的是该像素点对应区块所使用的预测模式。预测模式共有14种

预测转换的转换数据的前3位定义区块宽度和高度。
若当前待预测转换的像素为P,如下所示:

O    O    O    O    O    O    O    O    O    O    O                                O    O    O    O    O    O    O    O    O    O    O                               O    O    O    O    TL   T    TR   O    O    O    O                               O    O    O    O    L    P    X    X    X    X    X                               X    X    X    X    X    X    X    X    X    X    X                               X    X    X    X    X    X    X    X    X    X    X

其中 TL 表示左上角、T 表示上方、TR 表示右上角,L 表示左侧。在 预测 P 值的时候,所有 0、TL、T、TR 和 L 像素都已知, P 像素和 X 像素未知。
14种预测模式的定义如下.

ModePredicted value of each channel of the current pixel
00xff000000 (表示 ARGB 中的纯黑色)
1L
2T
3TR
4TL
5Average2(Average2(L, TR), T)
6Average2(L, TL)
7Average2(L, T)
8Average2(TL, T)
9Average2(T, TR)
10Average2(Average2(L, TL), Average2(T, TR))
11Select(L, T, TL)
12ClampAddSubtractFull(L, T, TL)
13ClampAddSubtractHalf(Average2(L, T), TL)
uint8 Average2(uint8 a, uint8 b) {  
return (a + b) / 2;
}
// Clamp the input value between 0 and 255.
int Clamp(int a) {
  return (a < 0) ? 0 : (a > 255) ? 255 : a;
}
int ClampAddSubtractFull(int a, int b, int c) {
  return Clamp(a + b - c);
}
int ClampAddSubtractHalf(int a, int b) {
  return Clamp(a + (a - b) / 2);
}

图片左上方像素预测为0xff000000,最上一行像素预测值均为L,最左列的像素预测值为T。
最右列的像素按照设定的预测模式进行预测,但是将当前行最左侧的像素视为TR像素的替代。

2. 颜色转换

关于分块等思路与预测器转换相同,对块中的所有像素使用相同的转换模式,对于 每个块均有三种类型的颜色转换元素。每个块对应颜色转换图中一个像素点,该像素点的三个通道分别储存三种颜色转换元素的值。

typedef struct {
  uint8 green_to_red;
  uint8 green_to_blue;
  uint8 red_to_blue;
} ColorTransformElement;

颜色转换是通过改变每个像素的红蓝通道的值来减少颜色相关性。

void ColorTransform(uint8 red, uint8 blue, uint8 green,
                    ColorTransformElement *trans,
                    uint8 *new_red, uint8 *new_blue) {
  // Transformed values of red and blue components
  int tmp_red = red;
  int tmp_blue = blue;

  // Applying the transform is just subtracting the transform deltas
  tmp_red  -= ColorTransformDelta(trans->green_to_red,  green);
  tmp_blue -= ColorTransformDelta(trans->green_to_blue, green);
  tmp_blue -= ColorTransformDelta(trans->red_to_blue, red);

  *new_red = tmp_red & 0xff;
  *new_blue = tmp_blue & 0xff;
}

int8 ColorTransformDelta(int8 t, int8 c) {
  return (t * c) >> 5;
}

3. 减绿色转换

减绿色转换没有跟随着的转换数据,它仅仅是从每个像素的红色和蓝色值中减去绿色值。

减绿色转换可以使用2中提到的颜色转换来实现,但是由于减绿色转换较为简单,单独使用时比以特殊的颜色转换来替代可以使用更少的位数来对转换模式及数据进行编码。

void AddGreenToBlueAndRed(uint8 green, uint8 *red, uint8 *blue) {
  *red  = (*red  + green) & 0xff;
  *blue = (*blue + green) & 0xff;
}

4. 颜色索引转换

如果图片像素值有限,那么创建颜色索引数组,使用数组的索引替换像素值将对编码十分有效。

颜色索引转换的工作原理
  1. 唯一值检测

    • 颜色索引转换首先检查图像中唯一的 ARGB 值的数量。
    • 如果该数量低于阈值(256),就会创建一个包含这些 ARGB 值的数组。
  2. 颜色表的构建和使用

    • 将图像中的像素值替换为颜色表中的对应索引:(为什么还保留其他通道?)
      • 替换后的像素的绿色通道保存索引值。
      • 所有的 Alpha 通道值设为 255。
      • 所有的红色和蓝色通道值设为 0。
  3. 传输的数据内容

    • 转换数据包含颜色表的大小和条目。

    • 解码时,通过以下方式读取颜色表:

      • 颜色表大小:存储为 8 位值。

      int color_table_size = ReadBits(8) + 1;

      • 颜色表内容
        • 颜色表使用图像的存储格式存储(省略 RIFF 头、图像大小和其他转换)。
        • 颜色表的高度设为 1 像素,宽度为 color_table_size
        • 使用"减法编码" (subtraction coding) 存储,以降低表的熵(信息复杂性)。
  4. 减法编码(Subtraction Coding)

    • 减少颜色表中的熵,通过对每个 ARGB 分量的当前值与前一个值的差进行存储。
    • 解码时,通过加回前一个颜色分量的值重建最终的颜色表。
  5. 逆变换(Inverse Transform)

    • 在解码时,将像素值(即索引)替换为颜色表中的实际颜色值:

    argb = color_table[GREEN(argb)];

    • 如果索引值大于或等于颜色表的大小,则像素值设为透明黑色 (0x00000000)。
像素捆绑(Pixel Bundling)

当颜色表很小(16 个颜色或更少)时,可以将多个像素打包成一个像素,进一步提高编码效率。

  1. 捆绑规则

    • 如果颜色表的大小 color_table_size ≤ 16,可以打包多个像素:
      • 2 像素打包为 1 像素(width_bits = 1)。
      • 4 像素打包为 1 像素(width_bits = 2)。
      • 8 像素打包为 1 像素(width_bits = 3)。
    • 捆绑后,图像宽度会相应减少。
  2. 数据打包方式

    • 绿色通道存储索引值,根据 width_bits 的值,将多个像素的索引打包到一个绿色通道中。例如:
      • width_bits = 1:每个绿色值的低 4 位存储第一个索引,高 4 位存储第二个索引。
      • width_bits = 2:每个绿色值的低 2 位存储第一个索引,其余位依次存储后续索引。
  3. 图像宽度的更新

    • 捆绑完成后,图像宽度按以下公式更新:

    image_width = DIV_ROUND_UP(image_width, 1 << width_bits);

标签:blue,颜色,uint8,像素,WEBP,red,转换,无损,四种
From: https://blog.csdn.net/m0_47623965/article/details/143838805

相关文章

  • RabbitMQ的五种模式和四种交换机
    六种消息模式而在的RabbitMQ中,出现了六种消息传播模式:RabbitMQ官网说明的六种模式SimpleWorkQueue(简单工作队列):也就是常说的点对点模式,一条消息由一个消费者进行消费。(当有多个消费者时,默认使用轮训机制把消息分配给消费者)。WorkQueues(工作队列):也叫公平队列,能者多劳......
  • 免费下载无损歌曲网站
    免费下载无损歌曲网站1、MyFreeMP3网址:http://tool.liumingye.cn/music/?page=searchPage一个可以免费下载无损音乐的网站,涵盖了海量的MP3歌曲,页面干净无广告,支持离线使用。打开页面可以看到当下流行的音乐单曲,还支持强大的音乐搜索功能,下载方式简单,每首歌曲都提供了下载按......
  • 小米笔记本Pro15锐龙版(R7 5800H/15G RAM/512G SSD)拆机单固态硬盘SSD扩容,无损迁移Win
    1.准备工作1.1梅花头螺丝刀2.72米 1.2新的固态硬盘三星980nvmem2固态硬盘,官方说读取速度能到3.5G,实测能到3.3G。小米笔记本Pro15锐龙版的M.2插槽支持的是PCIE3.0,三星980支持的就是PCIE3.0,够用了。三星980Pro支持的是PCIE4.0,读取能到7G,但接口不支持,只能降到PCIE......
  • 7.Java 注解和元注解(三种注解、四种元注解)
    一、注解概述注解也被称为元数据,用于修饰包、类、方法等数据信息和注释一样,注解不影响程序逻辑,但注解可以被编译或运行,相当于嵌入在代码中的补充信息在JavaSE中,注解使用的目的比较简单,例如标记过时的功能,忽略警告等JavaEE中注解会充当更加重要的角色二、三种注......
  • new webpack.ProvidePlugin({ Buffer: ['buffer', 'Buffer'], }),
    在Webpack配置中,ProvidePlugin是一个非常有用的插件,它可以自动向模块中注入特定的变量,而无需在每个模块中显式导入这些变量。你提到的配置片段使用了ProvidePlugin来注入Buffer和process对象。下面是对这段代码的详细解释:代码解析newwebpack.ProvidePlugin({Buffer......
  • chainWebpack: config => { // 移除 preload(预载) 插件 config.plugins.dele
    在VueCLI项目中,chainWebpack是一个用于自定义Webpack配置的钩子。通过chainWebpack,你可以对Webpack配置进行更细粒度的控制。你提到的代码片段的作用是移除preload和prefetch插件。下面是对这段代码的详细解释:代码解析chainWebpack:config=>{//移除preload......
  • 2024 同一个网段,反弹shell四种方法【linux版本】bash、python、nc、villian反弹shell
    实验环境准备(同一个网段下,我是桥接的虚拟机)一、bash反弹shell二、python反弹shell三、nc反弹shell四、villain反弹shell实验环境准备(同一个网段下,我是桥接的虚拟机)      一台kali的linux(攻击者)        一台centos7/debian[另一个linux](受害者)一、b......
  • 【划重点】一文搞懂Webpack环境区分配置(12)
    在实际开发中,我们经常需要针对生产环境和开发环境分别书写webpack配置。为了更好地适应这种需求,webpack允许配置不仅可以是一个对象,还可以是一个函数。这样,开发者可以根据不同的环境返回不同的配置对象。1.使用函数作为配置module.exports=env=>{return{......
  • libwebp在windows下构建及编译运行
    因为正在进行WEBP图像的学习,因此有必要对WEBP的官方实现——libwebp进行本地构建和编译,以方便对标准及代码的理解。下面记录一下,在本地Windows电脑上,构建并编译libwebp的过程。步骤一:下载源码首先,获取libwebp的最新源码:从官方Git仓库克隆:gitclonehttps://chromium......
  • C盘满了,C盘无损扩容,简单实现
    C盘爆满原因很多,无外乎当年固态硬盘贵,C盘分区过小,或者装系统时无意把分区分的太小,这就造成了一个困扰,C盘满了,变成红色,造成软件无法运行,电脑无法启动。如果重新分区,电脑上的资料就没了,所以今天就来介绍一款不用重装系统,扩充C盘容量的方法,操作非常简单,完全就是傻瓜式的。第一......