有没有使用过或了解过此格式的朋友,求解答。
一个图标能占多少内存。。。说实话我不相信一个小小的svg格式图标,能把系统卡成那个样,这必定是个bug。苹果用不卡,麒麟用不卡,就你用一个图标就卡了?
以目前显卡的算力,这点图标算力损耗可以忽略不计。
也就是说一些图标的代码被写进芯片,可以硬解的话,其他方法几乎失去作用。
MP4格式被显卡硬解后,看1080P电源,资源占用显卡算力8%。
不明白为什么用DCI而不用SVG,但在同样屏幕分辨率下,隔壁OK的任务栏图标确实要比DP的清晰好多,这是事实!
不明白为什么用DCI而不用SVG,但在同样屏幕分辨率下,隔壁OK的任务栏图标确实要比DP的清晰好多,这是事实!
你确定OK都用的是SVG?而且系统图标也是分类的吧,中间的应用图标和右边的小图标明显不一样。
不明白为什么用DCI而不用SVG,但在同样屏幕分辨率下,隔壁OK的任务栏图标确实要比DP的清晰好多,这是事实!
DCI是带动画的图标格式
改一下吧,DCI是deepin的超级图标格式,AI给出的都是瞎猜的
以下是官方的specification
https://github.com/linuxdeepin/deepin-specifications/blob/master/unstable/%E5%9B%BE%E6%A0%87%E6%96%87%E4%BB%B6%E8%A7%84%E8%8C%83.md
图标文件规范
警告!此规范内容是不稳定版本,可能会发生破坏兼容性的更新。当无法保障向下兼容时,将会升级此文档的主版本号,如从“1.0”更新到“2.0”。反之,普通更新只会升级次版本号,如“1.0”更新到“1.1”,其对“1.0”版本向下兼容。请在使用前确认此文档的版本号,并为将来可能发生的兼容性变化做好准备。
- 维护者:zccrs zhangjide@uniontech.com
- 版本:1.1
- 修改日期:2022.11.21
- 议题:#5
引言
本规范约定了各类图标文件的内部数据格式要求,以及此类文件的使用规范。
归档打包
dci 文件(以下简称为 dci)为一种归档打包格式,其规定了如何将多个图标文件合并为一个文件。
格式
- 格式名称:
dci
,为 DSG combined icons 的缩写 - mimetype:image/dci,继承自:application/octet-stream
- magic:DCI,类型为 string,offset 为 0
- 此类型对应的图标名:image-dci
- 后缀名:dci
对应的 mimetype 描述文件内容:关于 mimetype 规范的详细设计请查看 http://www.freedesktop.org/standards/shared-mime-info
DSG Icon file format
深度图标文件格式
文件头
dci 使用小端序,文件的元数据位于文件开头。内容如下:
起始地址:结束地址 | 名称 | 大小 | 缺省值 |
---|---|---|---|
0x0000:0x0003 | magic | 4B | DCI |
0x0004:0x0004 | 版本 | 1B | - |
0x0005:0x0007 | 文件数量 | 3B | - |
0x0008:0x0057 | 文件1元数据 | 72B | 格式 |
... | 文件元数据 | - | - |
这里的文件数量指根文件,不包含目录内的子文件。
文件顺序需按照其名称升序排列,此排列不区分文件类型。另外,需遵循自然排序(如“a2”在“a11”之前)规则。
文件的元数据
相对起始地址:相对结束地址 | 名称 | 大小 | 缺省值 |
---|---|---|---|
0x0000:0x0000 | 文件类型 | 1B | 可选值 |
0x0001:0x003F | 文件名 | 63B | - |
0x0040:0x0048 | 内容的大小 | 8B | - |
0x0049:0x???? | 内容 | - | - |
文件名为 UTF-8 编码,必须以 '\0' 结尾,且不可包含 '/' 字符。
目录的内容是:此目标内子目录以及文件的元数据和数据。
值 | 类型 |
---|---|
0 | 保留 |
1 | 文件 |
2 | 目录 |
3 | 链接 |
目录文件也属于文件类型的一种,可在目录下嵌套子目录。
目录内的文件顺序需按照其名称升序排列,此排列不区分文件类型。另外,需遵循英文环境(无国家要求)下的自然排序(如“a2”在“a11”之前)规则。
链接文件
链接的目标可以是“文件”或其它(不可链接自身)“链接”,否则认为此链接目标无效。创建链接时不检查链接的目标是否存在,对链接文件内容的读写操作等价于读写链接的目标,如若链接目标无效或不存在,则读写失败。获取链接的目标路径时,如果链接文件无效,需给出一个空路径。此外,需要提供方法以允许获取链接路径的原始数据。
链接文件的内容格式:
相对起始地址:相对结束地址 | 名称 | 大小 | 缺省值 |
---|---|---|---|
0x0000:0x???? | 目标路径 | 取决于元数据中指定的内容大小 | - |
内容编码为 UTF-8,路径需符合 UNIX 标准,可使用相对路径。相对路径的 "." 和 ".." 仅可用于路径的开头,当"."、".."出现在路径中间时,如 "/./test.txt"、"../a/../",此处的"."和".."需当作文件名称处理。
图标文件规范
在归档打包中描述了 dci 文件的归档规范,本章节将描述 dci 格式的文件目录结构和命名规范。
图标状态
图标适应环境变化时所需要展现的不同形态,分为以下四种状态:
- normal:缺省状态
- disabled :被禁用时的状态,一般表现为不再响应鼠标、键盘等输入事件
- hover:鼠标悬浮在图标上的状态
- pressed:点击后且未释放时的状态
当图标只提供
normal
状态的文件时,可使用一些固定规则对normal
状态进行加工而得到其它状态,此规范不约束加工后的效果。
图标动画
如果对应状态的图片文件具有动画效果,如嵌入了动态的 webp 图片,则应当在图标状态变化时播放动画。动画播放需满足以下规则:
- 初始化状态不自动播放动画,初始为 normal 状态时显示动画第一帧,其它状态显示动画的最后一帧;
- normal 状态动态图的第一帧和最后一帧要等价,即内容完全相同;
- 当从 normal 状态变为 hover 状态时,使用 1.0 倍速正序播放 hover 图片的动画,且停留到最后一帧;
- 当从 hover 状态变为 pressed 状态时,使用 1.0 倍速正序播放 pressed 图片的动画,且停留到最后一帧;
- 当从 normal 状态变为 pressed 状态时,如果存在 hover 状态,则界面效果(仅影响UI,不实际改变图标的当前状态)先变化为 hover 状态,再由 hover 状态变化为 pressed 状态,在此期间的动画使用 2.0(如果 hover 状态是静态图片,则使用 1.0 倍速)倍速正序播放,不同动画图片切换时中间无停顿。否则,如果 hover 状态不存在,则直接使用 1.0 倍速正序播放 pressed 图片的动画。动画播放完毕后停留到最后一帧;
- 当从 hover 状态变为 normal 状态时,使用 1.0 倍速倒序播放 hover 图片动画,不停留到最后一帧,动画播放完毕后当作初始化状态停留到 normal 状态的图片;
- 当从 pressed 状态变为 hover 状态时,使用 1.0 倍速倒序播放 pressed 图片动画,不停留到最后一帧,动画播放完毕后当作初始化状态停留到 hover 状态的图片;
- 当从 pressed 状态变为 normal 状态时,如果存在 hover 状态,则界面效果(仅影响UI,不实际改变图标的当前状态)先变化为 hover 状态,再由 hover 状态变化为 normal,在此期间的动画使用 2.0(如果 hover 状态是静态图片,则使用 1.0 倍速)倍速倒序播放,不同动画图片切换时中间无停顿。否则,如果 hover 状态不存在,则直接使用 1.0 倍速倒序播放 pressed 图片的动画。动画播放完毕后当作初始化状态停留到 normal 状态的图片;
- 当从任意状态变为 disabled 状态时,界面效果(仅影响UI,不实际改变图标的当前状态)先变为(直接变化,不播放任何动画)初始化时的 normal 状态,再使用 1.0 倍速正序播放 disabled 图片的动画,动画播放完毕后停留到最后一帧;
- 当从 disabled 状态变为任意状态时,使用 1.0 倍速倒序播放 disabled 图片的动画,最后停留在 normal 状态(仅影响UI,不实际改变图标的当前状态)对应的图片;
- 只有最后一个播放的动画允许循环播放,如从 normal 状态变为 pressed 状态,顺序播放 hover 和 pressed 对应的动画时,hover 的动画不允许循环播放;
- 当需要播放动画时,如果当前已经有动画正在播放,如果待播放的动画是当前动画的逆播放,则暂停当前动画,且从暂停的帧开始倒序播放。否则如果待播放的动画是当前动画的延续(即可以衔接到一起,如从 normal 状态变为 hover 状态,在播放动画期间又变为了 pressed 状态),则等到当前动画播放完毕后接着播放新动画,且当前动画禁止重复播放。除此之外的情况则停止当前动画,立即开始播放新动画;
- normal 状态的动画用于需要突显此图标的情况,由使用方决定在合适的时机播放。一些使用场景:某个图标刚被新增到某个地方显示时可以播放 normal 的动画,比如新安装一个应用,这个应用的图标出现在 Launcher 上时,或者是把一个应用图标发送到 Dock 或 Desktop 上面时;当一个应用最小化到任务栏时,任务栏上可以播放 normal 状态的动画。
伪代码实现:
enum Flags {
Continue = 1,
InvertedOrder = 2,
IgnoreLastImageLoop = 4,
AllowNonLastImageLoop = 8
};
fn playImages(images, speed, flags)
{
...
}
fn playAnimation(oldMode, newMode)
{
if (oldMode == Normal) {
if (newMode == Normal) {
showImage(Normal);
} else if (newMode == Hover) {
if (hover.supportsAnimation()) {
playImages({hover}, 1.0);
} else {
showImage(Hover);
}
} else if (newMode == Pressed) {
if (pressed.supportsAnimation()) {
if (hover.supportsAnimation()) {
playImages({hover, pressed}, 2.0);
} else {
playImages({pressed}, 1.0);
}
} else {
showImage(Pressed);
}
} else if (newMode == Disabled) {
if (disabled.supportsAnimation()) {
playImages({disabled}, 1.0, Flags::IgnoreLastImageLoop);
} else {
showImage(Disabled);
}
}
} else if (oldMode == Hover) {
if (newMode == Normal) {
if (hover.supportsAnimation()) {
setFinishedImage(Normal);
playImages({hover}, 1.0, Flags::InvertedOrder | Flags::IgnoreLastImageLoop);
} else {
showImage(Normal);
}
} else if (newMode == Pressed) {
if (pressed.isNull()) {
if (hover.supportsAnimation()) {
playImages({hover}, 1.0, Flags::InvertedOrder | Flags::IgnoreLastImageLoop);
} else {
showImage(Normal);
}
return;
}
if (pressed.supportsAnimation()) {
playImages({pressed}, 1.0);
} else {
showImage(Pressed);
}
} else if (newMode == Disabled) {
if (disabled.isNull()) {
showImage(Normal);
return;
}
if (disabled.supportsAnimation()) {
playImages({disabled}, 1.0, Flags::IgnoreLastImageLoop);
} else {
showImage(Disabled);
}
}
} else if (oldMode == Pressed) {
if (newMode == Normal) {
if (!pressed.supportsAnimation()) {
showImage(Normal);
return false;
}
setFinishedImage(Normal);
if (hover.supportsAnimation()) {
playImages({hover, pressed}, 2.0, Flags::InvertedOrder | Flags::IgnoreLastImageLoop);
} else {
playImages({pressed}, 1.0, Flags::InvertedOrder | Flags::IgnoreLastImageLoop);
}
} else if (newMode == Hover) {
if (pressed.isNull()) {
if (hover.supportsAnimation()) {
playImages({hover}, 1.0);
} else {
showImage(Hover);
}
return;
}
if (pressed.supportsAnimation()) {
ensureHoverModeLastImage();
finishedImage = hoverModeLastImage;
playImages({pressed}, 1.0, Flags::InvertedOrder | Flags::IgnoreLastImageLoop);
} else {
showImage(Hover);
}
} else if (newMode == Disabled) {
if (disabled.isNull()) {
showImage(Normal);
return;
}
if (disabled.supportsAnimation()) {
playImages({disabled}, 1.0, Flags::IgnoreLastImageLoop);
} else {
showImage(Disabled);
}
}
} else if (oldMode == Disabled) {
if (disabled.supportsAnimation()) {
setFinishedImage(Normal);
playImages({disabled}, 1.0, Flags::InvertedOrder | Flags::IgnoreLastImageLoop);
} else {
showImage(Normal);
}
}
return;
}
缩放倍数
为适应不同的 DPI,图标大小的缩放倍数分类以下三类:
- 1:无缩放(1倍)
- 2:放大2倍
- 3:放大3倍
色调类型
为适应不同的明暗色,图标按色调可分为以下两类:
- light:用于亮色环境
- dark:用于暗色环境
一个图标可能包含 图标大小 x 图标状态 x 色调类型 x 缩放倍数 x 图层数
个图片文件,以名称为 dde
的图标举例,封装为 dci 格式后的目录结构如下:
├── 16
| ├── disabled.light
| │ ├── 1
| │ │ └── 1.0.png
| │ ├── 2
| │ │ └── 2.0.jpg
| │ └── 3
| │ └── 3.0.webp
| │
| └── normal.light
│ ├── 1
│ │ ├── 1.0.png
│ │ └── 2.1.png
│ ├── 2
│ │ ├── 1.0.png
│ │ └── 2.1.png
│ └── 3
│ ├── 1.0.png
│ └── 2.1.png
│
├── 32
│ └── hover.light
│ ├── 1
│ │ └── 1.0.png
│ └── 1
│ ├── 1.0.png
│ └── 2.1.png
└── 512
└── pressed.dark
├── 1
│ └── 1.0.png
├── 2
│ └── 2.0.png
└── 3
└── 3.0.png
- 一级目录按
图标大小
创建 - 二级目录按
图标状态.色调类型
创建 - 三级目录的名称格式为:
缩放倍数
,,可以存放多个缩放比系数来适配系统的缩放比。例如上述示例:缩放比系数在1和2之间时,选择 2,大于 2 时,选择 2 ,默认情况下选择 1。目前提供的图标中,为了保证尽量减少图标文件的大小,仅保存缩放比为 3 的文件。在软件层面进行缩放。 - 四级目录中是图片文件,描述图标图片文件(图层)所携带的信息。这些信息中,包含:图层优先级、外边框数值、调色板格式、颜色调整数值、图层格式。可以通过下述文件表示:
目录/文件名中各项变量的可选值:
变量 | 可选值 | 备注 |
---|---|---|
图标大小 | 整数 | 假设查找的图标大小为 16,则优先查找大于等于 16 的图标,无法找到时,可使用最大的图标资源,且可以忽略缩放倍数,以使用大小最匹配的图标资源 |
图标状态 | normal 、 disabled 、 hover 、pressed |
normal 状态的 light 图标必须存在,其它状态为可选,查找图标时,如果对应状态不存在,则允许使用 normal.light 状态代替(fallback) |
色调类型 | light 、 dark |
查找图标时色调类型必须完全匹配 |
缩放倍数 | 1 、 2 、 3 |
至少要提供此三类缩放比例的图标,其它更高的缩放为可选,如目标缩放倍数的图片不存在,则可以选用更高倍数的图,如无更高倍数的图,则可以使用低倍数中较高的图片 |
图层 | 整数 | 优先级代表图层的绘制顺序,从 1-n 进行绘制,最底层的图层会被上层图层覆盖。 |
外边框 | 整数 | 外边框(padding):外边框在有阴影效果的图标中充分利用。padding 代表图层外围不被控件大小覆盖的区域。 |
调色板 | 整数:-1 , 0 , 1 , 2 , 3 |
当无调色板时,该部分的数值为空。调色板格式分为5种,无(无需指定)、前景色(0)、背景色(1)、高亮前景色(2)、高亮色(3) |
色调/饱和度/亮度/rgba调整参数 | 整数:-100 ~ 100 |
用于调节图片填充颜色的色调/饱和度/亮度/rgba等参数的百分比,可以通过 -100~100 的值调整 0~255 的颜色取值范围(如:调色板中颜色的亮度为 50 ,这里亮度调整参数为 20 时,调整后亮度为 50 + (255 - 50) * 20% = 91 。 亮度调整参数为 -20 时调整后亮度为 50 - 50x20% = 40 )。当三原色调整参数为 -100 时,颜色为 黑色,参数为 100 时,颜色为 白色 。主题填充颜色来自调色板中的基础颜色。 |
后缀名 | png 、jpg 、webp |
图片格式后缀,如果图层存在调色板格式,就意味着可以优化其大小,转化为 alpha8 格式,使用 .alpha8 作为后缀,进行标识,在软件渲染时进行进行复原。注意 webp 格式的图片显示需要安装对应格式的插件( 如 qt5-image-formats-plugins ) |
![]() |
||
dci-demo.zip |
一个图标能占多少内存。。。说实话我不相信一个小小的svg格式图标,能把系统卡成那个样,这必定是个bug。苹果用不卡,麒麟用不卡,就你用一个图标就卡了?
qt原生的svg支持比较简陋,复杂的SVG图标会出现渲染错误的情况
deepin 有专门对这个做过扩展,让DDE上可以较好地展示svg
从15 20 没有这个问题而23 25 有这个问题来推测,盲猜是qt5版本的扩展没有性能问题,而qt6版本的扩展有性能问题,因为23后期和25的桌面组件是qt6的,而15 20是qt5的
或者推测问题并不出在deepin对qt的扩展上,而是deepin-shell的实现有问题,比如可能把图标渲染的进程和右键菜单的进程写到一个里面了,而先前的dde-desktop是分开的,所以不会卡
这些仅仅是个人推测,没看代码盲猜的
你问的第一个ai是哪个AI,我避一下雷。
你问的第一个ai是哪个AI,我避一下雷。
百度的,哈哈。我已经将它删除了。
改一下吧,DCI是deepin的超级图标格式,AI给出的都是瞎猜的
以下是官方的specification
https://github.com/linuxdeepin/deepin-specifications/blob/master/unstable/%E5%9B%BE%E6%A0%87%E6%96%87%E4%BB%B6%E8%A7%84%E8%8C%83.md
图标文件规范
警告!此规范内容是不稳定版本,可能会发生破坏兼容性的更新。当无法保障向下兼容时,将会升级此文档的主版本号,如从“1.0”更新到“2.0”。反之,普通更新只会升级次版本号,如“1.0”更新到“1.1”,其对“1.0”版本向下兼容。请在使用前确认此文档的版本号,并为将来可能发生的兼容性变化做好准备。
- 维护者:zccrs zhangjide@uniontech.com
- 版本:1.1
- 修改日期:2022.11.21
- 议题:#5
引言
本规范约定了各类图标文件的内部数据格式要求,以及此类文件的使用规范。
归档打包
dci 文件(以下简称为 dci)为一种归档打包格式,其规定了如何将多个图标文件合并为一个文件。
格式
- 格式名称:
dci
,为 DSG combined icons 的缩写 - mimetype:image/dci,继承自:application/octet-stream
- magic:DCI,类型为 string,offset 为 0
- 此类型对应的图标名:image-dci
- 后缀名:dci
对应的 mimetype 描述文件内容:关于 mimetype 规范的详细设计请查看 http://www.freedesktop.org/standards/shared-mime-info
DSG Icon file format
深度图标文件格式
文件头
dci 使用小端序,文件的元数据位于文件开头。内容如下:
起始地址:结束地址 | 名称 | 大小 | 缺省值 |
---|---|---|---|
0x0000:0x0003 | magic | 4B | DCI |
0x0004:0x0004 | 版本 | 1B | - |
0x0005:0x0007 | 文件数量 | 3B | - |
0x0008:0x0057 | 文件1元数据 | 72B | 格式 |
... | 文件元数据 | - | - |
这里的文件数量指根文件,不包含目录内的子文件。
文件顺序需按照其名称升序排列,此排列不区分文件类型。另外,需遵循自然排序(如“a2”在“a11”之前)规则。
文件的元数据
相对起始地址:相对结束地址 | 名称 | 大小 | 缺省值 |
---|---|---|---|
0x0000:0x0000 | 文件类型 | 1B | 可选值 |
0x0001:0x003F | 文件名 | 63B | - |
0x0040:0x0048 | 内容的大小 | 8B | - |
0x0049:0x???? | 内容 | - | - |
文件名为 UTF-8 编码,必须以 '\0' 结尾,且不可包含 '/' 字符。
目录的内容是:此目标内子目录以及文件的元数据和数据。
值 | 类型 |
---|---|
0 | 保留 |
1 | 文件 |
2 | 目录 |
3 | 链接 |
目录文件也属于文件类型的一种,可在目录下嵌套子目录。
目录内的文件顺序需按照其名称升序排列,此排列不区分文件类型。另外,需遵循英文环境(无国家要求)下的自然排序(如“a2”在“a11”之前)规则。
链接文件
链接的目标可以是“文件”或其它(不可链接自身)“链接”,否则认为此链接目标无效。创建链接时不检查链接的目标是否存在,对链接文件内容的读写操作等价于读写链接的目标,如若链接目标无效或不存在,则读写失败。获取链接的目标路径时,如果链接文件无效,需给出一个空路径。此外,需要提供方法以允许获取链接路径的原始数据。
链接文件的内容格式:
相对起始地址:相对结束地址 | 名称 | 大小 | 缺省值 |
---|---|---|---|
0x0000:0x???? | 目标路径 | 取决于元数据中指定的内容大小 | - |
内容编码为 UTF-8,路径需符合 UNIX 标准,可使用相对路径。相对路径的 "." 和 ".." 仅可用于路径的开头,当"."、".."出现在路径中间时,如 "/./test.txt"、"../a/../",此处的"."和".."需当作文件名称处理。
图标文件规范
在归档打包中描述了 dci 文件的归档规范,本章节将描述 dci 格式的文件目录结构和命名规范。
图标状态
图标适应环境变化时所需要展现的不同形态,分为以下四种状态:
- normal:缺省状态
- disabled :被禁用时的状态,一般表现为不再响应鼠标、键盘等输入事件
- hover:鼠标悬浮在图标上的状态
- pressed:点击后且未释放时的状态
当图标只提供
normal
状态的文件时,可使用一些固定规则对normal
状态进行加工而得到其它状态,此规范不约束加工后的效果。
图标动画
如果对应状态的图片文件具有动画效果,如嵌入了动态的 webp 图片,则应当在图标状态变化时播放动画。动画播放需满足以下规则:
- 初始化状态不自动播放动画,初始为 normal 状态时显示动画第一帧,其它状态显示动画的最后一帧;
- normal 状态动态图的第一帧和最后一帧要等价,即内容完全相同;
- 当从 normal 状态变为 hover 状态时,使用 1.0 倍速正序播放 hover 图片的动画,且停留到最后一帧;
- 当从 hover 状态变为 pressed 状态时,使用 1.0 倍速正序播放 pressed 图片的动画,且停留到最后一帧;
- 当从 normal 状态变为 pressed 状态时,如果存在 hover 状态,则界面效果(仅影响UI,不实际改变图标的当前状态)先变化为 hover 状态,再由 hover 状态变化为 pressed 状态,在此期间的动画使用 2.0(如果 hover 状态是静态图片,则使用 1.0 倍速)倍速正序播放,不同动画图片切换时中间无停顿。否则,如果 hover 状态不存在,则直接使用 1.0 倍速正序播放 pressed 图片的动画。动画播放完毕后停留到最后一帧;
- 当从 hover 状态变为 normal 状态时,使用 1.0 倍速倒序播放 hover 图片动画,不停留到最后一帧,动画播放完毕后当作初始化状态停留到 normal 状态的图片;
- 当从 pressed 状态变为 hover 状态时,使用 1.0 倍速倒序播放 pressed 图片动画,不停留到最后一帧,动画播放完毕后当作初始化状态停留到 hover 状态的图片;
- 当从 pressed 状态变为 normal 状态时,如果存在 hover 状态,则界面效果(仅影响UI,不实际改变图标的当前状态)先变化为 hover 状态,再由 hover 状态变化为 normal,在此期间的动画使用 2.0(如果 hover 状态是静态图片,则使用 1.0 倍速)倍速倒序播放,不同动画图片切换时中间无停顿。否则,如果 hover 状态不存在,则直接使用 1.0 倍速倒序播放 pressed 图片的动画。动画播放完毕后当作初始化状态停留到 normal 状态的图片;
- 当从任意状态变为 disabled 状态时,界面效果(仅影响UI,不实际改变图标的当前状态)先变为(直接变化,不播放任何动画)初始化时的 normal 状态,再使用 1.0 倍速正序播放 disabled 图片的动画,动画播放完毕后停留到最后一帧;
- 当从 disabled 状态变为任意状态时,使用 1.0 倍速倒序播放 disabled 图片的动画,最后停留在 normal 状态(仅影响UI,不实际改变图标的当前状态)对应的图片;
- 只有最后一个播放的动画允许循环播放,如从 normal 状态变为 pressed 状态,顺序播放 hover 和 pressed 对应的动画时,hover 的动画不允许循环播放;
- 当需要播放动画时,如果当前已经有动画正在播放,如果待播放的动画是当前动画的逆播放,则暂停当前动画,且从暂停的帧开始倒序播放。否则如果待播放的动画是当前动画的延续(即可以衔接到一起,如从 normal 状态变为 hover 状态,在播放动画期间又变为了 pressed 状态),则等到当前动画播放完毕后接着播放新动画,且当前动画禁止重复播放。除此之外的情况则停止当前动画,立即开始播放新动画;
- normal 状态的动画用于需要突显此图标的情况,由使用方决定在合适的时机播放。一些使用场景:某个图标刚被新增到某个地方显示时可以播放 normal 的动画,比如新安装一个应用,这个应用的图标出现在 Launcher 上时,或者是把一个应用图标发送到 Dock 或 Desktop 上面时;当一个应用最小化到任务栏时,任务栏上可以播放 normal 状态的动画。
伪代码实现:
enum Flags {
Continue = 1,
InvertedOrder = 2,
IgnoreLastImageLoop = 4,
AllowNonLastImageLoop = 8
};
fn playImages(images, speed, flags)
{
...
}
fn playAnimation(oldMode, newMode)
{
if (oldMode == Normal) {
if (newMode == Normal) {
showImage(Normal);
} else if (newMode == Hover) {
if (hover.supportsAnimation()) {
playImages({hover}, 1.0);
} else {
showImage(Hover);
}
} else if (newMode == Pressed) {
if (pressed.supportsAnimation()) {
if (hover.supportsAnimation()) {
playImages({hover, pressed}, 2.0);
} else {
playImages({pressed}, 1.0);
}
} else {
showImage(Pressed);
}
} else if (newMode == Disabled) {
if (disabled.supportsAnimation()) {
playImages({disabled}, 1.0, Flags::IgnoreLastImageLoop);
} else {
showImage(Disabled);
}
}
} else if (oldMode == Hover) {
if (newMode == Normal) {
if (hover.supportsAnimation()) {
setFinishedImage(Normal);
playImages({hover}, 1.0, Flags::InvertedOrder | Flags::IgnoreLastImageLoop);
} else {
showImage(Normal);
}
} else if (newMode == Pressed) {
if (pressed.isNull()) {
if (hover.supportsAnimation()) {
playImages({hover}, 1.0, Flags::InvertedOrder | Flags::IgnoreLastImageLoop);
} else {
showImage(Normal);
}
return;
}
if (pressed.supportsAnimation()) {
playImages({pressed}, 1.0);
} else {
showImage(Pressed);
}
} else if (newMode == Disabled) {
if (disabled.isNull()) {
showImage(Normal);
return;
}
if (disabled.supportsAnimation()) {
playImages({disabled}, 1.0, Flags::IgnoreLastImageLoop);
} else {
showImage(Disabled);
}
}
} else if (oldMode == Pressed) {
if (newMode == Normal) {
if (!pressed.supportsAnimation()) {
showImage(Normal);
return false;
}
setFinishedImage(Normal);
if (hover.supportsAnimation()) {
playImages({hover, pressed}, 2.0, Flags::InvertedOrder | Flags::IgnoreLastImageLoop);
} else {
playImages({pressed}, 1.0, Flags::InvertedOrder | Flags::IgnoreLastImageLoop);
}
} else if (newMode == Hover) {
if (pressed.isNull()) {
if (hover.supportsAnimation()) {
playImages({hover}, 1.0);
} else {
showImage(Hover);
}
return;
}
if (pressed.supportsAnimation()) {
ensureHoverModeLastImage();
finishedImage = hoverModeLastImage;
playImages({pressed}, 1.0, Flags::InvertedOrder | Flags::IgnoreLastImageLoop);
} else {
showImage(Hover);
}
} else if (newMode == Disabled) {
if (disabled.isNull()) {
showImage(Normal);
return;
}
if (disabled.supportsAnimation()) {
playImages({disabled}, 1.0, Flags::IgnoreLastImageLoop);
} else {
showImage(Disabled);
}
}
} else if (oldMode == Disabled) {
if (disabled.supportsAnimation()) {
setFinishedImage(Normal);
playImages({disabled}, 1.0, Flags::InvertedOrder | Flags::IgnoreLastImageLoop);
} else {
showImage(Normal);
}
}
return;
}
缩放倍数
为适应不同的 DPI,图标大小的缩放倍数分类以下三类:
- 1:无缩放(1倍)
- 2:放大2倍
- 3:放大3倍
色调类型
为适应不同的明暗色,图标按色调可分为以下两类:
- light:用于亮色环境
- dark:用于暗色环境
一个图标可能包含 图标大小 x 图标状态 x 色调类型 x 缩放倍数 x 图层数
个图片文件,以名称为 dde
的图标举例,封装为 dci 格式后的目录结构如下:
├── 16
| ├── disabled.light
| │ ├── 1
| │ │ └── 1.0.png
| │ ├── 2
| │ │ └── 2.0.jpg
| │ └── 3
| │ └── 3.0.webp
| │
| └── normal.light
│ ├── 1
│ │ ├── 1.0.png
│ │ └── 2.1.png
│ ├── 2
│ │ ├── 1.0.png
│ │ └── 2.1.png
│ └── 3
│ ├── 1.0.png
│ └── 2.1.png
│
├── 32
│ └── hover.light
│ ├── 1
│ │ └── 1.0.png
│ └── 1
│ ├── 1.0.png
│ └── 2.1.png
└── 512
└── pressed.dark
├── 1
│ └── 1.0.png
├── 2
│ └── 2.0.png
└── 3
└── 3.0.png
- 一级目录按
图标大小
创建 - 二级目录按
图标状态.色调类型
创建 - 三级目录的名称格式为:
缩放倍数
,,可以存放多个缩放比系数来适配系统的缩放比。例如上述示例:缩放比系数在1和2之间时,选择 2,大于 2 时,选择 2 ,默认情况下选择 1。目前提供的图标中,为了保证尽量减少图标文件的大小,仅保存缩放比为 3 的文件。在软件层面进行缩放。 - 四级目录中是图片文件,描述图标图片文件(图层)所携带的信息。这些信息中,包含:图层优先级、外边框数值、调色板格式、颜色调整数值、图层格式。可以通过下述文件表示:
目录/文件名中各项变量的可选值:
变量 | 可选值 | 备注 |
---|---|---|
图标大小 | 整数 | 假设查找的图标大小为 16,则优先查找大于等于 16 的图标,无法找到时,可使用最大的图标资源,且可以忽略缩放倍数,以使用大小最匹配的图标资源 |
图标状态 | normal 、 disabled 、 hover 、pressed |
normal 状态的 light 图标必须存在,其它状态为可选,查找图标时,如果对应状态不存在,则允许使用 normal.light 状态代替(fallback) |
色调类型 | light 、 dark |
查找图标时色调类型必须完全匹配 |
缩放倍数 | 1 、 2 、 3 |
至少要提供此三类缩放比例的图标,其它更高的缩放为可选,如目标缩放倍数的图片不存在,则可以选用更高倍数的图,如无更高倍数的图,则可以使用低倍数中较高的图片 |
图层 | 整数 | 优先级代表图层的绘制顺序,从 1-n 进行绘制,最底层的图层会被上层图层覆盖。 |
外边框 | 整数 | 外边框(padding):外边框在有阴影效果的图标中充分利用。padding 代表图层外围不被控件大小覆盖的区域。 |
调色板 | 整数:-1 , 0 , 1 , 2 , 3 |
当无调色板时,该部分的数值为空。调色板格式分为5种,无(无需指定)、前景色(0)、背景色(1)、高亮前景色(2)、高亮色(3) |
色调/饱和度/亮度/rgba调整参数 | 整数:-100 ~ 100 |
用于调节图片填充颜色的色调/饱和度/亮度/rgba等参数的百分比,可以通过 -100~100 的值调整 0~255 的颜色取值范围(如:调色板中颜色的亮度为 50 ,这里亮度调整参数为 20 时,调整后亮度为 50 + (255 - 50) * 20% = 91 。 亮度调整参数为 -20 时调整后亮度为 50 - 50x20% = 40 )。当三原色调整参数为 -100 时,颜色为 黑色,参数为 100 时,颜色为 白色 。主题填充颜色来自调色板中的基础颜色。 |
后缀名 | png 、jpg 、webp |
图片格式后缀,如果图层存在调色板格式,就意味着可以优化其大小,转化为 alpha8 格式,使用 .alpha8 作为后缀,进行标识,在软件渲染时进行进行复原。注意 webp 格式的图片显示需要安装对应格式的插件( 如 qt5-image-formats-plugins ) |
![]() |
||
dci-demo.zip |
大神,你搞这么长的文档做什么,就你的了解分析说明呀,有对比更好。
个人理解dci格式是类似mac的icns、windows的ico,一个图标资源容器。但是添加了鼠标划过、按下的一些效果以及动画特效、图层之类,也有点类似图标数据库。与svg相比应该更耗计算资源一些。当前Linux的图标组织方式有点松散,一个完善一点的图标主题动辄数千个文件,dci这种类数据库格式的就更简洁一些。目前就是还没有看到deepin发布专用的dci图标制作工具,DIY上手难度高一点。
另外,dci格式的图标存储路径是:/usr/share/dsg/icons
个人理解dci格式是类似mac的icns、windows的ico,一个图标资源容器。但是添加了鼠标划过、按下的一些效果以及动画特效、图层之类,也有点类似图标数据库。与svg相比应该更耗计算资源一些。当前Linux的图标组织方式有点松散,一个完善一点的图标主题动辄数千个文件,dci这种类数据库格式的就更简洁一些。目前就是还没有看到deepin发布专用的dci图标制作工具,DIY上手难度高一点。
另外,dci格式的图标存储路径是:/usr/share/dsg/icons
好家伙,1262,够全的,可惜不知道如何打开。
好家伙,1262,够全的,可惜不知道如何打开。
好像找到了创建dci的工具,@zccrs 写的python GUI工具,项目地址在:https://github.com/zccrs/comfyui-dci?tab=readme-ov-file#%E4%B8%AD%E6%96%87
你可以去安装看看。
向你学习
大神,你搞这么长的文档做什么,就你的了解分析说明呀,有对比更好。
你可以简单理解为 DCI 格式的图标是打包了一套 什么深色模式 浅色模式的都在这一个文件里边,然后根据设置动态切换
根据下边这个图也可以理解 原来是一堆图标 分散在各目录 现在把着堆图标打包成了一个
├── 16
| ├── disabled.light
| │ ├── 1
| │ │ └── 1.0.png
| │ ├── 2
| │ │ └── 2.0.jpg
| │ └── 3
| │ └── 3.0.webp
| │
| └── normal.light
│ ├── 1
│ │ ├── 1.0.png
│ │ └── 2.1.png
│ ├── 2
│ │ ├── 1.0.png
│ │ └── 2.1.png
│ └── 3
│ ├── 1.0.png
│ └── 2.1.png
│
├── 32
│ └── hover.light
│ ├── 1
│ │ └── 1.0.png
│ └── 1
│ ├── 1.0.png
│ └── 2.1.png
└── 512
└── pressed.dark
├── 1
│ └── 1.0.png
├── 2
│ └── 2.0.png
└── 3
└── 3.0.png
个人理解dci格式是类似mac的icns、windows的ico,一个图标资源容器。但是添加了鼠标划过、按下的一些效果以及动画特效、图层之类,也有点类似图标数据库。与svg相比应该更耗计算资源一些。当前Linux的图标组织方式有点松散,一个完善一点的图标主题动辄数千个文件,dci这种类数据库格式的就更简洁一些。目前就是还没有看到deepin发布专用的dci图标制作工具,DIY上手难度高一点。
另外,dci格式的图标存储路径是:/usr/share/dsg/icons
制作工具有 但是命令行的
我印象中是这种的,具体的命令你可以 dci --help 看看
dci 打包 -i 文件目录 -o dci文件
dci 解包 -i dci文件 -o 目录
一个图标能占多少内存。。。说实话我不相信一个小小的svg格式图标,能把系统卡成那个样,这必定是个bug。苹果用不卡,麒麟用不卡,就你用一个图标就卡了?
占很大,你去看看deepin的svg图标,他妈的里面塞了个png,一个svg图标4m大小你敢信?
你可以简单理解为 DCI 格式的图标是打包了一套 什么深色模式 浅色模式的都在这一个文件里边,然后根据设置动态切换
根据下边这个图也可以理解 原来是一堆图标 分散在各目录 现在把着堆图标打包成了一个
├── 16
| ├── disabled.light
| │ ├── 1
| │ │ └── 1.0.png
| │ ├── 2
| │ │ └── 2.0.jpg
| │ └── 3
| │ └── 3.0.webp
| │
| └── normal.light
│ ├── 1
│ │ ├── 1.0.png
│ │ └── 2.1.png
│ ├── 2
│ │ ├── 1.0.png
│ │ └── 2.1.png
│ └── 3
│ ├── 1.0.png
│ └── 2.1.png
│
├── 32
│ └── hover.light
│ ├── 1
│ │ └── 1.0.png
│ └── 1
│ ├── 1.0.png
│ └── 2.1.png
└── 512
└── pressed.dark
├── 1
│ └── 1.0.png
├── 2
│ └── 2.0.png
└── 3
└── 3.0.png
这和当年的PCD有点相似呀,也是通过预存多级分辨率实现了“一档多用途”,用户打开时需主动选择适配当前输出场景的分辨率层级,可惜这格式一直没发展起来。
制作工具有 但是命令行的
我印象中是这种的,具体的命令你可以 dci --help 看看
dci 打包 -i 文件目录 -o dci文件
dci 解包 -i dci文件 -o 目录
晕,这样来说我能不能简单的将DCI理解成一个压缩包呀。感觉优势和不足都比较明显呀。
Popular Ranking
ChangePopular Events
More
原因起源于:https://bbs.deepin.org.cn/post/288947
7楼官方表示:现在25的系统自带应用图标都已经换成了DCI格式,svg 的渲染会比较费内存,所以会引起桌面卡顿问题。
因为没有了解过,问了AI还闹了笑话,后面又问了另一个AI,好像这个AI没理解错误,但不知所讲是否准确,不知坛里有没大神,能够教下我。
对了,这里是deepin官方文档的解释:https://docs.deepin.org/linuxdeepin/master/dtkcore/dci.html
选择系统图标时,SVG图标通常是更通用、更强大且更推荐的选择。虽然“DCI图标”不是一个标准的行业术语,但我理解你可能指的是“基于设备上下文或分辨率动态调整的图标”或类似概念(有时也称为“响应式图标”)。让我们来详细比较一下:
📐 1. SVG图标 (Scalable Vector Graphics)
</code>, <code><desc></code>)和ARIA属性,对屏幕阅读器友好。</li> <li><strong>设计保真度:</strong> 线条清晰锐利,不受分辨率限制。</li> <li><strong>易于修改:</strong> 在代码编辑器或矢量图形软件中修改方便(如调整颜色、形状)。</li> <li><strong>现代Web标准:</strong> 是W3C标准,被所有现代浏览器完美支持,是构建响应式、现代化Web应用的基石。</li> <li><strong>SEO友好:</strong> 文本内容可以被搜索引擎索引(如果是内嵌文本而非纯路径)。</li> </ul> </li> <li><strong>缺点:</strong> <ul> <li><strong>复杂图形性能:</strong> 包含大量复杂路径或渐变的高细节SVG可能比简单位图渲染更慢(但系统图标通常很简单,此问题不突出)。</li> <li><strong>学习曲线:</strong> 需要理解SVG DOM结构或矢量编辑工具才能高效创建和修改。</li> <li><strong>跨浏览器一致性:</strong> 极少数情况下,非常复杂的SVG特性在不同浏览器中可能有微小渲染差异(系统图标通常避免复杂特性)。</li> </ul> </li> </ul> <h2 id="--2---DCI图标----响应式-上下文感知图标--假设含义-">📱 2. “DCI图标” / 响应式/上下文感知图标 (假设含义)</h2> <ul> <li><strong>核心概念:</strong> 根据设备类型、屏幕尺寸、分辨率、像素密度、甚至用户偏好等“设备上下文信息”,提供或切换到最合适的图标资源(可能是位图或矢量)。</li> <li><strong>可能的实现方式:</strong> <ul> <li><strong>位图方案:</strong> 提供不同尺寸(如16x16, 24x24, 32x32, 48x48)和不同分辨率(1x, 2x, 3x)的PNG/JPG图标集合,通过HTML的 <code>srcset</code>和 <code>sizes</code>属性或CSS媒体查询选择。</li> <li><strong>混合方案:</strong> 使用SVG作为基础,但在特定场景(如极小的尺寸)使用专门优化的位图替代。</li> <li><strong>SVG方案:</strong> 使用单个SVG文件,但利用CSS媒体查*根据上下文改变其样式(如显示/隐藏某些部分、改变颜色)。</li> </ul> </li> <li><strong>优点:</strong> <ul> <li><strong>极致优化潜力:</strong> 理论上可以为每种特定场景提供最精确优化的资源(尤其是针对复杂图标在特定小尺寸下的像素级控制)。</li> <li><strong>解决SVG小尺寸渲染问题:</strong> 在非常小的尺寸下,某些复杂SVG的细节可能模糊或粘连,此时专门绘制的位图可能更清晰(虽然现代渲染引擎已大幅改善此问题)。</li> </ul> </li> <li><strong>缺点:</strong> <ul> <li><strong>复杂性:</strong> 需要生成、管理和维护多套资源(不同尺寸/分辨率)。</li> <li><strong>HTTP请求:</strong> 使用多个位图文件会增加HTTP请求数量(虽然HTTP/2缓解了此问题,缓存也有效)。</li> <li><strong>文件总体积更大:</strong> 存储多套资源的总大小通常远大于单个SVG文件。</li> <li><strong>不够灵活:</strong> 改变颜色或样式通常需要提供不同颜色的整套位图资源。</li> <li><strong>可访问性和交互性:</strong> 位图本身不具备SVG的可编程性和丰富的可访问性支持(需额外工作)。</li> <li><strong>非矢量:</strong> 位图资源无法无限缩放,在新出现的高分辨率设备上可能显得模糊。</li> </ul> </li> </ul> <h2 id="--结论与建议-SVG是首选-DCI-响应式作为补充优化">🏆 结论与建议:SVG是首选,DCI/响应式作为补充优化</h2> <ol> <li><strong>首选SVG:</strong> 对于绝大多数系统图标场景,<strong>SVG是绝对的首选和现代最佳实践</strong>。它完美解决了响应式设计的核心需求(无限缩放),同时提供文件小、可编程、可访问性好等巨大优势。现代UI框架和设计系统(如Material Design, Apple’s SF Symbols)都强烈依赖SVG图标。</li> <li><strong>“DCI”/响应式理念仍有价值,但通常配合SVG使用:</strong> <ul> <li><strong>核心是SVG:</strong> 优先使用单个SVG图标。</li> <li><strong>利用SVG内置响应性:</strong> 使用CSS媒体查询改变SVG图标的尺寸、颜色或内部元素的显示/隐藏。</li> <li><strong>极端情况优化(位图后备):</strong> 仅在<strong>极少数</strong>情况下,当某个图标在<strong>特定极小尺寸</strong>下(例如小于16px)且SVG渲染效果确实不佳时,可以考虑使用 <code><picture></code>元素或CSS媒体查询为该特定断点提供一张专门优化过的位图(PNG)作为后备。但这应该是例外,而非规则。</li> <li><strong>利用 <code>srcset</code> for SVG (谨慎):</strong> 如果有<strong>截然不同设计</strong>的SVG版本(比如极简版用于小尺寸,详细版用于大尺寸),可以使用 <code>srcset</code>。但通常更推荐使用CSS切换单个SVG的样式。</li> </ul> </li> </ol> <h2 id="--简单对比表">📊 简单对比表</h2> <table> <thead> <tr> <th align="left">特性</th> <th align="left">SVG 图标</th> <th align="left">“DCI”/响应式图标 (主要指位图方案)</th> </tr> </thead> <tbody> <tr> <td align="left"><strong>缩放性</strong></td> <td align="left">⭐⭐⭐ 无限缩放,完美清晰</td> <td align="left">⚠️ 有限缩放,大尺寸或高分辨率下模糊</td> </tr> <tr> <td align="left"><strong>文件大小</strong></td> <td align="left">⭐⭐⭐ 通常非常小 (简单图标)</td> <td align="left">⚠️ 需要多套文件,总体积较大</td> </tr> <tr> <td align="left"><strong>HTTP请求</strong></td> <td align="left">⭐⭐⭐ 通常1个 (或内联)</td> <td align="left">⚠️ 可能需要多个请求 (不同分辨率/尺寸)</td> </tr> <tr> <td align="left"><strong>颜色/样式修改</strong></td> <td align="left">⭐⭐⭐ 通过CSS轻松修改</td> <td align="left">❌ 困难,需提供多套资源</td> </tr> <tr> <td align="left"><strong>动画/交互</strong></td> <td align="left">⭐⭐⭐ 支持CSS/JS丰富动画和交互</td> <td align="left">⚠️ 有限支持 (通常需CSS Sprite或JS技巧)</td> </tr> <tr> <td align="left"><strong>可访问性</strong></td> <td align="left">⭐⭐⭐ 原生支持好 (<code><title></code>, <code><desc></code>, ARIA)</td> <td align="left">⚠️ 依赖 <code>alt</code>文本,支持较弱</td> </tr> <tr> <td align="left"><strong>渲染性能</strong></td> <td align="left">⭐⭐ 通常很好 (简单图标)</td> <td align="left">⭐⭐ 通常很好 (位图解码快)</td> </tr> <tr> <td align="left"><strong>小尺寸清晰度</strong></td> <td align="left">⭐⭐ 现代浏览器下通常很好</td> <td align="left">⭐⭐⭐ 可像素级精确控制 (如果专门优化)</td> </tr> <tr> <td align="left"><strong>维护复杂度</strong></td> <td align="left">⭐ 单个文件,易于维护</td> <td align="left">⚠️ 需管理多套资源,复杂度高</td> </tr> <tr> <td align="left"><strong>浏览器支持</strong></td> <td align="left">⭐⭐⭐ 所有现代浏览器完美支持</td> <td align="left">⭐⭐⭐ 广泛支持 (位图是基础)</td> </tr> <tr> <td align="left"><strong>现代Web标准推荐</strong></td> <td align="left">⭐⭐⭐ 是核心标准</td> <td align="left">⚠️ 是解决历史问题的方案</td> </tr> </tbody> </table> <p><strong>总结:</strong> <strong>拥抱SVG作为系统图标的基础</strong>。它的矢量特性、灵活性、性能和可访问性优势使其成为现代Web和应用程序开发的标杆。将“DCI”或响应式的思想理解为<strong>在SVG的基础上,利用其自身可编程性和少量媒体查询进行优化</strong>,或者在极其罕见的情况下为极小尺寸的复杂图标提供像素级优化的位图后备。对于绝大多数系统图标需求,一个精心设计的SVG文件就足够了。🎯</p> </div>