Terminal: 功能要求:sixel 图形支持

创建于 2019-05-07  ·  58评论  ·  资料来源: microsoft/terminal

希望在终端中看到 Sixel 支持,这是用于在控制台中显示图形的标准。

Sixel 是用于在终端中进行图形处理的原始 DEC 规范的一部分,并且近年来已重新流行用于在命令行上进行图形处理,特别是由 Pythonistas 进行数据科学。

libsixel 库提供了一个编码器,但也是对该主题的一个很好的介绍(比维基百科页面更好):

https://github.com/saitoha/libsixel

Area-Output Area-Rendering Issue-Feature Product-Conpty Product-Terminal

最有用的评论

哦。 Sixel 是非常酷的东西。

我决定我需要那个。 需要。

所有58条评论

在实现 Sixel 时,使用包含透明度的图像进行测试很重要。
可以通过绘制不同颜色的像素来实现透明度,但不绘制任何 Sixel 颜色中的某些像素,而将背景颜色保持不变。
我相信这是正确绘制非矩形 Sixels 的唯一方法,并且在新的 Windows 终端中使用背景丙烯酸透明度特别好。

例如,在 Ubuntu 中使用 WSL 进行测试,在 mlterm 中,此类图像被正确渲染为具有透明蒙版并保留背景颜色,而在 xterm -ti vt340 中,未触及的像素被绘制为黑色,即使背景是白色的,这似乎暗示他们在将它们传送到终端窗口之前,在没有透明度掩码或 alpha 的情况下在初始化为黑色的内存位图上渲染 Sixel。

哦。 Sixel 是非常酷的东西。

我决定我需要那个。 需要。

我会很乐意审查 PR :)

今天接受了Build 2019采访,提到了这个请求。 我仍然认为 Sixel 上的 Xorg 是错误的。 所以_非常非常错误_。

ffmpeg-sixel “Steve Ballmer Sells CS50”演示永远不会厌倦。 不得不说,视频没有声音有点令人失望(声音确实使视频成为现实)。 自然,控制台已经有声音了。 他们完全发出哔哔声。 先例集。 我们真正需要的是一个新的CSI 序列,用于与帧交错的作品剪辑, amirite

肯,我真的值得一提Sixels;)


