我期待在gif文件的每一帧中存储text
的方法。不在图像中打印文本,而是添加为属性。微软制作的程序可以为每个框架设置文本。
如您所见,每个框架都有一个“评论”字段。
现在,我的问题是:
这个字段是GIF规范批准的吗?那里几乎没有文件,这样说。 (实际上,有)
如果是的话:
位于哪里?在其中一种方法中?
protected void WriteGraphicCtrlExt()
{
fs.WriteByte(0x21); // extension introducer
fs.WriteByte(0xf9); // GCE label
fs.WriteByte(4); // data block size
int transp, disp;
if (transparent == Color.Empty)
{
transp = 0;
disp = 0; // dispose = no action
}
else
{
transp = 1;
disp = 2; // force clear if using transparent color
}
//If first frame, no transparency and no dispose.
if (firstFrame)
{
disp = 0;
transp = 0;
}
else
{
if (dispose >= 0)
{
disp = dispose & 7; // user override
}
disp <<= 2;
}
// packed fields
fs.WriteByte( Convert.ToByte( 0 | // 1:3 reserved
disp | // 4:6 disposal
0 | // 7 user input - 0 = none
transp )); // 8 transparency flag
WriteShort(delay); // delay x 1/100 sec
fs.WriteByte( Convert.ToByte( transIndex)); // transparent color index
fs.WriteByte(0); // block terminator
}
protected void WriteImageDesc()
{
fs.WriteByte(0x2c); // image separator
WriteShort(0); // image position x,y = 0,0
WriteShort(0);
WriteShort(width); // image size
WriteShort(height);
// packed fields
if (firstFrame)
{
// no LCT - GCT is used for first (or only) frame
fs.WriteByte(0);
}
else
{
// specify normal LCT
fs.WriteByte( Convert.ToByte( 0x80 | // 1 local color table 1=yes
0 | // 2 interlace - 0=no
0 | // 3 sorted - 0=no
0 | // 4-5 reserved
palSize ) ); // 6-8 size of color table
}
}
我找到了一种方法,就像Hans Passand写道:
protected void WriteComment(string comment)
{
fs.WriteByte(0x21);
fs.WriteByte(0xfe);
byte[] lenght = StringToByteArray(comment.Length.ToString("X"));
foreach (byte b in lenght)
{
fs.WriteByte(b);
}
WriteString(comment);
}
答案 0 :(得分:3)
最好只使用该工具(Microsoft的GIFAnimator,可通过MSDN订阅获得),并查看它使用十六进制查看器生成的内容。保持GIF specification方便,以便您可以将您看到的内容与规范相关联。
我创建了一个非常简单的GIF文件,其中包含两个8x8帧,第一个键入“frame 1”,第二个键入“number 2”。哪个产生了这个十六进制转储:
我用红色突出显示了相关的块。它们与规范中的第24节“评论扩展名”匹配:
评论扩展包含文本信息 不属于GIF数据流中的实际图形。这很合适 包括有关图形,信用,描述或任何的评论 其他类型的非控制和非图形数据。评论扩展 解码器可以忽略它,或者可以保存它以供以后处理; 在任何情况下,评论扩展都不应该破坏或干扰 处理数据流。
这个块是可选的;任何数量的数据流都可能出现在数据流中。
注意每个如何跟随21 F9块,“图形控制扩展”块,规范中的第23节。它描述了图像文件中的每一帧,“延迟时间”值至关重要。然后是2C,“图像描述符”块,规范中的第20节。它包含每个帧的图像数据。
回答您的具体问题:
这个字段是GIF规范批准的吗?
是的,明确如第24节所述。完全取决于应用程序在其认为合适时使用它们。它们仅仅是注释性的,并不意味着对另一个GIF实用程序或图像使用者有任何意义。
位于哪里?在其中一种方法中?
不,该代码不会写注释,它只会发出21个F9和2C块。只需更改代码即可在其前面插入21 FE块。像这样:
protected void WriteGraphicCtrlExt(string comment)
{
if (!string.IsNullOrEmpty(comment)) {
fs.WriteByte(0x21);
fs.WriteByte(0xfe);
var bytes = Encoding.ASCII.GetBytes(comment);
fs.WriteByte((byte)bytes.Length);
fs.Write(bytes, 0, bytes.Length);
fs.WriteByte(0);
}
// Rest of code
//...
}
答案 1 :(得分:1)
那么GifLib项目可以帮助您解决这个问题。具体来说,这些文件:
http://giflib.codeplex.com/SourceControl/latest#GifEncoder.cs,第87行Encode(),它在代码中指定将内容写入输出gif流的顺序
以及评论扩展,一些指示:
http://giflib.codeplex.com/SourceControl/latest#CommentEx.cs,第57行GetBuffer():
internal byte[] GetBuffer()
{
List<byte> list = new List<byte>();
list.Add(GifExtensions.ExtensionIntroducer); // 0x21
list.Add(GifExtensions.CommentLabel); // 0xFE
foreach (string coment in CommentDatas)
{
char[] commentCharArray = coment.ToCharArray();
list.Add((byte)commentCharArray.Length);
foreach (char c in commentCharArray)
{
list.Add((byte)c);
}
}
list.Add(GifExtensions.Terminator); // 0
return list.ToArray();
}