Подтвердить что ты не робот

MATLAB: как отображать текст в кодировке UTF-8, считанный из файла?

Суть моего вопроса такова:

Как я могу отображать символы Unicode в графическом интерфейсе Matlab (OS X), чтобы они были правильно отображены?

Подробнее:

У меня есть таблица строк, хранящихся в файле, и некоторые из этих строк содержат символы Unicode с кодировкой UTF-8. Я пробовал много разных способов (слишком много, чтобы перечислить здесь), чтобы отобразить содержимое этого файла в графическом интерфейсе MATLAB без успеха. Например:

>> fid = fopen('/Users/kj/mytable.txt', 'r', 'n', 'UTF-8');
>> [x, x, x, enc] = fopen(fid); enc

enc =

UTF-8

>> tbl = textscan(fid, '%s', 35, 'delimiter', ',');
>> tbl{1}{1}

ans =

ÎÎÎÎÎΠΣΦΩαβγδεζηθικλμνξÏÏÏÏÏÏÏÏÏÏ
>> 

Как только это произойдет, если я вставляю строку непосредственно в GUI MATLAB, вставляемая строка отображается правильно, что показывает, что графический интерфейс не является принципиально неспособным отображать эти символы, но как только MATLAB его считывает, он больше отображает его правильно. Например:

>> pasted = 'ΓΔΘΛΞΠΣΦΩαβγδεζηθικλμνξπρςστυφχψω'

pasted =


>> 

Спасибо!

4b9b3361

Ответ 1

Ниже я расскажу о своих выводах после некоторого рытья... Рассмотрим эти тестовые файлы:

a.txt

ΓΔΘΛΞΠΣΦΩαβγδεζηθικλμνξπρςστυφχψω

b.txt

தமிழ்

Сначала мы читаем файлы:

%# open file in binary mode, and read a list of bytes
fid = fopen('a.txt', 'rb');
b = fread(fid, '*uint8')';             %'# read bytes
fclose(fid);

%# decode as unicode string
str = native2unicode(b,'UTF-8');

Если вы попытаетесь напечатать строку, вы получите кучу бессмыслицы:

>> str
str =

Тем не менее, str содержит правильную строку. Мы можем проверить код Юникода каждого символа, который находится так же, как вы можете видеть вне диапазона ASCII (последние два - это строки, не подлежащие печати CR-LF):

>> double(str)
ans =
  Columns 1 through 13
   915   916   920   923   926   928   931   934   937   945   946   947   948
  Columns 14 through 26
   949   950   951   952   953   954   955   956   957   958   960   961   962
  Columns 27 through 35
   963   964   965   966   967   968   969    13    10

К сожалению, MATLAB кажется неспособным отобразить эту строку Unicode в графическом интерфейсе самостоятельно. Например, все эти ошибки:

figure
text(0.1, 0.5, str, 'FontName','Arial Unicode MS')
title(str)
xlabel(str)

Один трюк, который я нашел, - это использовать встроенную возможность Java:

%# Java Swing
label = javax.swing.JLabel();
label.setFont( java.awt.Font('Arial Unicode MS',java.awt.Font.PLAIN, 30) );
label.setText(str);
f = javax.swing.JFrame('frame');
f.getContentPane().add(label);
f.pack();
f.setVisible(true);

enter image description here


Поскольку я готовился написать выше, я нашел альтернативное решение. Мы можем использовать недокументированную функцию DefaultCharacterSet и установить кодировку на UTF-8 (на моей машине она ISO-8859-1 по умолчанию):

feature('DefaultCharacterSet','UTF-8');

Теперь с правильным шрифтом (вы можете изменить шрифт, используемый в окне команд из Preferences > Font), мы можем напечатать строку в приглашении (обратите внимание, что DISP по-прежнему не может печатать Юникод):

>> str
str =
ΓΔΘΛΞΠΣΦΩαβγδεζηθικλμνξπρςστυφχψω

>> disp(str)
Î"Î"ΘΛΞΠΣΦΩαβγδεζηθικλμνξπÏςστυφχψω

И чтобы отобразить его в графическом интерфейсе, UICONTROL должен работать (под капотом, я думаю, что это действительно компонент Java Swing):

uicontrol('Style','text', 'String',str, ...
    'Units','normalized', 'Position',[0 0 1 1], ...
    'FontName','Arial Unicode MS', 'FontSize',30)

enter image description here

К сожалению, TEXT, TITLE, XLABEL и т.д. все еще показывают мусор:

enter image description here


В качестве побочного примечания. Трудно работать с источниками m файлов, содержащими символы Unicode в редакторе MATLAB. Я использовал Notepad ++ с файлами, закодированными как UTF-8 без спецификации.