use*_*695 7 printing matlab diacritics character-encoding eps
我正在尝试在MATLAB中的图例命令中使用变音符号.一个快速的谷歌告诉我我想要的形式char(146),这适用于显示文件,或打印到TIF.
但是当我打印到EPS格式(或epsc,eps2,epsc2)时,文件中会显示不同的字符.我已经尝试过打印前300多个字符了,它们肯定会改变(虽然非常缓慢,其中一半是"A",后面有一个符号),但这似乎是一个相当慢的方法,我不是保证实际找到我想要的符号.那么,这里有没有人对我能尝试的东西有任何想法?
我正在使用MATLAB R2011a,我的默认字符集是UTF-8,我的打印行看起来像..
legend( plot_id , strcat('lala',char(146)) )
Run Code Online (Sandbox Code Playgroud)
我的印刷线看起来像......
print -depsc2 -tiff -r600 <filename>
Run Code Online (Sandbox Code Playgroud)
(但关闭tiff缩略图生成没有任何影响)
小智 8
当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
Run Code Online (Sandbox Code Playgroud)
MATLAB在eps文件中定义了一个函数FMSR,它将Helvetica字体重新编码为另一种编码,这里是ISOLatin1Encoding,它是两个内置编码向量之一,与ISO-8859-1(Latin1)标准紧密匹配(见第329页)有关详细信息,请参阅"Postscript语言参考手册"330.简而言之,编码向量是256个元素的数组,它将字符名称与字符代码相关联.所以它只读取1字节字符代码.在ISO-8859-1中,\ 303 = 195 =Ã和\ 266 = 182 =.结果,它打印Ã.
将八进制UTF-8代码转换为八进制ISO-8859-1代码,这很容易,因为非ASCII ISO-8859-1字符遵循UTF-8中的相同布局.例如,使用程序sed,可以从命令窗口或导出脚本运行:
!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
Run Code Online (Sandbox Code Playgroud)
因此,\303\266变为\366= 246 =ö.您可以直接在MATLAB中键入非ASCII字符.
slCharacterEncoding('ISO-8859-1')在向图中添加文本之前更改MATLAB字符集编码,如果从命令窗口添加文本,则使用char(数字)表示非ASCII字符.如果使用绘图工具在图中直接添加文本,则可以输入非ASCII字符.这个解决方案并不理想,因为非ASCII字符在默认字体中没有出现在图中(默认情况下,在Linux上使用MATLAB,Helvetica),如果您编写图形的脚本,则需要使用char(数字).
稍后使用用户提交的MATLAB函数(如LaPrint或其中一个分支)使用LaTex渲染文本,该函数使用图形文本和带有图形非文本部分的eps文件创建tex文件.类似的解决方案是matlab2tikz,它创建一个tikz/pgfplot文件和一个tex文件.
使用MATLAB的Latex解释器:\"{o}.MATLAB通过将ASCII字符与其变音符号组合来创建字符,但由于相对定位不良,结果质量较差(与字符相比,变音符号在右侧有点过多).MATLAB使用Computer Modern字体中的字形并将字体嵌入eps文件中(增加~80 Ko).此外,从eps创建的pdf中的原始文本不包含ö但是o ?.
对于出口不在ISO-8859-1,这是问的字符在这里,有可能是一个合理的解决方案,如果需要的字符数少于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
Run Code Online (Sandbox Code Playgroud)
保存为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
Run Code Online (Sandbox Code Playgroud)
这是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()
Run Code Online (Sandbox Code Playgroud)
保存为eps_lat2.py; 然后运行该命令python eps_lat2.py file.eps使用Latin-2编码创建file_latin2.eps.
通过更改脚本中的编码向量和iconv(或codecs.open)参数,可以轻松地将其适用于其他8位编码标准.
这是一个简单的测试:
\n\n%# common text properties\nprops = {\'FontSize\',30};\n\n%# LaTeX\nstr = \'\\"a\\"o\\"u\';\nsubplot(121), plot(1:10)\ntext(5, 5, str, \'Interpreter\',\'latex\', props{:})\nlegend({str}, \'Interpreter\',\'latex\', props{:})\nxlabel(str, \'Interpreter\',\'latex\', props{:})\ntitle(str, \'Interpreter\',\'latex\', props{:})\n\n%# normal text\nstr = \'\xc3\xa4\xc3\xb6\xc3\xbc\';\nsubplot(122), plot(10:-1:1)\ntext(5, 5, str, props{:})\nlegend({str}, props{:})\ntitle(str, props{:})\nxlabel(str, props{:})\n\n%# export as EPS file\nprint -depsc2 -tiff -r600 file.eps\nRun Code Online (Sandbox Code Playgroud)\n\n
生成的EPS文件看起来相同。
\n\n我使用的是 Windows XP,默认字符编码是Windows-1252:
\n\n>> feature(\'DefaultCharacterSet\')\nans =\nwindows-1252\nRun Code Online (Sandbox Code Playgroud)\n\n因此,您可以使用它们的(扩展)ASCII 代码直接键入这些变音符号:Alt+0228、Alt+0246和Alt+0252分别表示 \xc3\xa4、\xc3\xb6、\xc3\xbc:
\n\n>> char([228 246 252])\nans =\n\xc3\xa4\xc3\xb6\xc3\xbc\nRun Code Online (Sandbox Code Playgroud)\n\n另请注意,我默认使用 Arial 字体:
\n\n>> get(0, \'defaultTextFontName\')\nans =\nArial\n\n>> get(0, \'defaultAxesFontName\')\nans =\nArial\nRun Code Online (Sandbox Code Playgroud)\n