7

MATLAB の凡例コマンド内でウムラウトを使用しようとしています。簡単な Google は、私が望むフォームは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 サムネイルの生成をオフにしても効果はありません)

4

2 に答える 2

10

この問題は、MATLAB 文字エンコーディングが UTF-8 の場合に発生します。これは通常、Linux ユーザーの場合です (したがって、CP1252 を使用する Amro の構成では問題ありません)。MATLAB 文字セット エンコーディング (で取得slCharacterEncoding()) が UTF-8 の場合、MATLAB の eps エクスポート関数は (少なくとも R2011b までは) バグが発生します。Postscript が 8 進エスケープされた UTF-8 形式 (2 バイト) で非 ASCII 文字をエクスポートするためです。インタープリターは、1 バイト形式をデコードするように設定されています。

文字 ö U+00F6 のバグを説明しましょう。そのいくつかの表現は次のとおりです。

  • UTF-16: 0x00F6
  • UTF-8: 0xC3 0xB6
  • C 8 進数エスケープ UTF-8: \303\266
  • XML 10 進数エンティティ: ö

MATLAB によって作成された eps ファイルには、以下が含まれます。

/Helvetica /ISOLatin1Encoding 120 FMSR
(\303\266) s

MATLAB は、eps ファイルで、FMSRHelvetica フォントを別のエンコーディングに再エンコードする関数を定義します。ここでは、2 つの組み込みエンコーディング ベクトルの 1 つであり、ISO-8859-1 (Latin1) 標準に厳密に一致する ISOLatin1Encoding です (p.329 を参照) 詳細については、Postscript Language Reference Manual の 330 を参照してください)。簡単に言うと、エンコーディング ベクトルは、文字名を文字コードに関連付ける 256 要素の配列です。そのため、1 バイトの文字コードのみを読み取ります。ISO-8859-1 では、\303=195=à および \266=182=¶ です。その結果、それは ö を出力します。

UTF-8 ロケール環境で非 ASCII ISO-8859-1 文字をエクスポートするためのオプション

  1. 8 進 UTF-8 コードを 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
    

    したがって、=246=ö\303\266となります。\366非 ASCII 文字を MATLAB に直接入力できます。

  2. Figure にテキストを追加する前にMATLAB 文字セットのエンコードを変更slCharacterEncoding('ISO-8859-1')し、コマンド ウィンドウからテキストを追加する場合は、非 ASCII 文字に char(number) を使用します。プロット ツールを使用して Figure にテキストを直接追加する場合は、非 ASCII 文字を入力できます。非 ASCII 文字は既定のフォント (Linux 上の MATLAB では既定で Helvetica) では Figure に表示されず、Figure の作成をスクリプト化する場合は char(number) を使用する必要があるため、このソリューションは理想的ではありません。

  3. LaPrint などのユーザーが送信した MATLAB 関数またはそのフォークの 1 つを使用して、後でテキストを LaTex でレンダリングします。これにより、Figure のテキストを含む tex ファイルと、Figure のテキスト以外の部分を含む eps ファイルが作成されます。同様のソリューションは、tikz/pgfplot ファイルと tex ファイルを作成する matlab2tikz です。

  4. MATLAB の Latex インタープリターを使用します\"{o}。MATLAB は ASCII 文字とその分音記号を組み合わせて文字を作成しますが、相対位置が不適切であるため、結果の品質は低くなります (分音記号は文字に比べて少し右寄りです)。MATLAB は、Computer Modern フォントのグリフを使用し、そのフォントを eps ファイルに埋め込みます (これにより ~ 80 Ko が追加されます)。さらに、eps から作成された pdf の生のテキストにはöbut が含まれていませんo ̈

非 ISO-8859-1 文字のエクスポート

こちらで質問された ISO-8859-1 にない文字をエクスポートする場合、必要な文字数が 256 (8 ビット形式) 未満で、理想的には標準のエンコーディング セットである場合、おそらく合理的な解決策があります。次の手順が含まれます。

  1. 8 進コードを Unicode 文字に変換します。
  2. ファイルをターゲットのエンコード標準 (8 ビット形式) に保存します。
  3. ターゲット エンコーディング セットのエンコーディング ベクトルを追加します。

たとえば、ポーランド語のテキストをエクスポートする場合は、ファイルを ISO-8859-2 に変換する必要があります。Bash を使用した Linux での実装は次のとおりです。

#!/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 ビット エンコーディング標準に簡単に適合させることができます。

于 2013-02-08T09:50:45.243 に答える
3

簡単なテストを次に示します。

%# 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

スクリーンショット

結果のEPSファイルは同じように見えます。

ノート:

私は Windows XP を使用しており、デフォルトの文字エンコーディングはWindows-1252です。

>> feature('DefaultCharacterSet')
ans =
windows-1252

Alt+0228したがって、(拡張) ASCII コードを使用Alt+0246してこれらのウムラウトを直接入力できますAlt+0252

>> char([228 246 252])
ans =
äöü

また、デフォルトで Arial フォントを使用していることにも注意してください。

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

>> get(0, 'defaultAxesFontName')
ans =
Arial
于 2012-08-09T22:24:15.763 に答える