来自:therealkenc [email protected]
发送时间:2019 年 5 月 8 日星期三下午 4:31:31
至:微软/终端
抄送:已订阅
主题:回复:[微软/终端] Sixel 图形支持 (#448)

抓到 Build 2019 https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fmybuild.techcommunity.microsoft.com%2Fhome%23top-anchor&data=01%7C01%7Cduhowett%40microsoft.com %7C81f48be19f374665cd3408d6d40d4dc6%7C72f988bf86f141af91ab2d7cd011db47%7C1&sdata=i8rfPCaN%2FxqdF%2F4qRtdN2Py4%2BVRlbPgpwJWtPZSGGHc%3D&reserved=0今天要求采访。 我仍然认为 Sixel 上的 Xorg 是错误的https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fmicrosoft%2FWSL%2Fissues%2F1099%23issuecomment-248513013&data=01 %7C01%7Cduhowett%40microsoft.com%7C81f48be19f374665cd3408d6d40d4dc6%7C72f988bf86f141af91ab2d7cd011db47%7C1&sdata=J%2BwCnn0z70FkI9lDcus1nMXcKz1P0ArL%2Bmddz5oi . 所以非常非常错误。

ffmpeg-sixel https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fsaitoha%2FFFmpeg-SIXEL&data=01%7C01%7Cduhowett%40microsoft.com%7C81f48be19f374665cd3408d6d40d4dc6%7C7114918baf7cdf6 %7C1&sdata=G%2F9mvw1EdADkwChSbHZ%2FI54k9xvXagV%2FxD9VbJtyw7g%3D&reserved=0 “史蒂夫鲍尔默销售 CS50”演示https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.youtube.com% 2Fwatch%3Fv%3D7z6lo4aq6zc%26feature%3Dyoutu.be&数据= 01%7C01%7Cduhowett%40microsoft.com%7C81f48be19f374665cd3408d6d40d4dc6%7C72f988bf86f141af91ab2d7cd011db47%7C1&SDATA = 6IVwBHs6%2F43rXdk6GabiSUpTFS86xUGB6bubfkS3ea0%3D&保留= 0从未得到累寿。 不得不说,视频没有声音有点令人失望(声音真的让视频https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv %3DEl2mr5aS8y0&数据= 01%7C01%7Cduhowett%40microsoft.com%7C81f48be19f374665cd3408d6d40d4dc6%7C72f988bf86f141af91ab2d7cd011db47%7C1&SDATA = Mm1ICN5KcgrP5YmdAZsUCzUKbVQDtxFE1qAEpkhKiZk%3D&保留= 0 )。 自然,控制台已经有声音了。 他们完全发出哔哔声。 先例集。 我们真正需要的是一个新的 CSI 序列https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fen.wikipedia.org%2Fwiki%2FANSI_escape_code%23CSI_sequences&data=01%7C01%7Cduhowett% 40microsoft.com%7C81f48be19f374665cd3408d6d40d4dc6%7C72f988bf86f141af91ab2d7cd011db47%7C1&SDATA = 29pJq5661TXtnn2huLyUMgebTyYMEhTKXpAm19jzqHU%3D&保留= 0为OPUS https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fen.wikipedia.org%2Fwiki%2FOpus_ (audio_format)数据= 01%7C01%7Cduhowett%40microsoft.com%7C81f48be19f374665cd3408d6d40d4dc6%7C72f988bf86f141af91ab2d7cd011db47%7C1&SDATA = XOq6Acz4%2B7gQeTKQBQ2fYJPnoLvx6vUjmLRhgOX1eDo%3D&保留= 0的剪辑与框架,amirite交错?


您收到此消息是因为您订阅了此线程。
直接回复此邮件,在 GitHub 上查看https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fmicrosoft%2FTerminal%2Fissues%2F448%23issuecomment-490688164&data=01 %7C01%7Cduhowett%40microsoft.com%7C81f48be19f374665cd3408d6d40d4dc6%7C72f988bf86f141af91ab2d7cd011db47%7C1&SDATA = pnXPvsuGF7l5mQfU2htzFwJnqZjEuW4zNuh1HaBJnKM%3D&保留= 0 ,或静音螺纹https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub。 COM%2Fnotifications%2Funsubscribe-AUTH%2FADNHLGXQOYKINZMIBKTB4LTPUNPFHANCNFSM4HLENFOQ&数据= 01%7C01%7Cduhowett%40microsoft.com%7C81f48be19f374665cd3408d6d40d4dc6%7C72f988bf86f141af91ab2d7cd011db47%7C1&SDATA =%2F4pMmm7bvPa%2BbFmE1gyN8%2BoTZDKJyRksBrkJpDh%2BLug%3D&保留= 0

相关:#120

需要。

needthis

哈哈,我当时正在看直播,我只是在想“这是我的老板分配给我在演播室观众面前现场直播的工作”。

请将此作为 v1.0 的优先事项!

3d 动画可以是 v1.5 😛

我的天啊

支持这一请求,Sixels 在终端中将是一件了不起的事情。

这个周末我完成了对我的 MIT 许可的基于 Java 的 TUI 库的Sixel 读取支持,它非常​​简单。 将 Sixel 数据字符串转换为位图图像的代码在这里,Sixel 类的客户端代码在这里

我在解码器的性能方面做得很少。 但是当使用 Swing 后端时,性能还是可以的,如此处所示。 (蛇的图像看起来很糟糕,只是因为 byzanz 使用了糟糕的调色板来创建演示 gif。)我有点吃惊它组合得如此之快。 公平地说,“将 Sixel 解码为位图”部分是简单的部分,困难的部分是“将图像数据粘贴到文本单元格中,当它出现时,将图像而不是字符blit 到屏幕上”。

只是想向其他对 Sixel 的终端支持感兴趣的人提一下,希望它可以帮助您。

如果其他人编写 Jupyter 笔记本客户端,我会投赞成票;)

我们已经有一个在 mintty 中支持Sixel的示例,它是用 C (vice java) 编写的。 唯一需要的是对 C++ 的重构(至少对于初始支持而言)。 仍然很高兴看到它是如何在其他项目中实施的。

我们已经有一个在 mintty 中支持Sixel的示例,它是用 C (vice java) 编写的。 唯一需要的是对 C++ 的重构(至少对于初始支持而言)。 仍然很高兴看到它是如何在其他项目中实施的。

mintty 的许可证(GPLv3 或更高版本)有任何问题吗?

https://github.com/mintty/mintty/blob/master/LICENSE

从那个链接:

Sixel 代码 (sixel.c) 在 GPL 下重新授权,就像 mintty 一样
其作者的许可(kmiya@culti)

如果您将确切的代码音译为 C++,则根据其条款,衍生作品需要获得 GPLv3 或更高版本的许可,或者根本不分发。 (也可以询问 kmiya @culti ,他们是否愿意在不同的许可证下提供 Sixel.c,或者如果它曾经可以通过其他方式获得,请从该来源找到副本。)

我不知道什么可以被包含在 Windows 终端中 - 我快速浏览 Windows 终端说它是 MIT 许可的,所以取决于它是如何使用 mintty 的 GPLv3+ Sixel.c 的直接后代链接/加载的可能导致到许可证问题。

无论如何,很抱歉在这里打扰别人的项目,现在回到洞穴......

