修改JPEG文件的标题以正确匹配格式

时间:2012-01-19 22:01:00

标签: image delphi file jpeg

我已经在世界各地试图用一大堆我的图像解决一个奇怪的问题。

我需要知道如何读取和写入JPEG文件头中的前4个和第18个字节。如果它们匹配某些属性,我需要做一些特定的工作并调整这些字节以反映其他内容。我基本上将这些图片的格式修改为更标准的格式,因为Delphi无法识别它们所处的格式。

那么如何读/写这些字节呢?我该用什么?我对读取图像文件的原始数据一无所知,更不用说调整它了。


注意

删除了大部分问题,因为我从一开始就提供了太多信息。

4 个答案:

答案 0 :(得分:3)

甚至不认为你可以手动调整你的jpeg文件的前x个字节。

正如已经解释的那样,jpeg格式是多种形式且非常复杂。一些常用的库不能处理所有可接受的格式。打开libjpeg.h并查看可在jpeg文件中找到的一堆标题结构。

如果您想在不更改数据的情况下修改标题,您仍然需要打开带有库的jpeg,该库将移交适当的结构,以便您修改相关标志并将其保存为所需格式。

找到一个用Delphi或Delphi接口编写的库,并使用它来构建批处理转换器,或者在应用程序中打开jpeg时动态转换格式。

如果你知道定义问题文件的属性/标志的确切组合,你可以调整jpeg.pas单位以满足你的需要,正如我在previous answer中所示。

答案 1 :(得分:3)

实际更改JPG标头的机制非常简单。这并不意味着修复JPG很容易,只是如果你知道要改变什么,你就可以轻松地做到。既然这就是你要问的,这里是如何在内存中更改JPG标头,将修改后的JPG加载到TJpgImage并转换为TBitmap。

请注意我认为这不是一个好方法。修复生成的位图非常简单!有关如何修复位图here的详细信息,请参阅我对您的其他问题的新答案。

以下是您要求的代码(如何更改JPG标题):

function LoadJpegIntoBitmap_HeaderFix(const FileName:string): TBitmap;
var M: TMemoryStream;
    P: PByteArray;
    Jpg: TJPEGImage;
begin
  M := TMemoryStream.Create;
  try
    M.LoadFromFile(FileName);
    if M.Size < 18 then raise Exception.Create('File too short.');
    P := M.Memory;

    // Here you can manipulate the header of the JPG file any way you want.
    if P[0] = $07 then P[3] := P[17] - P[0]*3;

    // Now load the modified JPG into a TJpgImage
    Jpg := TJPEGImage.Create;
    try
      Jpg.LoadFromStream(M);

      // Convert to bitmap
      Result := TBitmap.Create;
      Result.Assign(Jpg);

    finally Jpg.Free;
    end;

  finally M.Free;
  end;
end;

答案 2 :(得分:2)

这里有一些伪代码非常快。我稍后会改进它。我必须跑。

Assign the Adobe JPEG image file to a TFileStream
Read first 18 bytes and use CompareMem to see if signature matches Adobe RGB JPEG
If RGB JPEG then
  We'll either:
    Load from stream and tweak the header as we load
  OR
    Load from stream, copy to TBitmap, and use ScanLine to fix RGB
Else
  Load from stream, normally

提示,请参阅LoadFromStream()而不是LoadFromFile()

我不知道你之后对图像做了什么,所以可能还有一些工作要做。

答案 3 :(得分:2)

是的,所以你的选择是(因为我们完全排除了任何第三方代码):

  1. 一些Delphi大师(我当然不是)从木工中走出来,并用标准的Delphi库代码来处理这个,或者,
  2. 您编写自己的JPEG元数据解码库。
  3. 由于我无法帮助您使用第一个选项,因此以下是您在追求第二个选项时需要的一些参考:

    • Wikipedia's JPEG article - 关于维基的更好的文章之一。这个毛茸茸的主题的伟大介绍材料。
    • ITU T.81 - 原始JPEG规范。最重要的一点是附件B,但这实际上描述了一种称为JIF的格式,它实际上并未使用。但是,JFIF和EXIF都是基于它的。
    • ICC - 这指定了ICC(国际色彩联盟)配置文件,这些配置文件似乎与您的标题有关。
    • ICC 2010 - 上述规范的新版本,Errata
    • JFIF - 大多数JPEG文件实际使用的格式。
    • EXIF - JPEG文件使用的另一种格式,尤其是那些来自数码相机的格式。
    • ITU T.84 - 不太有用,它描述了JPEG扩展。我把它包括在这里是为了完整。

    可悲的是,我所知道的任何公共域JPEG实现(在任何语言中)都没有实际处理标准的相关位,即EXIF和ICC配置文件,因此我无法为您提供任何可以绘制的代码来自的灵感。最好看的地方可能是libexif,但这是GPL。

    您要做的是将JPEG文件作为常规文件读入,根据从上述文档中收集的信息解析输入,进行必要的更改,然后将其写回。我不认为这很容易,但显然这是你唯一接受的解决方案。

    祝你好运!