确定JPEG(JFIF)图像的大小 [英] Determining the size of a JPEG (JFIF) image

查看:121
本文介绍了确定JPEG(JFIF)图像的大小的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要找到JPEG(JFIF)图像的大小.该图像未保存为独立文件,因此我不能使用GetFileSize或任何其他API这样的图像(图像放置在流中,并且不存在其他标头,但通常的JPEG/JFIF标头除外) (s)).

I need to find the size of a JPEG (JFIF) image. The image is not saved as a stand-alone file, so I can't use GetFileSize or any other API such this one (the image is placed in a stream and no other header is present, except the usual JPEG/JFIF header(s)).

我进行了一些研究,发现JPEG图像由不同的部分组成,每个部分都以帧标记(0xFF 0xXX)开头以及该帧的大小.使用这些信息,我能够从文件中解析出很多信息.

I did some research and found out that JPEG images are composed of different parts, each part starting with a frame marker (0xFF 0xXX), and the size of this frame. Using this information I was able to parse a lot of information from the file.

问题是,我找不到压缩数据的大小,因为似乎没有用于压缩数据的帧标记.同样,压缩数据似乎遵循SOS(FFDA)标记,并且图像以图像结束(EOI)(FFD9)标记结束.

The problem is, I cannot find the size of the compressed data, as it seems there is no frame marker for the compressed data. Also, it seems the compressed data follows the SOS (FFDA) marker and the image ends with the End Of Image (EOI) (FFD9) marker.

一种实现此目的的方法是从一个字节到另一个字节搜索EOI标记,但是我认为压缩数据可能包含此字节组合,对吧?

A way to accomplish this would be to search for the EOI marker from byte to byte, but I think the compressed data might contain this combination of bytes, right?

是否有一种简单正确的方法来查找图像的总尺寸? (我希望在没有任何外部库的情况下提供一些代码/想法 )

Is there an easy and correct way to find the total size of the image? (I would prefer some code/idea without any external library)

基本上,我需要图像开始(SOI- FFE0)和图像结束(EOI- FFD9)之间的距离(以字节为单位).

Basically, I need the distance (in bytes) between the Start of Image (SOI-FFE0) and End of Image (EOI-FFD9).

推荐答案

压缩数据将不包含SOI或EOI字节,因此您在那很安全.但是注释,应用程序数据或其他标题可能会出现.幸运的是,您可以根据长度确定并跳过这些部分.

The compressed data will not include SOI or EOI bytes, so you are safe there. But the comment, application data, or other headers might. Fortunately, you can identify and skip these sections as the length is given.

JPEG规范告诉您您需要什么:
http://www.w3.org/Graphics/JPEG/itu-t81.pdf

The JPEG specification tells you what you need:
http://www.w3.org/Graphics/JPEG/itu-t81.pdf

请参阅第32页的表B.1.带有*的符号后面没有长度字段(RST,SOI,EOI,TEM).其他人这样做.

Look at Table B.1, on page 32. The symbols that have an * do not have a length field following it (RST, SOI, EOI, TEM). The others do.

您将需要跳过各个字段,但这还不错.

You will need to skip over the various fields, but it is not too bad.

操作方法:

  1. 开始读取SOI(FFD8).这是开始.它应该是流中的第一件事.

  1. Start reading SOI (FFD8). This is the start. It should be the first thing in the stream.

  • 然后,浏览文件,查找更多标记并跳过标题:

  • Then, progress through the file, finding more markers and skipping over the headers:

SOI标记(FFD8):损坏的图像.您应该已经找到了EOI!

SOI marker (FFD8): Corrupted image. You should have found an EOI already!

TEM(FF01):独立标记,请继续.

TEM (FF01): standalone marker, keep going.

RST(FFD0FFD7):独立标记,请继续.您可以验证重启标记从FFD0FFD7计数并重复,但是这对于测量长度不是必需的.

RST (FFD0 through FFD7): standalone marker, keep going. You could validate that the restart markers count up from FFD0 through FFD7 and repeat, but that is not necessary for measuring the length.

EOI标记(FFD9):完成!

EOI marker (FFD9): You're done!

不是RST,SOI,EOI,TEM的任何标记(FF01FFFE,减去上面的异常):在标记之后,读取接下来的2个字节,这是16位大帧头的endian长度(不包括2字节标记,但包括length字段).跳过给定的数量(通常长度减去2,因为您已经获得了这些字节).

Any marker that is not RST, SOI, EOI, TEM (FF01 through FFFE, minus the exceptions above): After the marker, read the next 2 bytes, this is the 16-bit big-endian length of that frame header (not including the 2-byte marker, but including the length field). Skip the given amount (typically length minus 2, since you already got those bytes).

如果在EOI之前获得文件结尾,则表示图像已损坏.

If you get an end-of-file before EOI, then you've got a corrupted image.

一旦有了EOI,就已经获得了JPEG,并且应该具有长度.如果您希望流中有多个JPEG,则可以通过读取另一个SOI重新开始.

Once you've got an EOI, you've gotten through the JPEG and should have the length. You can start again by reading another SOI if you expect more than one JPEG in your stream.

这篇关于确定JPEG(JFIF)图像的大小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