跳到主内容

SWF 资源类型与计数:从形状到二进制数据

作品页里的“形状 177”“影片剪辑 67”是怎么数出来的?从 SWF 的角色字典和定义标签慢慢看起。

Flash 保存计划 · 最近整理于 2026年7月30日

本文目录 · 14 节
  1. 作品页上的数字从哪里来
  2. 形状(Shape)
  3. 变形形状(Morph Shape)
  4. 影片剪辑(Sprite)
  5. 按钮(Button)
  6. 静态文本(Static Text)
  7. 动态文本(Edit Text)
  8. 位图(Bitmap)
  9. 声音(Sound)
  10. 视频(Video)
  11. 二进制数据(Binary Data)
  12. 字体(Font)
  13. 把这些数字放回作品里看
  14. 相关词条

SWF 不是一串预先渲染好的画面,而是带角色字典和时间轴的二进制容器。形状、文字、位图、声音等内容先由定义标签写入字典,获得 CharacterIdPlaceObjectStartSound控制标签再引用它们,创建画面实例或触发播放。

作品页的“资源计数”汇总的正是这些定义标签。提取器一路读过顶层标签,遇到对应家族就给 assets 字段加一,零值不显示。所以“形状 177”其实是在说:文件里出现了 177 个 DefineShape 系列定义。

这不是舞台上的实例数,也不是绘制次数。一个形状可以从未放置,也可以在多个影片剪辑和按钮状态里反复使用;一帧上的大量实例也可能都指向同一个定义。

正常写出的 SWF 会为每个字典定义使用唯一 CharacterId,通常一个定义标签就是一个角色。不过这里按标签出现次数计数,不按 ID 去重;碰到损坏或不标准的文件重复使用 ID,数字仍会照实反映标签次数。

同一家族的历代标签会合并展示:DefineShape 1–4 都是“形状”,DefineMorphShape 1–2 都是“变形形状”。精确版本仍保留在 SWF 标签构成中。

作品页上的数字从哪里来

作品页名称 元数据字段 加一的 SWF 定义标签 不计入的相关标签
形状 shapes DefineShapeDefineShape2DefineShape3DefineShape4 PlaceObject*、形状被引用的次数
变形形状 morphshapes DefineMorphShapeDefineMorphShape2 PlaceObject2 的变形比例与放置次数
影片剪辑 sprites DefineSprite 剪辑内的 ShowFramePlaceObject* 等控制标签
按钮 buttons DefineButtonDefineButton2 DefineButtonSound、按钮内部的状态记录数量
静态文本 texts DefineTextDefineText2 字符数、字形数、文本记录数
动态文本 edit_texts DefineEditText 初始字符串长度、变量被改写的次数
位图 bitmaps DefineBitsDefineBitsJPEG2DefineBitsJPEG3DefineBitsJPEG4DefineBitsLosslessDefineBitsLossless2 JPEGTables、位图填充或放置次数
声音 sounds DefineSound SoundStreamHead*SoundStreamBlockStartSound*
视频 videos DefineVideoStream VideoFrame 的数量
二进制 binary_data DefineBinaryData 数据字节数、SymbolClass 关联数
字体 fonts DefineFontDefineFont2DefineFont3DefineFont4 DefineFontInfo*DefineFontName、字形数

后缀数字只是同类标签随 SWF 版本长出的新一代,并不表示同一资源被重复计算;概览把它们收进同一个名字,细节留在标签构成里。

形状(Shape)

DefineShape 系列把矢量路径、填充、线条和边界作为一个角色加入字典。第二代放宽样式数量并允许多套样式表,第三代引入 RGBA,第四代又扩展线帽、连接、缩放笔触和边缘边界。一个定义内部可以只有几条边,也可以包含大量路径并引用位图填充,所以数量既不代表复杂度,也不等于“纯矢量”。

变形形状(Morph Shape)

DefineMorphShapeDefineMorphShape2 保存角色的起止轮廓、填充和线条状态;PlaceObject2.Ratio 指定播放时的插值位置。无论时间轴使用多少个比例、生成多少补间帧,每个变形定义仍只计一次。

影片剪辑(Sprite)

SWF 的 sprite 对应 Flash 创作工具里的 movie clip(影片剪辑):一个拥有独立帧数和控制标签的嵌套时间轴,可以自行播放、停止、放置子角色,也可以被主时间轴反复实例化。它不是 sprite sheet,更不是视频;真正的嵌入视频由 DefineVideoStreamVideoFrame 表示。界面采用“影片剪辑”而没有直译成“精灵”,正是为了避开这层歧义。

