首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在GIF图像中找到图像块的起始位置?

如何在GIF图像中找到图像块的起始位置?
EN

Stack Overflow用户
提问于 2015-09-02 09:16:49
回答 1查看 1.3K关注 0票数 2

信息源- http://www.onicos.com/staff/iz/formats/gif.html#header

GIF图像中,实际图像大小(宽度、高度)存储在图像块中。据我所知,图像块是头中包含的第一个块。在实际块开始之前,有一个名为全局颜色表(0..255x3字节)的内存分配(从现在起-在GCT上)。如果我知道为GCT保留的字节计数,我可以从图像块中提取字节5-9,并具有实际的图像大小。

问题:如何知道/了解GCT的大小?

GCT在哪里结束?

图像块从哪里开始?

图像块在哪里结束?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-09-03 07:20:12

您所需的gif enc/dec您可以在这里找到3MF项目GIF

  1. GCT 此块是可选的,并不总是出现在GIF文件中。大小由颜色数决定,并从GIF标头中变宽。我像这样解码/加载它: 结构化_hdr { //头字节Signature3;/*头签名(总是" GIF ") */字节Version3;/* GIF格式版本(“87a”或"89a") * / /逻辑屏幕描述符词xs;WORD ys;字节打包;/*屏幕和彩色地图信息*/字节BackgroundColor;/*背景颜色索引*/字节AspectRatio;/*像素长径比*/ } hdr;gcolor_bits= (hdr.Packed &7)+1;//全球托盘scolor_bits=((hdr.Packed>>4)&7)+1;// screen _gcolor_sorted =hdr.Packed&8;_gcolor_table =hdr.Packed&128;scolors=1<
代码语言:javascript
复制
- if `_gcolor_table` is true then **GCT** is present
- **GCT** size is `3*gcolors` [Bytes] stored in order `R,G,B`

  1. 启动图像 这个问题有点棘手,因为GIF89a文件可能包含许多可选块。您需要执行解码循环,检测块的类型,并根据其目的对其进行解码/跳过。我这样做: struct _gfxext {字节导入器;/*扩展导入器(总是21h) */字节标签;/*图形控制标签(总是F9h) */字节BlockSize;剩余字段的/*大小(总是04h) */字节填充;/*图形处理方法使用*/ WORD DelayTime;/*百分之一秒等待*/字节ColorIndex;/*透明颜色索引*/字节终止符;/*块终止符(总是0) */ } gfx;结构_txtext {字节导入器;/*扩展导入器(总是21h) */字节标签;/*扩展标签(总是01h) */字节BlockSize;扩展块的/*大小(总是0Ch) */ WORD TextGridLeft;以像素*/ WORD TextGridTop为单位的文本网格的TextGridTop X位置;以像素*/ WORD TextGridWidth为单位的文本网格的/* Y位置;以像素*/ WORD TextGridHeight为单位的文本网格的/*宽度;以像素*/字节CellWidth为单位的文本网格的/*高度;以像素*/字节CellHeight为单位的网格单元格的/*宽度;以像素*/字节为单位的网格单元格的/*高度;以像素*/字节为单位的/*文本前景颜色索引值*/字节TextFgColorIndex;/*文本背景色索引值* / /字节*PlainTextData;/*纯文本数据* / /字节终止符;/*块终止符(总是0) */ };struct _remext {字节导入器;/*扩展导入器(总是21h) */字节标签;/*注释标签(总是FEh) * / /字节*CommentData;/*指针,用于注释数据子块* / /字节终止符;/*块终止符(总是0) */ };结构_appext {字节导入器;/*扩展导入器(总是21h) */字节标签;/*扩展标签(总是FFh) */字节BlockSize;扩展块的/*大小(总是0 0Bh) */ CHAR Identifier8;/*应用程序标识符*/ AuthentCode3;/*应用程序身份验证代码* / /字节*ApplicationData;/*指向应用程序数据子块* / /字节终止符;/*块终止符(始终为0) */ };// Handl89a扩展阻止_gfxext gfxext;gfxext.Introducer=0;_txtext txtext;txtext.Introducer=0;_remext remext;remext.Introducer=0;_appext;appext.Introducer=0;if ((hdr.version=‘8’)&&(hdr.Version 1=‘9’)和(hdr.Version 2=‘a’) _89a=true;else _89a=false;if (_89a) for (;!f.eof;) {f.peek(字节*)&dw,2;if (dw==0xF921) {f.read(字节*)&gfxext,相当大的(_gfxext);} if (dw==0x0121) {f.read((字节*)&txtext,sizeof(_txtext));for (;!f.eof;) { f.read(&db,1);if (!db)断开;f.read(dat,DWORD(db));} if (dw==0xFE21) {f.read(字节*&remext,sizeof(_remext));for (;!f.eof;) { f.read(&db,1);if (!db)中断;f.read(dat,DWORD(db));} else (dw==0xFF21) {f.read((字节*)&appext,sizeof(_appext));for (;!f.eof;) { f.read(&db,1);if (!db)断开;f.read(dat,DWORD(db));}} if (dw&0x00ff)==0x0021)返回;//损坏的文件其他中断;//无延期}
代码语言:javascript
复制
- `db` is BYTE variable
- `dw` is WORD variable
- `f` is my file cache class the members are self explanatory I hope anyway:
- `f.read(&data,size)` read `size` BYTES into `data`
- `f.peek(&data,size)` do the same but do not update position in file
- `f.eof` indicates end of file reached

在所有这些图像头开始后,必须对每个帧执行此操作。

  1. 图像 图像块以终止符结束。所有的图像块都以BYTE计数开始。如果是zero,则为终止符块。通常在图像之后,很少有BYTES不被、LZW、数据使用,所以在填充整个图像区域之后,跳过所有块,直到点击零大小的块,然后停止,即图像结束。如果BYTE之后是0x3B十六进制,则到达GIF文件的末尾。

注意到

不要忘记通过#pragma pack(1)#pragma pack()封装结构,或者手动将对齐设置为1 BYTE。注意有符号数据类型的问题(LZW数据是无符号的),所以在可以避免问题的地方过度类型,或者只使用无符号变量(有足够的位宽)来解码。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32349200

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档