【发布时间】:2009-07-13 17:36:41
【问题描述】:
我正在编写一个 C++ 程序来将 BMP 图像转换为 JPEG。
这是我尝试遵循的基本算法:
- 将 RGB 颜色空间转换为 Y,Cb,Cr..
- 将 Cb 和 Cr 下采样 2(这意味着对于 2*2 的每个方块,有 4 个不同的 Y 值,但有 1 个 Cb 和 1 个 Cr 值
- 对每个 8*8 像素的数据单元应用 DCT...
- 然后使用标准的 Cb 和 Cr 量化表对 DCT 系数进行量化。
- 进行曲折排序。
- 使用霍夫曼编码分别对直流和交流系数进行编码。
- 写入正确的标头并将霍夫曼编码值写入文件...
我已确认我执行上述操作是正确的,但我仍然遇到以下问题:
- 生成的 JPEG 显示不正确。
- 我制作了一个小的 8*8 24 位(颜色深度)bmp 文件,完全填充了颜色值 R=10 B=10 和 G=100...所有 64 个像素都是相同颜色的..
- 我在每一步得到的数据如下...
- BMP 标头大小为 40
- 标题 40 的大小
- 宽8
- 身高8
- 平面数 1
- 每像素的位数 24
- 图像尺寸 194
- x 分辨率像素每米 2834
- y 分辨率像素每米 2834
- 颜色数量 0
- imp 颜色数 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直流编码:00111110
- Y ac 编码:1010(对于 ac 霍夫曼表(亮度 Y)EOB 值为 1010)
- Cb 和 Cr 分量的类似霍夫曼编码如下:
- cb直流编码:11000010
- cb ac 编码: 01 (for ac huffman table(chrominance Cb,Cr) EOB 值为 01)
- cr 直流编码:110101110
- cr ac 编码:01
-
我得到的最终霍夫曼代码是:
001111101010110000100111010111001 长度33
为了使它能被 8 整除,填充 1 就完成了。
0011111010101100001001110101110011111111 Length 40.
这里每个0或1实际上是需要存储在JPEG文件中的一个位,但是由于我们不能逐位写入文件,所以总共取8位并转换为整数以 10 为底的值并存储为 1 字节字符。
任何人都可以提供任何关于我哪里出错的建议吗?
【问题讨论】:
-
您似乎需要帮助来撰写帖子和选择合适的标签。
-
最后是一个很棒的技术问题。谢谢马克。不幸的是,我没有答案,但我希望有人知道。
-
顺便提一下,将您的代码提炼成其他人可以编译的最短示例可以创造奇迹。提供代码也是一种更有效的方式,可以帮助其他人了解可能缺少的内容。
-
我投了反对票,因为不清楚您认为结果的哪一部分是错误的以及它们应该是什么,并且您没有包含任何代码来明确可能发生的情况。
-
你有什么理由不能使用 IJG 的 libjpeg?
标签: jpeg bmp huffman-code dct