按 SWF 的组织方式,DefineSprite 里面放的是控制标签,DefineShape 等角色定义应先写在主文件中。所以只数顶层定义就能覆盖正常文件里的字典资源,影片剪辑反复放置同一角色也不会把数字越滚越大。

按钮(Button)

DefineButtonDefineButton2 用字典角色组成交互按钮,并分别描述默认(Up)、悬停(Over)、按下(Down)和点击判定区(Hit)。第二代还可为更多状态转换关联传统动作。状态记录、视觉子角色再多也只算一个按钮;纯脚本模拟、没有 DefineButton* 的按钮则不在数字里。

静态文本(Static Text)

DefineTextDefineText2 保存已经排定的字形文本:它们引用字体字典里的字形索引,并记录位置、推进量、字号和颜色;第二代颜色可带透明度。“静态”指排版在导出时已经确定,不妨碍整个对象随时间轴移动或隐藏。这里按文本对象定义计数,不按字符、行、字形或 TEXTRECORD 计数;字形索引也不是可直接搜索的 Unicode 文本。

动态文本(Edit Text)

DefineEditText 定义运行时文本字段,可带初始文字、变量名、字体、颜色、长度、布局和 HTML 文本等选项,ActionScript 也能读写它。字段既可能显示分数、对话或状态,也可能是输入框;Edit 并不保证用户可输入,是否只读另由标志决定。一个定义计一个字段,初始值为空或运行时反复改写都不改变计数。

位图(Bitmap)

本馆把压缩图像家族 DefineBitsDefineBitsJPEG2/3/4 与无损家族 DefineBitsLossless/2 合并为“位图”。前者的后续版本可携带透明通道;其中 DefineBitsJPEG2 实际也允许 PNG 或 GIF89a,标签名不能证明素材扩展名。无损家族由 SWF 描述像素格式并压缩数据,第二代支持透明度。每个定义算一个位图角色,像素数、字节数、引用次数以及运行时网络图片都不在这个数字里。

声音(Sound)

“声音”只统计 DefineSound,也就是可由 StartSound 等标签触发的事件声音。时间轴流式声音走另一条路径:SoundStreamHead* 描述格式,SoundStreamBlock 携带数据;它会让媒体概况显示“有音频”,却不增加 assets.sounds。因此“声音 0”和“音频:有”可以同时成立,编码与采样率另见 SWF 音频

视频(Video)

DefineVideoStream 定义可放入显示列表的视频角色,记录宽高、预计帧数、平滑和解码器信息;VideoFrame 再逐帧提供数据。本馆只数流定义,所以数百帧的单流仍是“视频 1”,只有流定义而缺少帧数据的异常文件也可能计为 1。H.263、VP6、Screen Video 等编码另见 SWF 视频。这与作为嵌套时间轴的 DefineSprite“影片剪辑”是两种结构。

二进制数据(Binary Data)

DefineBinaryData 把任意字节块作为带 CharacterId 的资源嵌入 SWF,常与 SymbolClass 配合,关联到 AS3 ByteArray 子类。负载可能是配置、压缩包、媒体、加密数据甚至另一份 SWF;提取器不嗅探格式,也不按大小计数。“二进制 3”只表示三个数据块定义。

字体(Font)

DefineFont 只保存早期字形轮廓;DefineFont2 加入名称、编码映射和可选布局度量;DefineFont3 提高字形坐标精度;DefineFont4 面向 Flash Text Engine,并可嵌入 OpenType CFF 数据。四者都计入“字体”。

这个数字是字体定义标签数,不是字形数或去重后的家族数。作品页另列的“字体 · N 种”来自成功提取并去重的名称;早期定义可能没有名称,多个定义也可能同名,两项数字自然可能不同。DefineFontInfo*DefineFontName 只补充信息,不另算字体。

把这些数字放回作品里看

资源计数描述的是当前 SWF 内嵌了哪些定义,不是文件大小、渲染负担或作者工作量的仪表。一个画面热闹的小游戏可能只是在聪明地复用少数角色;运行时从外部加载的图片、声音和子 SWF 不会算进来,反过来,已经嵌入却从未上场的角色仍会留下一个计数。想继续追查,可以去完整技术信息的标签构成看各代标签的原始次数。

计数器认得标签,不代表播放器已经实现这个资源的每项细节。真正能不能顺利播放,还要看显示列表、脚本、时间轴和媒体解码;遇到怪作品,标签明细、解析备注和实际播放结果要放在一起看。

相关词条

这些资料从哪来

  1. Adobe SWF File Format Specification, Version 19
  2. Ruffle:SWF tag code implementation
  3. Ruffle:SWF tag reader implementation