我正在尝试在 MATLAB 的图例命令中使用变音符号。一个快速的谷歌告诉我我想要的表格是 char(146)
,这适用于显示文件或将其打印到 tif。
但是当我打印为 EPS 格式(或 epsc、eps2、epsc2)时,文件中会显示不同的字符。我试过打印前 300 多个字符,它们肯定会改变(尽管速度很慢,其中很大一部分是“A”,紧接着是一个符号),但这似乎是一种很慢的方法,我不是保证真正找到我想要的符号。那么,这里有人对我可以尝试的方法有任何想法吗?
我正在使用 MATLAB R2011a,我的默认字符集是 UTF-8,我的打印行看起来像..
legend( plot_id , strcat('lala',char(146)) )
我的打印线看起来像..
print -depsc2 -tiff -r600 <filename>
(但关闭 tiff 缩略图生成没有任何效果)
最佳答案
当 MATLAB 字符编码为 UTF-8 时会出现问题,这通常是 Linux 用户的情况(因此 Amro 使用 CP1252 的配置没有问题)。当 MATLAB 字符集编码(使用 slCharacterEncoding()
获取)为 UTF-8 时,MATLAB eps 导出函数会被窃听(至少在 R2011b 之前),因为它以八进制转义 UTF-8 格式(2 个字节)导出非 ASCII 字符而 Postscript 解释器设置为解码 1 字节格式。
让我们用字符 ö U+00F6 来说明这个错误,它的一些表示是:
MATLAB 创建的 eps 文件包含:
/Helvetica /ISOLatin1Encoding 120 FMSR
(\303\266) s
MATLAB 在 eps 文件中定义了一个函数
FMSR
将 Helvetica 字体重新编码为另一种编码,这里是 ISOLatin1Encoding它是两个内置编码向量之一,与 ISO-8859-1 (Latin1) 标准非常匹配(有关详细信息,请参阅 Postscript 语言引用手册的第 329-330 页)。简而言之,编码向量是将字符名称与字符代码相关联的 256 个元素数组。所以它只读取 1 字节的字符代码。在 ISO-8859-1 中,\303=195=à 和\266=182=¶。结果,它打印 ö。使用 UTF-8 语言环境导出非 ASCII ISO-8859-1 字符的选项
!sed -i -e 's/\\302\(\\2[4-7][0-7]\)/\1/g' -e 's/\\303\\2\([0-7][0-7]\)/\\3\1/g' file.eps
因此,
\303\266
变成 \366
=246=ö。您可以在 MATLAB 中直接键入非 ASCII 字符。 slCharacterEncoding('ISO-8859-1')
在向图中添加文本之前,如果从命令窗口添加文本,请对非 ASCII 字符使用 char(number)。如果使用绘图工具直接在图中添加文本,则可以输入非 ASCII 字符。此解决方案并不理想,因为非 ASCII 字符不会以默认字体(Linux 上的 MATLAB 默认为 Helvetica)出现在图形上,并且如果您编写图形创建脚本,则需要使用 char(number)。 \"{o}
. MATLAB 通过将 ASCII 字符与其变音符号组合来创建字符,但由于相对定位不佳(与字符相比,变音符号在右侧有点太多),结果质量很低。 MATLAB 使用 Computer Modern 字体中的字形并将字体嵌入到 eps 文件中(增加了约 80 Ko)。此外,从 eps 创建的 pdf 中的原始文本不包含 ö
但是 o ̈
. 导出非 ISO-8859-1 字符
用于导出不在 ISO-8859-1 中的字符,这是在 here 上询问的,如果需要的字符数小于 256(8 位格式)并且理想情况下在标准编码集中,则可能有一个合理的解决方案。它包括以下步骤:
例如,如果要导出波兰语文本,则需要将文件转换为 ISO-8859-2。这是在 Linux 上使用 Bash 的实现:
#!/bin/bash
name=$(basename "$1" .eps)
ascii2uni -a K "$1" > /tmp/eps_uni.eps
iconv -t ISO-8859-2 /tmp/eps_uni.eps -o "$name"_latin2.eps
sed -i -e '/%EndPageSetup/ r ISOLatin2Encoding.ps' -e 's/ISOLatin1Encoding/MyEncoding/' "$name"_latin2.eps
保存为 eps_lat2;然后运行命令
sh eps_lat2 file.eps
使用 Latin-2 编码创建 file_latin2.eps。文件 ISOLatin2Encoding.ps 包含以下内容:/MyEncoding
% The first 144 entries are the same as the ISO Latin-1 encoding.
ISOLatin1Encoding 0 144 getinterval aload pop
% \22x
/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
% \24x
/nbspace /Aogonek /breve /Lslash /currency /Lcaron /Sacute /section
/dieresis /Scaron /Scedilla /Tcaron /Zacute /hyphen /Zcaron /Zdotaccent
/degree /aogonek /ogonek /lslash /acute /lcaron /sacute /caron
/cedilla /scaron /scedilla /tcaron /zacute /hungarumlaut /zcaron /zdotaccent
% \30x
/Racute /Aacute /Acircumflex /Abreve /Adieresis /Lacute /Cacute /Ccedilla
/Ccaron /Eacute /Eogonek /Edieresis /Ecaron /Iacute /Icircumflex /Dcaron
/Dcroat /Nacute /Ncaron /Oacute /Ocircumflex /Ohungarumlaut /Odieresis /multiply
/Rcaron /Uring /Uacute /Uhungarumlaut /Udieresis /Yacute /Tcedilla /germandbls
% \34x
/racute /aacute /acircumflex /abreve /adieresis /lacute /cacute /ccedilla
/ccaron /eacute /eogonek /edieresis /ecaron /iacute /icircumflex /dcaron
/dcroat /nacute /ncaron /oacute /ocircumflex /ohungarumlaut /odieresis /divide
/rcaron /uring /uacute /uhungarumlaut /udieresis /yacute /tcedilla /dotaccent
256 packedarray def
这是 Python 的另一个实现(因此它也可以在 Windows 和 Mac 上运行):
#!/usr/bin/python
# -*- coding: utf-8 -*-
import sys,codecs
input = sys.argv[1]
fo = codecs.open(input[:-4]+'_latin2.eps','w','latin2')
with codecs.open(input,'r','string_escape') as fi:
data = fi.readlines()
with open('ISOLatin2Encoding.ps') as fenc:
for line in data:
fo.write(line.decode('utf-8').replace('ISOLatin1Encoding','MyEncoding'))
if line.startswith('%%EndPageSetup'):
fo.write(fenc.read())
fo.close()
保存为 eps_lat2.py;然后运行命令
python eps_lat2.py file.eps
使用 Latin-2 编码创建 file_latin2.eps。通过更改脚本中的编码向量和 iconv(或 codecs.open)参数,它可以轻松适应其他 8 位编码标准。
关于matlab - 如何以 Matlab eps 格式导出变音符号(或任何外来字符)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11891836/