Problem karmisz ImageMagick wyjście "rozgałęźnika linii" (wordWrapAnnotation
), do którego jesteś utf8_decode
ing wprowadzenie tekstu. Na pewno jest to złe, jeśli masz do czynienia z chińskim tekstem. utf8_decode
może przetwarzać tylko tekst UTF-8, który MOŻE być przekonwertowany na ISO-8859-1 (najpopularniejsze 8-bitowe rozszerzenie ASCII).
Mam nadzieję, że tekst jest kodowany UTF-8. Jeśli tak nie jest, może być w stanie przekształcić go tak:
$text = mb_convert_encoding($text, 'UTF-8', 'BIG-5');
lub jak to
$text = mb_convert_encoding($text, 'UTF-8', 'GB18030'); // only PHP >= 5.4.0
(w kodzie $text
jest raczej $text1
i $text2
).
Następnie istnieją (co najmniej) dwie rzeczy do poprawienia w kodzie:
- przekazać tekst „tak jak jest” (bez
utf8_decode
) do wordWrapAnnotation
,
- zmiana argument
setTextEncoding
z "utf-8"
do "UTF-8"
zgodnie specs
mam nadzieję, że wszystkie zmienne w kodzie są inicjowane w jakiejś brakującej części. Przy dwóch powyższych zmianach (drugi może nie być konieczny, ale nigdy nie wiadomo ...), a przy brakujących częściach w miejscu, nie widzę powodu, dla którego twój kod nie powinien działać, chyba że plik TTF jest uszkodzony lub Biblioteka Imagick
jest zepsuta (imagemagick
, na której bazuje Imagick
, jest świetną biblioteką, więc uważam tę ostatnią możliwość raczej za mało prawdopodobną).
EDIT:
obserwuję Państwa życzenie mogę zaktualizować moją odpowiedź z
a) fakt, że ustawienie mb_internal_encoding('utf-8')
jest bardzo ważne dla rozwiązania, jak mówisz w swojej answer i
b) moja propozycja lepszego podziału linii, która działa akceptowalnie dla języków zachodnich i chińskiego, i to jest prawdopodobnie dobry punkt wyjścia dla innych języków używających logogramów Han (japońskie kanji i koreańska hanja):
function wordWrapAnnotation(&$image, &$draw, $text, $maxWidth)
{
$regex = '/(|(?=\p{Han})(?<!\p{Pi})(?<!\p{Ps})|(?=\p{Pi})|(?=\p{Ps}))/u';
$cleanText = trim(preg_replace('/[\s\v]+/', ' ', $text));
$strArr = preg_split($regex, $cleanText, -1, PREG_SPLIT_DELIM_CAPTURE |
PREG_SPLIT_NO_EMPTY);
$linesArr = array();
$lineHeight = 0;
$goodLine = '';
$spacePending = false;
foreach ($strArr as $str) {
if ($str == ' ') {
$spacePending = true;
} else {
if ($spacePending) {
$spacePending = false;
$line = $goodLine.' '.$str;
} else {
$line = $goodLine.$str;
}
$metrics = $image->queryFontMetrics($draw, $line);
if ($metrics['textWidth'] > $maxWidth) {
if ($goodLine != '') {
$linesArr[] = $goodLine;
}
$goodLine = $str;
} else {
$goodLine = $line;
}
if ($metrics['textHeight'] > $lineHeight) {
$lineHeight = $metrics['textHeight'];
}
}
}
if ($goodLine != '') {
$linesArr[] = $goodLine;
}
return array($linesArr, $lineHeight);
}
W słowach: dane wejściowe są najpierw oczyszczane przez zastąpienie wszystkich przebiegów białych znaków, w tym znaków nowej linii, pojedynczym odstępem, z wyjątkiem początkowych i końcowych białych znaków, które są usuwane. Następnie jest dzielona w spacjach lub tuż przed znakami Han nie poprzedzonymi znakami "wiodącymi" (takimi jak otwarcie nawiasów lub otwarcie cudzysłowów) lub bezpośrednio przed znakami "wiodącymi". Linie są montowane, aby nie były renderowane poziomo ponad 12,pikseli, z wyjątkiem sytuacji, gdy nie jest to możliwe dzięki regułom podziału (w takim przypadku ostateczne renderowanie prawdopodobnie przepełni się). Modyfikacja w celu wymuszenia podziału w skrzynkach przelewowych nie jest trudna. Zwróć uwagę, że np. Chińska interpunkcja nie jest sklasyfikowana jako Han w Unicode, więc poza "wiodącą" interpunkcją przed algorytmem nie można wstawić przed nim linii.
Tekst w języku chińskim? A co z pierwszym tworzeniem grafiki chińskich symboli, a następnie scaleniem jej z obrazem? – hakre
Jak mam to zrobić? –
Cóż, dla każdej chińskiej postaci utwórz jeden obraz, który ją wyświetli. Następnie umieść te obrazy razem na przykład. Może nie być najlepszą metodą, ale może zaoszczędzić ci problemu, aby rzeczywiście użyć chińskiej czcionki. – hakre