Delphi:从SWF文件上的DefineBitsJPEG3标签读取JPEG图像

时间:2013-11-29 01:00:01

标签: delphi flash

从SWF文件中的 DefineBitsJPEG3 标记读取JPEG图像时出现了一些错误。

在SWF文档中,DefineBitsJPEG3的标记结构如下:

Header : long  //Tag type = 35.
Chastrong textracterID : UI16  //ID for this character.
AlphaDataOffset :UI32  //Count of bytes in ImageData.
ImageData : UI8[data size]  //Compressed image data in either JPEG, PNG, or GIF89a format
BitmapAlphaData : UI8[alpha data size]  //ZLIB compressed array of alpha data.
Only supported when tag contains JPEG data. One byte per pixel. Total size after decompression must equal (width * height) of JPEG image.

当图像数据包含JPEG数据时,我使用来自流的常规加载来获取图像,如下所示:

procedure BufferToImg(Buffer:Pchar; BufSize:Integer; Img:TBitmap);
var
  JPG:TJpegImage;
  Mem:TStream;
begin
  JPG:=TJpegImage.Create;
  Mem:=TMemoryStream.Create;
  try
    mem.Write(Buffer^,BufSize);
    mem.Position:=0;
    JPG.LoadFromStream(mem);
    Img.Assign(JPG);
  finally
    mem.Free;
    JPG.Free;
  end;
end;

此代码有时不起作用。 调试时我发现DefineBitsJPEG3标签上有两种类型的JPEG数据:

  1. 在Hex Viewer上使用此标题的JPEG图像可以正常工作
  2.     FF D8 FF E0 00 10 4A 46 49 46  |  ÿØÿà.JFIF
        00 01 01 00 00 01 00 01 00 00  |  ......  
        FF DB 00 43 00 06 04 05 06 05  |  ÿÛ.C.  
    
    1. 在Hex viewer上使用此标题的JPEG图像将失败
    2.     FF D8 FF DB 00 43 00 06 04 05  |  ÿØÿÛ.C.  
          06 05 04 06 06 05 06 07 07 06  |    
          08 0A 10 0A 0A 09 09 0A 14 0E  |  ..  
      

      我的问题是如何加载第二次预览时用标题存储的图像?

      任何帮助将不胜感激。 感谢。

      更新:

      我应该在评论部分写这篇文章但是时间太长了。

      如果我错了,请原谅我。

      仅供参考,使用java编码时没有出现此问题。 我只用Delphi 发现了这个问题 那么让我们在Delphi环境中讨论它。

      使用单独的JPEGTablestag时,我没有发现 DefineBits 标记有任何问题。 问题是 DefineBitsJPEG3 specs说: DefineBitsJPEG3扩展了DefineBitsJPEG2(第139页),但与DefineBits(第138页)的不同之处在于它包含JPEG编码表和JPEG图像数据

      我发现在DefineBitsJPEG3标签上存储了两种类型的数据,两者都带有SOI标记(JFIF / JPEG)但有一个有APP0标记(以及JFIF标题段的所有成员的其余部分),而另一个没有。 /> 主要问题是:Delphi的TJPEGimage只能成功加载带有APP0标记的数据。 没有APP0标记的另一个将失败 如果这意味着我应该读取数据并使用TJPEGImage加载图像,如果存在APP0 并制作另一个功能来加载没有APP0的图像数据, 那我还有另一个问题: 我没有找到任何关于没有APP0标记的 的JPEG / JFIF图像数据的文档。

      有什么建议吗? (但请不要建议我不要使用Delphi)。

      更新2:

      在@FreeConsulting的帮助下,我终于得到了解决方案。

      以下是从SWF缓冲区读取图像的规则:

      • DefineBitsTag:首先读取JPEGTablesTag并在加载TJPEGImage之前用它来创建JPEG Stream。
      • TTagDefineBitsLossLess和TTagDefineBitsLossLess2:使用ZLib解压缩读取数据并使用扫描线设置像素
      • DefineBitsJPEG2和DefineBitsJPEG3:读取第一个和第二个JFIF标记。如果您在SOI之后立即找到DQT,则在使用TJPEGImage加载之前将其用作JPEGTablesTag来创建JPEG Stream(类似于DefineBitsTag)。但如果您在SOI之后没有立即找到DQT,只需将其加载到TJPEGImage。

0 个答案:

没有答案