jpeg - 需要有关 BMP 到 JPEG 转换的帮助

标签 jpeg bmp huffman-code dct

我正在编写一个 C++ 程序来将 BMP 图像转换为 JPEG。

这是我试图遵循的基本算法:

  • 将 RGB 颜色空间转换为 Y,Cb,Cr..
  • 对 Cb 和 Cr 进行 2 次下采样(这意味着对于每个 2*2 的正方形块,有 4 个不同的 Y 值,但有 1 个 Cb 和 1 个 Cr 值
  • 对每个 8*8 像素的数据单元应用 DCT...
  • 然后使用 Cb 和 Cr 的标准量化表对 DCT 系数进行量化。
  • 做锯齿形排序。
  • 使用霍夫曼编码分别对 DC 和 AC 系数进行编码。
  • 写入正确的 header 并将霍夫曼编码的值写入文件...

  • 我已经确认我正确地执行了上述操作,但我仍然遇到以下问题:
  • 生成的 JPEG 显示不正确。
  • 我制作了一个小的 8*8 24 位(颜色深度)bmp 文件,完全填充了颜色值 R=10 B=10 和 G=100...所有 64 个像素都是相同的颜色..
  • 我每一步得到的数据如下...
  • BMP header 大小为 40
  • 标题的大小 40
  • 宽度 8
  • 高度 8
  • 飞机数 1
  • 每像素位数 24
  • 图像大小 194
  • x 每米分辨率像素 2834
  • y 每米分辨率像素 2834
  • 颜色数 0
  • 小鬼颜色数 0
  • (R,B,G)=(10,10,100) 的 Y Cb Cr 转换为 (62,-29,-37)

  • 所以让我们首先考虑 Y 分量。

    Y 分量的 DCT 系数为:
     495 0 0 0 0 0 0 0
     0 0 0 0 0 0 0 0
     0 0 0 0 0 0 0 0
     0 0 0 0 0 0 0 0
     0 0 0 0 0 0 0 0
     0 0 0 0 0 0 0 0
     0 0 0 0 0 0 0 0
     0 0 0 0 0 0 0 0
    

    在量化之后,对于 Y 分量,我得到的单个数据单元的锯齿形排序是这样的。
    30 0 0 0 0 0 0 0 0 0 0 0 0 0
    0 0 0 0 0 0 0 0 0 0 0 0 0
    0 0 0 0 0 0 0 0 0 0 0 0 0
    0 0 0 0 0 0 0 0 0 0 0 0 0
    0 0 0 0 0 0 0 0 0 0 0
    

    现在上面锯齿形顺序数组的霍夫曼编码是:
  • Y dc 编码:00111110
  • Y ac 编码:1010(对于 ac 霍夫曼表(亮度 Y)EOB 值为 1010)
  • Cb 和 Cr 分量的类似霍夫曼编码如下:
  • cb dc 编码:11000010
  • cb ac coding: 01 (ac huffman table(chrominance Cb,Cr) EOB值为01)
  • cr dc 编码:110101110
  • cr ac 编码:01
  • 我得到的最终霍夫曼代码是:

    001111101010110000100111010111001 长度 33

  • 所以为了使它能被 8 整除,填充 1 就完成了。
    0011111010101100001001110101110011111111 Length 40.
    

    这里每一个 0 或 1 实际上是需要存储在 JPEG 文件中的一个位,但由于我们无法逐位写入文件,因此总共取 8 位并转换为 base 中的整数值10 并存储为 1 个字节的字符。

    任何人都可以提供有关我哪里出错的任何建议吗?

    最佳答案

    解决您的问题要做的第一件事是获取有关 JPEG 标准的 Pennebaker/Mitchel 书。

    操作顺序为:

    1) 色彩空间转换
    2)FDCT
    3) 量化
    4) 之字形重新排序
    5) 霍夫曼编码

    由于您必须遵循许多规则,因此这些操作具有许多复杂性。

    a) 您是否正确处理了 DC 预测器?
    b) 您是否正确编码了 A/C 组件 w.r.t.零的运行?
    c) 您是否尊重有关“填充零”和标记的输出流规则?
    d) 您的色彩空间转换公式是否正确?它是否包括必须从每个组件中减去的 0x80?
    e) 您是否根据您选择的子采样选项以正确的顺序对 MCU 块进行编码?

    关于jpeg - 需要有关 BMP 到 JPEG 转换的帮助,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1120951/

    相关文章:

    c++ - 在 Cimg 上创建的图像在使用 GDI+ 保存时在 pdf 上显示不同,而在 pdf 上使用 jagPDF 创建

    C# 从文件中读取 JPEG 并存储为图像

    c++ - 读取 JPEG,调整大小并将其保存到磁盘

    c - 调整 .bmp 文件大小和生成的文件大小错误

    java - 哈夫曼编码,如何对字节进行压缩?

    c - 如何生成霍夫曼树的二进制代码表?

    java - 从 JPEG 数据到完整的 JPEG 文件

    android - 如何将图像保存为 BMP 格式?

    c - 插入哈夫曼树

    c - 位图最大尺寸