libcaca - 将 ascii 字形更改为片假名

sta*_*wer 4 c ascii-art non-ascii-characters mplayer terminal-emulator

我正在创建一个视频效果,它应该看起来像“矩阵”电影,但有点不同(类似“矩阵”的视频输出将与真实视频的改变 alpha 通道混合,所以它看起来一半真实,一半带数字)。我只是使用带有 caca 驱动程序的 mplayer (mplayer -vo caca video.mp4) 以及屏幕录制,然后在其他软件中混合视频。为此,我需要更改文件dither.c 中的“静态 uint32_t ascii_glyphs[]”数组(来自此处发布的 caca 库的代码:https//github.com/cacalabs/libcaca/blob/master/caca/ dither.c ) from: ' ', '.', ':', ';', 't', '%', 'S', 'X', '@', '8', '?'包含所有片假名符号。但问题是看起来它们不可打印。所以视频的终端输出只包含阴影块。我应该说 bash 代码:

str123="???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????"

for i in $(seq 0 ${#str123}); do echo -n "'${str123:i:1}',"; done
Run Code Online (Sandbox Code Playgroud)

在我的终端中正常工作(用几个终端程序检查,正确打印),还设置了语言环境:

$ locale
LANG=en_US.UTF-8
LANGUAGE=en_US
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC=en_US.UTF-8
LC_TIME=en_US.UTF-8
LC_COLLATE="en_US.UTF-8"
LC_MONETARY=en_US.UTF-8
LC_MESSAGES="en_US.UTF-8"
LC_PAPER=en_US.UTF-8
LC_NAME=en_US.UTF-8
LC_ADDRESS=en_US.UTF-8
LC_TELEPHONE=en_US.UTF-8
LC_MEASUREMENT=en_US.UTF-8
LC_IDENTIFICATION=en_US.UTF-8
LC_ALL=
Run Code Online (Sandbox Code Playgroud)

新数组的结果:

/* List of glyphs */
static uint32_t ascii_glyphs[] =
{
    /*
    ' ', '.', ':', ';', 't', '%', 'S', 'X', '@', '8', '?'
    */

    /*
    ' ', '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',',
    '-', '.', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
    ':', ';', '<', '=', '>', '?', '@', 'A', 'B', 'C', 'D', 'E', 'F',
    'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
    'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^', '_', '`',
    'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
    'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
    '{', '|', '}', '~'
    */


    ' ', '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',',
    '-', '.', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
    ':', ';', '<', '=', '>', '?','@',
    '?','?','?','?','?','?','?','?','?','?','?','?','?','?',
    '?','?','?','?','?','?','?','?','?','?','?','?','?','?',
    '?','?','?','?','?','?','?','?','?','?','?','?','?','?',
    '?','?','?','?','?','?','?','?','?','?','?','?','?','?',
    '?','?','?','?','?','?','?','?','?','?','?','?','?','?',
    '?','?','?','?','?','?','?','?','?','?','?','?','?','?',
    '?','?','?','?','?','?','?','?','?','?','?','?','?','?',
    '?','?','?','?','?','?','?','?','?','?','?','?','?','?',
    '?','?','?','?','?','?','?','?','?','?','?','?','?','?',
    '?','?','?','?','?','?','?','?','?','?','?','?','?','?',
    '?','?','?','?','?','?','?','?','?','?','?','?','?','?',
    '?','?','?','?','?','?','?','?','?','?','?','?','?','?',
    '?','?','?','?','?','?','?','?','?','?','?','?','?','?',
    '?','?','?','?','?','?','?','?','?','?','?','?','?','?',
    '[', '\\', ']', '^', '_', '`',
    '?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?',
    '?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?',
    '?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?',
    '?',
    '{', '|', '}', '~'

};
Run Code Online (Sandbox Code Playgroud)

这是: 片假名

例如,如果我将这个“静态 uint32_t ascii_glyphs[]”数组更改为包含完整的 ascii 集,则结果为: 全ASCII

更新:我尝试更改“静态 uint32_t ascii_glyphs[]”数组以包含十六进制表示的片假名字形,仍然没有结果,但是(!)如果我添加这些多字节字符来设置:

static uint32_t ascii_glyphs[] =
{
    /* CP437 and box drawing */
    0x2591, 0x2592, 0x2593, 0x2588, 0x2584, 0x2580, /* ? ? ? ? ? ? */
    0x2500, 0x2501, 0x2503, 0x2503, 0x253c, 0x254b, /* ? ? ? ? ? ? */
    0x252c, 0x2534, 0x2533, 0x253b, 0x2566, 0x2569, /* ? ? ? ? ? ? */
    0x2550, 0x2551, 0x256c, /* ? ? ? */
    0x2575, 0x2577, 0x2579, 0x257b
};
Run Code Online (Sandbox Code Playgroud)

所以这些字符打印正确。结果: 结果 但是如果我在十六进制中添加片假名:

static uint32_t ascii_glyphs[] =
{
    /* CP437 and box drawing */
    0x2591, 0x2592, 0x2593, 0x2588, 0x2584, 0x2580, /* ? ? ? ? ? ? */
    0x2500, 0x2501, 0x2503, 0x2503, 0x253c, 0x254b, /* ? ? ? ? ? ? */
    0x252c, 0x2534, 0x2533, 0x253b, 0x2566, 0x2569, /* ? ? ? ? ? ? */
    0x2550, 0x2551, 0x256c, /* ? ? ? */
    0x2575, 0x2577, 0x2579, 0x257b,

    /* Katakana (part) */
    0x30a1,0x30a2,0x30a3,0x30a4,0x30a5,0x30a6,0x30a7,0x30a8,0x30a9,0x30aa,
    0x30ab,0x30ac,0x30ad,0x30ae,0x30af,0x30b0,0x30b1,0x30b2,0x30b3,0x30b4
}; 
Run Code Online (Sandbox Code Playgroud)

添加了这么多空白(只是背景和阴影字符,没有字形):

许多空白

那么为什么这仍然不起作用?看起来不知何故终端(?),gcc(?)或途中的某些东西只是不喜欢片假名符号:)

感谢您的指导!

G. *_*pen 5

问题是平假名和片假名是全角字符。当 Caca 尝试使用 将字符写入屏幕时caca_put_char(),它会检查屏幕上是否已经存在全角字符,如果是,它将用空格替换部分字符。由于屏幕上所有可能的字符位置都被写入,它最终会用空格覆盖任何全角字符,因此最终看不到片假名。

我认为您必须修改 Caca 以处理抖动字符集中的全角字符。如果所有字符都是全角,它应该只写入屏幕上的偶数列。如果你有一个混合,它会更复杂,但你可以例如这样做,如果给定位置上已经有一个全角字符,它就不会尝试覆盖它。