有一个用 C/C++ 为 Windows/Linux 编写的能够使用 Sixel 的简陋终端仿真器小部件,它有一个可以使用的 SixelRenderer 类(尽管它需要一些优化),它有一个 BSD-3 许可证。 可以说它最大的缺点是它是为特定的 C++ 框架编写的。 尽管如此,IMO SixelRenderer 的代码还是可以毫不费力地翻译。 (我知道这一点,因为我是它的作者。:))

https://github.com/ismail-yilmaz/upp-components/tree/master/CtrlLib/Terminal

在实现 Sixel 时,使用包含透明度的图像进行测试很重要。
可以通过绘制不同颜色的像素来实现透明度,但不绘制任何 Sixel 颜色中的某些像素,而将背景颜色保持不变。
我相信这是正确绘制非矩形 Sixels 的唯一方法,并且在新的 Windows 终端中使用背景丙烯酸透明度特别好。

例如,在 Ubuntu 中使用 WSL 进行测试,在 mlterm 中,此类图像被正确渲染为具有透明蒙版并保留背景颜色,而在 xterm -ti vt340 中,未触及的像素被绘制为黑色,即使背景是白色的,这似乎暗示他们在将它们传送到终端窗口之前,在没有透明度掩码或 alpha 的情况下在初始化为黑色的内存位图上渲染 Sixel。

唔。 我前面的 VT340 符合 DCS P1 中的 P2 参数; P2; P3 ; q 启动 SIXEL 序列的序列。 另一方面,Xterm 似乎忽略了它。 但是如果你使用光栅属性序列(“Pan ; Pad ; Ph ; Pv )并给它一个高度和宽度,它会清除背景,所以你会得到一个黑色像素。

我正在考虑免费试用 ttwin 模拟器并检查它的行为与 VT340 和充当 VT340 的 Xterm 有何不同。

但是... +1 一般支持 SIXEL 的想法,+10 提出兼容性测试的想法。

一旦我们在那里,我们可以添加对 iTerm2内联图像协议的支持......至少它应该更容易实现,它只需要一个图像的路径并且自己做所有事情。

我对这两个系统的一个疑问是,对齐会发生什么? 如果图像宽度或高度是字符宽度或高度的倍数,则一切正常,但如果不是,是否应仅在下侧和右侧添加填充,还是应将图像居中添加到所有侧面?

嘿,这里有一些相关的研究链接:

一旦我们在那里,我们可以添加对 iTerm2内联图像协议的支持......至少它应该更容易实现,它只需要一个图像的路径并且自己做所有事情。

那可能应该是一项不同的任务。 Sixel 和 ReGIS 明确用于带内图形或字符数据。 我并不是说这是一个坏主意,我只是说它应该被视为一个不同的功能。

我对这两个系统的一个疑问是,对齐会发生什么? 如果图像宽度或高度是字符宽度或高度的倍数,则一切正常,但如果不是,是否应仅在下侧和右侧添加填充,还是应将图像居中添加到所有侧面?

