我试图在不解码文件的情况下获得JPEG图像的分辨率。我从互联网上得到了几个样本但没有一个正常工作。这似乎是这种方式,因为很多 JPEG文件不是标准的,但任何图形应用程序(Irfan,PSP,Firefox等)都可以打开它们。
JPEG的标题应该是:
typedef struct _JFIFHeader
{
BYTE SOI[2]; /* 00h Start of Image Marker */
BYTE APP0[2]; /* 02h Application Use Marker */
BYTE Length[2]; /* 04h Length of APP0 Field */
BYTE Identifier[5]; /* 06h "JFIF" (zero terminated) Id String */
BYTE Version[2]; /* 07h JFIF Format Revision */
BYTE Units; /* 09h Units used for Resolution */
BYTE Xdensity[2]; /* 0Ah Horizontal Resolution */
BYTE Ydensity[2]; /* 0Ch Vertical Resolution */
BYTE XThumbnail; /* 0Eh Horizontal Pixel Count */
BYTE YThumbnail; /* 0Fh Vertical Pixel Count */
} JFIFHEAD;
然而,当我查看其中一个非标准文件时,Xdensity和Ydensity字段是错误的。但同样,所有图形应用程序都可以读取此非标准文件。
有人知道一段可以实际读取所有JPEG文件的Delphi代码吗?
Delphi 7,Win 7 32位
答案 0 :(得分:15)
我不知道所有JPEG文件,但您需要处理JPEG的两种常用文件格式。由于JPEG是一种压缩方法而不是文件格式,因此世界各地开发了一些将JPEG图像数据存储在文件中的方法。你最有可能遇到的两个是JFIF和EXIF。上面的代码涵盖了JFIF,但不处理EXIF。这两个在很大程度上是不兼容的,但都是JPEG,所以如果你使用标题信息,你需要检测和处理,因为它们是推迟的。
作为解决方案,作为一个例子。 EXIF的字段是 x-Resolution 和 y-Resolution ,与X / Y密度方法相比。
我会:
对两种格式(JFIF和EXIF)进行一些阅读。我发现 维基百科是一个很好的起点 在这个参考(对于一些过去 我做过的项目,但最重要的是 可能有一些很好的信息 主题也是。
JFIF: http://en.wikipedia.org/wiki/JPEG_File_Interchange_Format
编写代码以使用起始标题检测格式
独立处理每种格式
包裹整个东西,这样你就可以把JPEG扔到它上面然后得到它 密度。这也将为您提供一个很好的位置来折腾其他帮助代码来处理JPEG处理的“有趣”世界
答案 1 :(得分:10)
以下是一些可以帮助您获取所需数据的代码:
function GetJpegSize(jpeg: TMemoryStream; out width, height, BitDepth: integer): boolean;
var n: integer;
b: byte;
w: Word;
begin
result := false;
n := jpeg.Size-8;
jpeg.Position := 0;
if n<=0 then
exit;
jpeg.Read(w,2);
if w<>$D8FF then
exit; // invalid format
jpeg.Read(b,1);
while (jpeg.Position<n) and (b=$FF) do begin
jpeg.Read(b,1);
case b of
$C0..$C3: begin
jpeg.Seek(3,soFromCurrent);
jpeg.Read(w,2);
height := swap(w);
jpeg.Read(w,2);
width := swap(w);
jpeg.Read(b,1);
BitDepth := b*8;
Result := true; // JPEG format OK
exit;
end;
$FF:
jpeg.Read(b,1);
$D0..$D9, $01: begin
jpeg.Seek(1,soFromCurrent);
jpeg.Read(b,1);
end;
else begin
jpeg.Read(w,2);
jpeg.Seek(swap(w)-2, soFromCurrent);
jpeg.Read(b,1);
end;
end;
end;
end;
答案 2 :(得分:2)
单位, Xdensity 和 Ydensity 成员指定用于描述物理点密度打印文件时。
关键是存储在图像文件中的点分辨率(缩放的打印分辨率)在屏幕上无关紧要。因此,Windows程序将始终在屏幕上显示任何文件的96逻辑ppi。注意,一些应用程序更喜欢使用72逻辑ppi来在屏幕上显示图片,例如Adobe应用程序。
在屏幕上显示JPG文件时,ACDSee,Adobe Photoshop,CorelDRAW等图形应用程序只会忽略 Units , Xdensity 和 Ydensity 成员,但图形应用程序在打印JPG文件时会考虑这些成员的价值。如果JPG文件没有 Units , Xdensity 和 Ydensity 成员,图形应用程序将使用其自定义默认值(通常为150 dpi)打印JPG文件。
因此,对于可以读取所有JPEG头文件的Delphi代码的问题,答案很简单,只需读取JPG文件头信息;如果文件中不存在可选成员,只需忽略可选成员或告诉最终用户当前未在文件中指定它们。
答案 3 :(得分:0)
有一个TP / TPW / Delphi(1-4,但可能会工作到没有大mod的unicode版本)包,pasjp(e)g可以读取大多数旧的JPG类型(但不是例如JPEG2000)< / p>
FPC也包括此套餐。
来自J. Nommsi的原始网站已经消失,但该套餐仍然可用,例如从