Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/matlab/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何以Matlab eps格式导出umlaut(或任何外来字符)?_Matlab_Printing_Character Encoding_Diacritics_Eps - Fatal编程技术网

如何以Matlab eps格式导出umlaut(或任何外来字符)?

如何以Matlab eps格式导出umlaut(或任何外来字符)?,matlab,printing,character-encoding,diacritics,eps,Matlab,Printing,Character Encoding,Diacritics,Eps,我试图在MATLAB中的legend命令中使用umlaut。一个快速的谷歌告诉我我想要的表单是char(146),它可以很好地显示文件,或者打印到tif 但当我打印到EPS格式(或epsc、eps2、epsc2)时,文件中会显示不同的字符。我试过打印前300多个字符,它们肯定会发生变化(虽然变化非常缓慢,其中有一半是“a”,后面紧接着是一个符号),但这似乎是一种非常缓慢的方法,而且我不能保证能真正找到我想要的符号。那么,这里有人对我可以尝试什么有什么想法吗 我使用的是MatlabR2011A,我

我试图在MATLAB中的legend命令中使用umlaut。一个快速的谷歌告诉我我想要的表单是
char(146)
,它可以很好地显示文件,或者打印到tif

但当我打印到EPS格式(或epsc、eps2、epsc2)时,文件中会显示不同的字符。我试过打印前300多个字符,它们肯定会发生变化(虽然变化非常缓慢,其中有一半是“a”,后面紧接着是一个符号),但这似乎是一种非常缓慢的方法,而且我不能保证能真正找到我想要的符号。那么,这里有人对我可以尝试什么有什么想法吗

我使用的是MatlabR2011A,我的默认字符集是UTF-8,我的打印行看起来像

legend( plot_id , strcat('lala',char(146)) )
我的打印行看起来像

print -depsc2 -tiff -r600 <filename>
print-depsc2-tiff-r600
(但是关闭tiff缩略图生成没有任何效果)

下面是一个简单的测试:

%# common text properties
props = {'FontSize',30};

%# LaTeX
str = '\"a\"o\"u';
subplot(121), plot(1:10)
text(5, 5, str, 'Interpreter','latex', props{:})
legend({str}, 'Interpreter','latex', props{:})
xlabel(str, 'Interpreter','latex', props{:})
title(str, 'Interpreter','latex', props{:})

%# normal text
str = 'äöü';
subplot(122), plot(10:-1:1)
text(5, 5, str, props{:})
legend({str}, props{:})
title(str, props{:})
xlabel(str, props{:})

%# export as EPS file
print -depsc2 -tiff -r600 file.eps

生成的文件看起来相同

笔记: 我使用的是Windows XP,默认字符编码为:

因此,您可以使用它们的(扩展)ASCII代码直接键入这些UMLAUT:Alt+0228、Alt+0246和Alt+0252分别表示ä、ö、ü:

>> char([228 246 252])
ans =
äöü
另外请注意,默认情况下我使用的是Arial字体:

>> get(0, 'defaultTextFontName')
ans =
Arial

>> get(0, 'defaultAxesFontName')
ans =
Arial

当MATLAB字符编码为UTF-8时会出现问题,Linux用户通常会遇到这种情况(因此Amro使用CP1252的配置没有问题)。当MATLAB字符集编码(使用
slCharacterEncoding()
获取)为UTF-8时,MATLAB eps导出函数出现错误(至少直到R2011b),因为它以八进制转义UTF-8格式(2字节)导出非ASCII字符,而Postscript解释器设置为解码1字节格式

让我们用字符öU+00F6来说明该错误,该字符的一些表示形式如下:

  • UTF-16:0x00F6
  • UTF-8:0xC3 0xB6
  • C八进制转义UTF-8:\303\266
  • XML十进制实体:ö
由MATLAB创建的eps文件包含:

/Helvetica /ISOLatin1Encoding 120 FMSR
(\303\266) s
MATLAB在eps文件中定义了一个函数
FMSR
,该函数将Helvetica字体重新编码为另一种编码,这是两种内置编码向量之一,与ISO-8859-1(拉丁语1)标准非常匹配(有关详细信息,请参阅Postscript语言参考手册第329-330页)。简言之,编码向量是将字符名与字符代码关联的256个元素数组。所以它只读取1字节字符代码。在ISO-8859-1中,303=195=Ã和266=182=。因此,它会打印出Ã

使用UTF-8语言环境导出非ASCII ISO-8859-1字符的选项
  • 将八进制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
    
    因此,
    \303\266
    变为
    \366
    =246=。可以在MATLAB中直接键入非ASCII字符

  • 在向图形添加文本之前,请更改MATLAB字符集编码
    slCharacterEncoding('ISO-8859-1')
    ,如果从命令窗口添加文本,请将字符(数字)用于非ASCII字符。如果使用绘图工具直接在图形中添加文本,则可以输入非ASCII字符。此解决方案并不理想,因为非ASCII字符不会以默认字体显示在图形上(Linux上的MATLAB默认为Helvetica),并且如果编写图形创建脚本,则需要使用字符(数字)

  • 稍后,使用用户提交的MATLAB函数(如LaPrint或其一个分叉)使用LaTex渲染文本,该函数使用图形的文本创建一个tex文件,使用图形的非文本部分创建一个eps文件。类似的解决方案是matlab2tikz,它创建一个tikz/pgfplot文件和一个tex文件

  • 使用MATLAB的Latex解释器:
    \“{o}
    。MATLAB通过将ASCII字符与其变音符号相结合来创建字符,但由于相对定位不良,结果质量较低(与字符相比,右侧的变音符号有点太多).MATLAB使用Computer Modern font中的字形,并将字体嵌入eps文件中(增加了~80 Ko)。此外,从eps创建的pdf中的原始文本不包含
    ö
    ,而是

  • 导出非ISO-8859-1字符 对于导出ISO-8859-1中未列出的字符(如上所述),如果所需字符数小于256(8位格式),并且理想情况下为标准编码集,则可能有一个合理的解决方案。该解决方案包括以下步骤:

  • 将八进制码转换为Unicode字符
  • 将文件保存到目标编码标准(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
    创建具有拉丁-2编码的文件\u 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上工作):

    另存为eps_lat2.py;然后运行命令
    python eps_lat2.py file.eps
    创建拉丁2.eps文件


    通过更改编码向量和iconv(或codecs.open),它可以很容易地适应其他8位编码标准脚本中的参数。

    +1非常感谢分享。现在我对Postscript知之甚少,但我认为真正的问题与打印无关。事实上,MATLAB不具备打印功能。我用一些可能的解决方法说明了这个问题,不幸的是,在这种情况下,这对printi没有帮助
    /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
    
    #!/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()