Sixel 和 ReGIS 图形数据的对齐在各种手册中都有描述(很差)。 Sixel 图像在字符单元边界上对齐。 如果您想要图像周围有黑色边框,则必须自己添加这些黑色像素; 没有像 HTML 的边距或填充这样的概念。 每行 Sixel 数据描述一个六像素高的条纹。 如果您尝试在终端仿真器上将 Sixel 图像数据与文本字符对齐,这可能会令人沮丧,因为生成 Sixel 数据的软件可能不知道每个字符字形的像素高。 如果你手边有一个老式的 xterm,你可以通过在 vt340 模式下启动它来看到这一点,指定不同的字体大小(为你提供不同的字符单元大小),然后打印出一些尝试将图像数据与文本对齐的 Sixel 数据数据。 (这是一个简单的测试文件,当我告诉字体服务器使用 96DPI 并指定 15 磅字体时,它看起来是正确的。修改字体大小会导致图像越来越不与文本对齐。https://gist.github。 com/OhMeadhbh/3d63f8b8aa4080d4de40586ffff819de)

最初的 vt340 没有这个问题,因为(当然)你在打开终端时没有指定字体大小。

您可以从该图像中看到的另一件事是,在 Sixel 文档中没有很好地描述的是,打印一行 Sixel 数据会为图像数据建立一个“虚拟左边距”。 如果您使用 '$' 或 '-' 字符执行 CR 或 CRLF 的道德等效项,则下一行将相对于该虚拟左边距打印,而不是终端左侧的实际左边距。

希望这可以帮助。

最后滚动回来阅读这个。 抱歉回复迟了。

例如,在 Ubuntu 中使用 WSL 进行测试,在 mlterm 中,此类图像被正确渲染为具有透明蒙版并保留背景颜色,而在 xterm -ti vt340 中,未触及的像素被绘制为黑色,即使背景是白色的,这似乎暗示他们在将它们传送到终端窗口之前,在没有透明度掩码或 alpha 的情况下在初始化为黑色的内存位图上渲染 Sixel。

在 xterm 中支持透明度应该不会太难。 由于其他原因,我一直在研究代码。 我担心某个地方的某个人依赖于 Xterm 的这种行为,因此建议将其放在兼容性标志后面,这也应该是直截了当的。 但是还有默认值的问题。 默认应该是什么? 黑色或透明。

我们知道最初的 VT240、241、330 和 340 做了什么吗? 我可以建议尝试忠实地代表实际 VT 的体验吗作为默认行为? 您可以通过打印倒置空格字符来测试这一点,然后在它们上方分层 Sixel 图形并查看未指定的像素呈现什么颜色。

我不知道我关心 msft 终端的默认设置是什么,只要它能够像 Xterm 一样模拟 VT340。 我编写的用于在终端中通过 ssh 执行 loglines 的代码假定上述“未指定的像素是黑色”行为。 如果我们进行此更改,我将不得不重写该代码。

如果您尝试在终端仿真器上将 Sixel 图像数据与文本字符对齐,这可能会令人沮丧,因为生成 Sixel 数据的软件可能不知道每个字符字形的像素高。

最初的 vt340 没有这个问题,因为(当然)你在打开终端时没有指定字体大小。

终端仿真器是否有任何理由不能仅缩放图像以完全匹配原始 DEC 终端的行为? 因此,如果 VT340 上的行高为 20 像素,则高度为 200 像素的图像应该正好覆盖 10 行,无论字体大小如何。 在我看来,这似乎是您与遗留软件保持合理兼容的唯一方法,这是终端仿真器的重点。

我可以理解想要扩展该行为以以更高分辨率渲染图像,但这应该是我认为的可选扩展(或者只是使用现有的专有格式之一)。 所以理想情况下,我希望 Sixel 的默认值尽可能接近您在实际 DEC 终端上得到的值。

嘿,这里有一些相关的研究链接:
终端 wg 上的“良好图像协议的基础知识”

Sixel 已损坏,因为具有并排窗格的 tmux 无法支持它。

image

font-resize

这需要一些工作(实际上是很多工作),但是使用 Sixel 可以执行几乎所有可以想象的“终端中的图像”技巧:

  • 终端中的分层每个单元格屏蔽图像: https ://jexer.sourceforge.io/images/sixel_many_images.png

  • 终端中的浮动(多路复用)终端窗口使用 Sixel 来支持 VT100 样式的双宽度: https ://jexer.sourceforge.io/screenshots/jexer_sixel_in_sixel.png

  • 带有图像的“tmux 风格”平铺终端: https ://gitlab.com/klamonte/jexer/-/wikis/uploads/7603381f82414ef9ae214bfcf759c064/example_tilingwm2_1.png

  • 具有不同文本单元大小的多头共享终端会话显示相同的图: https ://jexer.sourceforge.io/screenshots/multiscreen_2b.png

  • 使用 Sixel 渲染主终端字体中不存在的 CJK 和表情符号: https ://jexer.sourceforge.io/screenshots/xterm_sixel_cjk.png

我在引用的“好”协议线程中包含了一些可能感兴趣的其他评论。

如果不出意外,sixel 是一个很好的垫脚石,可用于构建混合图片和文本的终端侧基础设施。 从直接经验来看,终端端(存储/显示图像)的难度大约是多路复用器/应用端(tmux/mc 等)的 1/4。

Sixels 确实是带内图形(例如通过 ssh)的理想解决方案:由于许多现有工具都支持它们,因此它们可以用于实际用途,例如在旅途中绘制时间戳同步问题

如 therealkenc 所示并由 klamonte在 640292222 中进一步解释,一切都可以用 Sixel 处理,甚至是并排图像,但它需要一些工作。

不久前,我和其他几个人一起研究 tmux 的后备模式,使用高级 unicode 图形在不支持 Sixel 的终端中表示 Sixel 图像。

它有点像自动化的 ANSII 艺术,利用大多数字体中存在的特殊块字符:这种等效的颜色 unicode 表示可以替代 Sixel,然后被实际的 Sixel 图像覆盖(或不覆盖!)。 它还可以解决保留所有 Sixel 图片以供向后滚动的问题,方法是用低保真 unicode 占位符替换它们(例如以节省内存),并在由于某种原因无法显示 Sixel 图像时使用占位符。

该代码是公共领域。 它可以立即用作向 Sixel 支持迈出的第一步:

  • 检测 Sixels 序列何时传输,然后计算 unicode 文本替换

  • 显示这个 unicode 序列,它已经被 Windows Terminal 支持

  • 稍后,当sixel 被实现时,在sixel 序列之上渲染。

你会感兴趣吗?

顺便说一句,我在这里认出了我熟悉的gnuplot x^2 sin 和 10 sin(x) 图我很高兴它提供了一些灵感😄

请。

@DHowett acac350是实际渲染 Sixel 图形的第一步吗? 我收到了来自使用 ssh 并希望使用我的lsix程序查看图像目录的人们在 Microsoft 终端中支持 Sixel 的请求。

排序。 我们现在有能力处理传入的 DCS 序列。 我们还没有连接任何处理程序,但是拥有这样做的基础设施非常重要。 :微笑:

这里有一些更新。 我在这里有一个工作分支。 早期的屏幕截图如下所示:

image

与我最初的想法相反,渲染sixel图像最困难的部分实际上是conpty层。 Sixel 图像应该是内联对象。 Sixel 图像的渲染取决于字符的渲染大小。 然而,由于额外的 conpty 层,我们在处理 Sixel 序列时实际上无法获得字符的渲染大小。 这听起来非常抽象和模糊。 对此感兴趣的任何人都可以查看我的分支并查看它是如何完成的。

总的来说,conpty 层使得处理 Sixel 图像的滚动和调整大小变得非常困难。 在我的分支中,如果您只需要显示它,它就可以工作。 但是滚动和调整大小都被完全破坏了。

还没看,但你可以使用直通模式在终端本身实现吗? 我仍然会在 OpenConsole 中添加它,但听起来共享代码是不可能的。 由于 Windows 终端在某些时候需要与 OpenConsole 分离,因此您最好简单地为两者复制代码。 您是否还根据您的参数和 j4james PRs 进行参数设置? 这也可能会有所帮助。

@WSLUser感谢您的关注。 这张截图实际上是大约一个月前的,当时 j4james 的神奇参数 PR 甚至不存在。 我的工作完全在 Windows 终端中,而不是在控制台中。 我在内部向控制台团队展示了这个 PR,并从那时起取得了一些进展。 但是由于 conpty 问题,我被卡住了。

是的,我会从 master 中重新定位并添加https://github.com/microsoft/terminal/pull/7578https://github.com/microsoft/terminal/pull/7799。 从那里,也许可以看到 ConPTY 在直通模式中缺少什么。 我想知道 Mintty 是否在 ConPTY 模式下使用直通。

我想知道 Mintty 是否在 ConPTY 模式下使用直通。

很确定 mintty 根本没有使用 conpty 😜


这里使用 conpty 的技巧是控制台 (conpty) 需要知道填充有 Sixel 内容的单元格,以免意外地从连接的终端中清除该内容。 也许 conpty 可能会被启发忽略使用 sizel 图形绘制单元格,并假设连接的终端将不理会这些单元格。

这可能会打乱我们的一些优化(比如我们不能 EraseLine 具有 Sixel 数据的行),但这可能是一个足够好的开始

\

也许 conpty 可能会被启发忽略使用 sizel 图形绘制单元格,并假设连接的终端将不理会这些单元格。

这也是我最初的计划,它可能是当前 conpty 架构的最佳解决方案,但有许多复杂性。

  1. 这将如何与 DCS 流媒体交互(我认为我们甚至还没有解决方案)。 我假设我们需要某种拆分流概念,在将字节流发送到 conhost 缓冲区的同时将其传递到 conpty,但这似乎会给流程增加很多不必要的开销。
  2. 这只有在您知道 conpty 终端的像素单元大小时才有效。 我之前提到过,我认为 Sixel 的最佳解决方案是匹配原始 VT 终端的单元大小,如果我们这样做,这将不是问题。 但是,据我所知,没有其他终端仿真器可以做到这一点,因此它不适用于其他任何人。

考虑到不同的字体、不同的字体大小和字体大小调整, @j4james提出的第二个问题变得更加复杂。 所以总的来说我认为这个问题有3个方面:

  • 首先 conpty 需要知道填充有 Sixel 内容的单元格,如果没有这个,conpty 中的后备缓冲区和 WT 中的绘图缓冲区将不可避免地不同步。
  • 为此,conpty 需要知道绘图上下文中的像素单元大小,这由 WT 中的绘图层处理。 conpty 和实际的 DXRenderer 之间存在巨大的差距,这使得这成为一项艰巨的任务。
  • 此外,当字体或字体大小发生变化时,理想情况下,sixel 图像也应该相应地发生变化。
  • 最后处理其他事情,如窗格、替代缓冲区、差分绘图、滚动等。

考虑到不同的字体、不同的字体大小和字体大小调整, @j4james提出的第二个问题变得更加复杂。 所以总的来说我认为这个问题有3个方面:

为了清楚起见,我的观点是,如果我们完全匹配 VT340 的行为,那么这些都不是问题,因此无论字体大小如何,一张 10x20 像素的图像都将占据一个字符单元。 如果我们想要匹配其他终端仿真器的行为,这只是一个问题,而且这始终是一个留待以后使用的选项。 这种方法仍然会有并发症,但我个人认为它们不太值得关注。

我更担心的是您似乎忽略了 DCS 流媒体问题,我预计这可能会从根本上改变解决方案的架构。 我希望看到的步骤是:1.解决#7316; 2. 就单元像素大小的解决方案达成一致; 3.在conhost中找点东西; 4. 一旦conhost中的所有复杂性都解决了,然后才考虑我们如何使它在conpty中工作。

很抱歉留下 DCS 流媒体问题。 在我当前的实现中,我只存储整个字符串并将其传递给引擎。 当序列较大时,这会引入性能问题。 但至少它有效。 所以我上面的评论主要是基于它。

但你是对的。 如果其他人想对此有所了解,DCS 流媒体问题实际上是重中之重。

获取 Outlook for iOS https://aka.ms/o0ukef

根据https://github.com/microsoft/terminal/issues/57中的讨论,我认为 conpty 根本不关心字体?

wrt调整大小我认为最自然的方法是在图像到达后将图像“锚定”到字符单元中,并根据锚几何重新计算图像大小。 其他任何事情都会导致图像与字符单元格的不一致。

@yatli是的。 这也是使问题变得棘手的原因。

10x20 像素的图像将只占用一个字符单元

不幸的是,这是错误的,至少对于我当前的字体设置而言。

如果我错了,请纠正我,但对于像素完美的图像显示,我认为我们确实需要关心字体。

@skyline75489请查看我对“锚”的更新评论

单元格数据结构需要更新为char | sixel anchor

Sixel 锚点应包含以下信息:

  • 指向图像对象的指针
  • 它占据的字符单元区域,以浮点数表示(例如 5.2 行 x 7.8 列)

这是一个好主意,但是由于在 conpty 层中的额外翻译,实现细节让我很生气。 为避免通过电子邮件向人们发送垃圾邮件,如果您有兴趣,请随时通过 Teams @yatli与我联系。

10x20 像素的图像将只占用一个字符单元

不幸的是,这是错误的,至少对于我当前的字体设置而言。

我的建议是你应该这样做。 如果您创建一个 10x20 像素的图像并将其输出到真正的 DEC VT320 终端上,它将只占用一个字符(至少在 80 列模式下)。 所以如果我们试图模拟那个终端,那么我们应该做同样的事情。 如果您当前的字体恰好是 30x60,那么您需要放大图像。 如果您的字体较小,那么您缩小图像。

这保证了您可以以任何字体大小输出 Sixel 图像并始终获得相同的布局。 如果你想让它覆盖屏幕的某个区域,或者你想用文本字符在它周围画一个边框,你就知道图像将占据多少空间。

如果我错了,请纠正我,但对于像素完美的图像显示,我认为我们确实需要关心字体。

确实,您不会以这种方式获得“像素完美”的图像,但我认为这不应该是主要目标。 许多现代计算机都有高 dpi 显示器,图像放大是常规的,所以这并不是一个奇怪的概念。 如果我们想在用户更改字体大小时保持布局一致,无论如何我们都必须在某个时候缩放图像,所以你最好从一开始就这样做,并获得可预测的所有好处尺寸。

当然,以这种方式做事的另一个好处是它可以在 conpty 上实现。 如果图像占用的区域取决于您不可能知道的字体大小,我看不出如何使 conpty 工作。

我不会假装这种方法没有任何缺点,但我认为积极的一面超过了消极的一面。

如果字体的纵横比与 10:20 不同怎么办?

如果字体的纵横比与 10:20 不同怎么办?

我是否可以建议阅读这篇关于终端仿真器中的内联图像的一般问题的冗长且有些“残酷”的讨论

它可以为您提供总体思路。

最好的祝福

如果字体的纵横比与 10:20 不同怎么办?

图像可能有点拉伸或挤压,但我不认为这是世界末日。

让我用一个真实的例子来演示。 想象一下,我是一个邦德反派,我有一个使用 VT340 作为前端的旧安全系统。 现在由于冠状病毒,我处于锁定状态并在家工作,因此我正在使用 Windows 终端远程登录系统。 如果我们与 VT340 完全匹配,这没问题 - 终端如下所示:

image

但也许我更喜欢长宽比奇怪的字体。 因此,让我们看看 _Miriam Fixed_ 会是什么样子,它比大多数都宽。 邦德的形象现在看起来有点挤,但他仍然很容易辨认。

image

另一种方法是使用像素完美的图像(目前对于 conpty 不可行,但让我们假装一秒钟)。 邦德看起来不再被压扁,但现在图像只是预期大小的一小部分。 显示器的分辨率越高,看起来就越糟糕。

image

也许这是个人喜好问题,但我知道我肯定会选择选项 1 而不是选项 2。

另请注意,当字体纵横比不是 1:2 时,我们没有理由无法调整确切的行为。 一种选择可能是将图像置于预期占据的单元格内。 或者我们可以扩展图像使其覆盖整个区域,但剪掉超出边界的边缘。 在我看来,这些选择中的任何一个都比精确的像素渲染要好。

也许这是个人喜好问题,但我知道我肯定会选择选项 1 而不是选项 2。

我也是,只是最好知道字体具有不同的纵横比,这样图像可以自行调整并保持正确。

一种选择可能是将图像置于预期占据的单元格内。 或者我们可以扩展图像使其覆盖整个区域,但剪掉溢出边界的边缘

我认为最好把它们放在中心。

也许我误读了这个线程。 我们实际上是在谈论终端为 Sixel 图像伪造 10:20 字符吗? 我认为这会导致许多问题,例如邦德失真。 以正确的方式做这件事可能会更困难,但是,在我看来,现代终端应该与字体无关,并让应用程序程序员来处理 Sixels 和字符单元格。

使用转义序列,用户运行程序可以确定以像素为单位的字符单元大小,并决定如何智能地处理该应用程序的失真。 我使用的图像查看程序就是这样工作的。 当我更改字体系列或大小时,显示的缩略图会更新为始终精确为五个文本行高。 图像的宽度按比例缩放,除非它大于某个(在这种情况下,相当大)最大值。 通过基于字符单元的图像大小,它可以在高 DPI 屏幕上自动运行。

虽然 VT340 是一个值得模仿的崇高目标,但将字符单元分辨率固定在 10:20(从而限制整个屏幕的分辨率)是错误的。 VT340 只是几个 Sixel 实现之一,因此它的字体大小不一定更正确。

强迫 10:20 也将导致丑陋的 kludges。 (例如,如何响应以像素为单位的终端窗口大小的请求。说实话,假设它们将在屏幕上定位窗口?或者,总是返回 800x480,假设用户正在缩放图像以用于 Sixel 输出? )

我们实际上是在谈论终端为 Sixel 图像伪造 10:20 字符吗?

是的。

现代终端应该与字体无关

该提案与字体无关。 应用程序不需要知道任何关于字体的信息。 这就是重点。

使用转义序列,用户运行程序可以确定以像素为单位的字符单元大小,并决定如何智能地处理该应用程序的失真。

我不确定您使用的是什么方法,但是我之前看到的方法是使用专有的 XTerm 查询来获取窗口像素大小,以及另一个查询来获取窗口单元格大小,然后使用它数据来计算实际的单元像素大小。 这种方法的缺点是:

  1. 它是专有的,因此无法在真实终端或任何与真实终端完全匹配的终端仿真器上运行。
  2. 如果用户在您的应用程序运行时更改了他们的字体大小,那么您的计算将不再正确,并且图像将以错误的大小呈现(除非您不断地重新计算似乎不切实际的字体大小)。
  3. 如果用户具有高分辨率显示器和/或大字体,您将被迫发送大量图像以尝试匹配该分辨率。 考虑到 Sixel 一开始的效率是多么低下,这可能会占用大量带宽。

也就是说,我知道这是某些人可能希望使用的一种模式,我认为我们至少应该有一个选择来支持它(出于上面讨论的原因,目前这是不可能的)。 但在我看来,这不是 Sixel 的最佳方法。

我在核电站中有 300 多台 VT340,我最终希望拥有这些设备
代替。

我们可以使用商业终端仿真包,但我认为
除了一个以外,所有的都被淘汰了。

我们已经用运行 XTerm(或更少
经常,Win10 + Hummingbird + WSL 运行 XTerm),因为它有一个
中途体面的开源 Sixel 实现和一种糟糕的,但是
开源 ReGIS 实现。

我们将为此部分编写新软件的可能性
生成 Sixel 八位字节流的系统是 NIL。

如果您的目标是通过内联八位字节流发送图形,则
是其他选项。 但是如果你想支持sixel图形,你应该
以与以前类似的方式支持 Sixel 图形
实施。 不幸的是,这意味着您应该效仿
示例系统的行为(即 VT240、VT241、VT330 和 VT340
终端),甚至在将图形与文本集成时也是如此。

这是我正在谈论的那种东西的模型。 会很
如果任何新的 Sixel 实现保持与现有的兼容性,那就太好了
实现,因此图像不会超出屏幕边缘或仅
填满一半的屏幕。

https://vimeo.com/user32814426/review/467991744/ac5892fa7e

现代终端应该与字体无关

该提案与字体无关。 应用程序不需要知道任何关于字体的信息。 这就是重点。

我的意思是 _terminal_ 应该与字体无关,而不是对每种字体都强制使用 10:20。 如果它愿意,应用程序应该能够知道实际的字体大小,因为它是应用程序知道它试图显示的内容的领域,并且可以找出将文本和图形一起呈现的最佳方式。

使用转义序列,用户运行程序可以确定以像素为单位的字符单元大小,并决定如何智能地处理该应用程序的失真。

我不确定您使用的是什么方法,但是我之前看到的方法是使用专有的 XTerm 查询来获取窗口像素大小,以及另一个查询来获取窗口单元格大小,然后使用它数据来计算实际的单元像素大小。

是的,这差不多。 还有一个查询可以直接获取字符单元格大小,但我认为这不像获取屏幕大小并除以 ROWS 和 COLUMNS 那样得到广泛支持。

这种方法的缺点是:

1. It's proprietary, so wouldn't work on a real terminal, or any terminal emulator that exactly matched a real terminal.

这不是缺点。 这只意味着程序必须退回到它本来应该做的事情上:假设 $TERM=="VT340" 表示字符单元格是 10:20,"VT240" 表示 10:10,"mskermit" 表示 8:8,等等。

此外,它不是 xterm 专有序列。 获取屏幕尺寸称为“dtterm”转义序列,但实际上它首先在 SunView 中实现(SunOS,1986)。 我相信它后来被记录在 PHIGS 编程手册(1992 年)中。 尝试将 "\e[14t" 发送到一些终端仿真器,您会发现它已被广泛实施。

2. If the user changes their font size while your application is running, then your calculations will no longer be correct, and images will be rendered at the wrong size (unless you're continuously recalculating the font size which seems impractical).

这不是问题。 该程序只是捕获 SIGWINCH 并且仅在窗口实际更改时才重新计算。

3. If the user has a high resolution display, and/or large font size, you're forced to send through a massive image to try and match that resolution. Considering how inefficient Sixel is to start with, that can amount to a lot of bandwidth.

是的,sixel 效率极低。 但是在现代计算机上,发送全屏图像非常有用,甚至通过 ssh。 Microsoft 终端是否有某种波特率限制?

顺便说一句,我相信 Sixel 确实有一个“高 DPI”模式,其中每个点的宽度和高度都加倍。 我从未使用过它,我认为 xterm 甚至没有实现它,但也许这会减轻对带宽的担忧。

也就是说,我知道这是某些人可能希望使用的一种模式,我认为我们至少应该有一个选择来支持它(出于上面讨论的原因,目前这是不可能的)。

这种“模式”只是让字符和图形对齐,就像各种历史上的 Sixel 终端和当前的模拟器一样。 我承认,我不明白为什么不能在 Microsoft Terminal 中做同样的事情。 如果您说这个 10:20 的拼凑是可以做到的最好的,我相信您是正确的,并感谢您这样做。 一张扭曲的照片总比没有好。

使用转义序列,用户运行程序可以确定以像素为单位的字符单元大小,并决定如何智能地处理该应用程序的失真。

@hackerb9 ,获取字体尺寸的实际转义序列是什么?

相关的 XTerm 序列可以在这里找到: https ://invisible-island.net/xterm/ctlseqs/ctlseqs.html——寻找 XTWINOPS。

此外,在 Unix 上,您通常可以使用 TIOCGWINSZ ioctl 获取终端的内部像素大小以及单元格大小。 使用 openssh 这也可以远程工作。

就像一个数据点,libvte 的 Sixel 分支采用@hackerb9所说的与单元大小无关的路线。 它将传入的 Sixel 数据视为“完美像素”,并跨缩放级别和字体大小重新调整先前接收到的图像以覆盖一致的单元格范围。 合并后,该实现将可用于大部分 Linux 终端仿真器,包括 GNOME 终端、XFCE 终端、终结器等。从表面上看,这似乎至少可以与 XTerm 和 mlterm 互操作。

由于 libvte 记录了每个图像的虚拟单元大小,因此使用固定的虚拟 10x20 单元大小进行互操作也很简单。 然而,我们需要一种方法让程序将其预期的像素:单元比率传送到终端(例如,通过扩展 DCS 参数)。 一般来说,这可能非常有用,因为它还可以在带宽受限的环境中提供一种像素密度控制形式,正如您在上面提到的那样。

此外,在 Unix 上,您通常可以使用 TIOCGWINSZ ioctl 获取终端的内部像素大小以及单元格大小。 使用 openssh 这也可以远程工作。

Linux 控制台总是返回 0 ......虽然他们应该解决这个问题,但似乎也不愿意:-/

此页面是否有帮助?
0 / 5 - 0 等级

相关问题

Paul-Weisser picture Paul-Weisser  ·  71评论

DHowett-MSFT picture DHowett-MSFT  ·  285评论

Ronkiro picture Ronkiro  ·  65评论

pingzing picture pingzing  ·  212评论

MoshiBin picture MoshiBin  ·  128评论