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

时间:2022-10-29 21:20:01

I'm writing a C++ program to convert a BMP image into a JPEG.

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

Here's the basic algorithm I'm trying to follow:

这是我想要遵循的基本算法:

  1. Convert RGB color space to Y,Cb,Cr..
  2. 将RGB色彩空间转换为Y,Cb,Cr ..

  3. 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
  4. 向下采样Cb和Cr为2(这意味着每个2 * 2的方块有4个不同的Y值,但是1 Cb和1 Cr值

  5. Apply DCT to data units of each 8*8 pixels...
  6. 将DCT应用于每个8 * 8像素的数据单元......

  7. Then apply quantization on DCT coefficient by using standard quantization table of Cb and Cr.
  8. 然后通过使用Cb和Cr的标准量化表对DCT系数应用量化。

  9. Do zigzag ordering.
  10. 做Z字形排序。

  11. Encode the DC and AC coefficient separately using huffman encoding.
  12. 使用霍夫曼编码分别对DC和AC系数进行编码。

  13. Write proper header and write huffman encoded value to the file...
  14. 写出正确的标题并将霍夫曼编码的值写入文件...

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.
  • 生成的JPEG无法正确显示。

  • 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..
  • 我做了一个小的8 * 8 24位(颜色深度)bmp文件完全填充颜色值R = 10 B = 10和G = 100 ...所有64个像素是相同的颜色..

  • The data that I'm getting at every step is as follows...
    • BMP header size of 40
    • BMP标头大小为40

    • size of header 40
    • 标题40的大小

    • width 8
    • height 8
    • no of planes 1
    • 没有飞机1

    • no of bits per pixel 24
    • 没有每像素24位

    • image size 194
    • 图像大小194

    • x resolution pixel per meter 2834
    • 每分钟x分辨率像素2834

    • y resolution pixel per meter 2834
    • y每分辨率像素2834

    • no of colors 0
    • 没有颜色0

    • no of imp colors 0
    • 没有imp颜色0

    • The Y Cb Cr conversion of (R,B,G)=(10,10,100) is (62,-29,-37)
    • (R,B,G)=(10,10,100)的Y Cb Cr转化率为(62,-29,-37)

  • 我在每一步得到的数据如下... BMP标题大小40标题标题40宽度8高度8平面没有1每像素没有比特24图像大小194 x分辨率像素每米2834 y分辨率像素每米2834没有颜色0没有颜色的颜色0(C,C)的转换(R,B,G)=(10,10,100)是(62,-29,-37)

So let's consider Y component first.

所以我们先考虑Y分量。

The DCT coefficient for Y component is :

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

After Quantization, the zig zag ordering of single data unit that I'm getting is this, for the Y component.

在量化之后,对于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

Now the Huffman coding of above zig zag order array is :

现在上面的Z字形顺序数组的霍夫曼编码是:

  • Y dc coding: 00111110
  • Y dc编码:00111110

  • Y ac coding: 1010 (for ac huffman table(luminance Y) EOB value is 1010)
  • Y ac编码:1010(对于交流霍夫曼表(亮度Y)EOB值为1010)

  • Similary huffman coding of Cb and Cr components is as follows:
  • 类似的Cb和Cr组分的霍夫曼编码如下:

  • cb dc coding: 11000010
  • cb dc编码:11000010

  • cb ac coding: 01 (for ac huffman table(chrominance Cb,Cr) EOB value is 01)
  • cb ac编码:01(用于交流霍夫曼表(色度Cb,Cr)EOB值为01)

  • cr dc coding: 110101110
  • cr dc编码:110101110

  • cr ac coding: 01
  • cr ac编码:01

  • The final Huffman code that I get is:

    我得到的最终霍夫曼代码是:

    001111101010110000100111010111001 Length 33

    001111101010110000100111010111001长度33

so to make it divisible by 8, padding of 1 is done.

所以为了使它可被8整除,填充为1就完成了。

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.

这里每个单独的0或1实际上是一个需要存储的位,因为它在JPEG文件中,但由于我们不能逐位写入文件,所以总共采用8位并将其转换为基数中的整数值10并存储为1字节字符。

Can anyone offer any suggestions about where I'm going wrong?

谁能提出任何关于我哪里出错的建议?

2 个解决方案

#1


The first thing to do to solve your problem is to get the Pennebaker/Mitchel book on the JPEG standard.

解决问题的第一步是获取JPEG标准的Pennebaker / Mitchel书籍。

The order of operations is:

操作顺序是:

1) Colorspace conversion 2) FDCT 3) Quantize 4) Zigzag reorder 5) Huffman encode

1)颜色空间转换2)FDCT 3)量化4)Zigzag重新排序5)Huffman编码

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?

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

#2


Don't reinvent the wheel. Use ImageMagick, Magick++, or CImg to accomplish this.

不要重新发明*。使用ImageMagick,Magick ++或CImg来完成此任务。

#1


The first thing to do to solve your problem is to get the Pennebaker/Mitchel book on the JPEG standard.

解决问题的第一步是获取JPEG标准的Pennebaker / Mitchel书籍。

The order of operations is:

操作顺序是:

1) Colorspace conversion 2) FDCT 3) Quantize 4) Zigzag reorder 5) Huffman encode

1)颜色空间转换2)FDCT 3)量化4)Zigzag重新排序5)Huffman编码

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?

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

#2


Don't reinvent the wheel. Use ImageMagick, Magick++, or CImg to accomplish this.

不要重新发明*。使用ImageMagick,Magick ++或CImg来完成此任务。