需要有关 BMP 到 JPEG 转换的帮助
我正在编写一个 C++ 程序来将 BMP 图像转换为 JPEG。
这是我尝试遵循的基本算法:
- 将 RGB 颜色空间转换为 Y,Cb,Cr..
- 将 Cb 和 Cr 采样减少 2(这意味着对于 2*2 的每个方块,有 4 个不同的 Y 值,但有 1 个 Cb和 1 Cr 值
- 对每个 8*8 像素的数据单元应用 DCT...
- 然后使用 Cb 和 Cr 的标准量化表对
- 锯齿形排序 分别使用哈夫曼编码进行
- DC 系数和 AC 系数进行
- 编码 。正确的标头并将霍夫曼编码值写入文件...
我已经验证我正确执行了上述操作,但仍然遇到以下问题:
- 生成的 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
- 小鬼颜色数量 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编码:01(对于ac霍夫曼表(色度Cb,Cr)EOB值为01)
- cr dc编码:110101110
- cr ac编码:01
我得到的最终霍夫曼代码是:
001111101010110000100111010111001 Length 33
因此为了使其能被8整除,填充了1。
0011111010101100001001110101110011111111 Length 40.
这里每个单独的 0 或 1 实际上是一个位,需要像在 JPEG 文件中一样存储,但由于我们无法逐位写入文件,因此总共取出 8 位并将其转换为基数中的整数值10 并存储为 1 字节字符。
谁能对我哪里出错提出任何建议?
I'm writing a C++ program to convert a BMP image into a JPEG.
Here's the basic algorithm I'm trying to follow:
- Convert RGB color space to Y,Cb,Cr..
- Down sample Cb and Cr by 2 (that means for each square block of 2*2 there is 4 different Y value but 1 Cb and 1 Cr value
- Apply DCT to data units of each 8*8 pixels...
- Then apply quantization on DCT coefficient by using standard quantization table of Cb and Cr.
- Do zigzag ordering.
- Encode the DC and AC coefficient separately using huffman encoding.
- Write proper header and write huffman encoded value to the file...
I've verified that I'm doing the above correctly but I'm still having the following issues:
- The JPEG being generated isn't displayed correctly.
- I made a small 8*8 24 bit(color depth) bmp file completly filled with color value R=10 B=10 and G=100...all 64 pixels are of same color..
- The data that I'm getting at every step is as follows...
- BMP header size of 40
- size of header 40
- width 8
- height 8
- no of planes 1
- no of bits per pixel 24
- image size 194
- x resolution pixel per meter 2834
- y resolution pixel per meter 2834
- no of colors 0
- no of imp colors 0
- The Y Cb Cr conversion of (R,B,G)=(10,10,100) is (62,-29,-37)
So let's consider Y component first.
The DCT coefficient for Y component is :
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
After Quantization, the zig zag ordering of single data unit that I'm getting is this, for the Y component.
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
Now the Huffman coding of above zig zag order array is :
- Y dc coding: 00111110
- Y ac coding: 1010 (for ac huffman table(luminance Y) EOB value is 1010)
- Similary huffman coding of Cb and Cr components is as follows:
- cb dc coding: 11000010
- cb ac coding: 01 (for ac huffman table(chrominance Cb,Cr) EOB value is 01)
- cr dc coding: 110101110
- cr ac coding: 01
The final Huffman code that I get is:
001111101010110000100111010111001 Length 33
so to make it divisible by 8, padding of 1 is done.
0011111010101100001001110101110011111111 Length 40.
Here each single 0 or 1 is actually a bit that needs to be stored as it is in the JPEG file but since we can't write bit by bit into file, a total of 8 bits are taken and converted into a integer value in base 10 and stored into a 1-byte character.
Can anyone offer any suggestions about where I'm going wrong?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
要解决您的问题,首先要做的就是获取 Pennebaker/Mitchel 有关 JPEG 标准的书。
操作顺序为:
1)色彩空间转换
2)FDCT
3)量化
4) 之字形重新排序
5) 霍夫曼编码
这些操作非常复杂,因为您必须遵循许多规则。
a) 您是否正确处理 DC 预测变量?
b) 您是否正确地对 A/C 组件进行了零游程编码?
c) 您是否遵守有关“填充零”和标记的输出流规则?
d) 您的色彩空间转换公式正确吗? 它是否包括必须从每个组件中减去的 0x80?
e) 您是否根据您选择的子采样选项以正确的顺序对 MCU 块进行编码?
The first thing to do to solve your problem is to get the Pennebaker/Mitchel book on the JPEG standard.
The order of operations is:
1) Colorspace conversion
2) FDCT
3) Quantize
4) Zigzag reorder
5) Huffman encode
Those operations have many complexities because of the many rules you must follow.
a) Are you handling the DC predictors properly?
b) Are you encoding the A/C components properly w.r.t. the runs of zeros?
c) Are you respecting the output stream rule about "padded zeros" and markers?
d) Is your colorspace conversion formula correct? Does it include the 0x80 which must be subtracted from each of the components?
e) Are you encoding the MCU blocks in the proper order based on your choice of subsampling option?
不要重新发明轮子。 使用 ImageMagick、Magick++ 或 CImg 来完成此操作。
Don't reinvent the wheel. Use ImageMagick, Magick++, or CImg to accomplish this.