2012-06-19 6 views
7

Ich muss ein Bild mit chinesischem Text kommentieren und ich benutze jetzt Imagick-Bibliothek.wie imagick annoTateImage für chinesischen Text zu verwenden?

Ein Beispiel für einen chinesischen Text ist

这 是 中文

Die chinesische verwendete Font-Datei ursprünglich this

Die Datei ist gestattet 华文 黑体 Ttf

kann es auch sein, gefunden in Mac OSX unter/Library/Font

Ich habe es umbenannt in Englisch STHeiTi.ttf machen es einfacher, th zu nennen Die Datei im PHP-Code.

Insbesondere the Imagick::annotateImage function

Ich bin auch using the answer from "How can I draw wrapped text using Imagick in PHP?".

Der Grund, warum ich es benutze, ist, weil es für englischen Text und Anwendung erfolgreich ist, sowohl Englisch als auch Chinesisch zu kommentieren, wenn auch nicht gleichzeitig.

Das Problem ist, dass, wenn ich die annotateImage mit chinesischen Text laufen, ich Anmerkung erhalten, die wie 罍

-Code sieht here enthalten

+1

chinesischer Text? Wie wäre es, zuerst eine Grafik der chinesischen Symbole zu erstellen und diese dann auf das Bild zu übertragen? – hakre

+0

Wie gehe ich dabei vor? –

+1

Nun, für jedes chinesische Schriftzeichen, erstellen Sie ein Bild, das es anzeigt. Dann fügen Sie diese Bilder zum Beispiel zusammen. Möglicherweise nicht die beste Methode, aber möglicherweise erspart Ihnen das Problem, tatsächlich einige chinesische Schriftarten zu verwenden. – hakre

Antwort

2

Voll Lösung hier:

https://gist.github.com/2971092/232adc3ebfc4b45f0e6e8bb5934308d9051450a4

Leitideen:

muss die HTML-charset und interne Codierung auf dem Formular festgelegt und auf der Bearbeitungsseite

header('Content-Type: text/html; charset=utf-8'); 
mb_internal_encoding('utf-8'); 

These Zeilen müssen in den obersten Zeilen der PHP-Dateien sein.

Mit dieser Funktion, um zu bestimmen, ob Text Chinese ist und verwenden Sie die richtige Schriftart-Datei

function isThisChineseText($text) { 
    return preg_match("/\p{Han}+/u", $text); 
} 

Weitere Details Besuche https://stackoverflow.com/a/11219301/80353

Set Textencoding richtig in ImagickDraw Objekt

$draw = new ImagickDraw(); 

// set utf 8 format 
$draw->setTextEncoding('UTF-8'); 

Beachten Sie die Großbuchstaben U TF. Dies war darauf helfend hier durch Walter Tross in seiner Antwort auf mich aus: https://stackoverflow.com/a/11207521/80353

Verwenden preg_match_all englische Wörter zu explodieren, chinesische Wörter und Räume

// separate the text by chinese characters or words or spaces 
preg_match_all('/([\w]+)|(.)/u', $text, $matches); 
$words = $matches[0]; 

durch diese Antwort Inspired https://stackoverflow.com/a/4113903/80353

funktioniert auch für englischen Text

+1

Der letzte Regex wird die Zeichenfolge "UTF-8" in 3 separate "Wörter" teilen. Ihre Korrektur von wordWrapAnnotation ist falsch, auch weil sie jetzt am Anfang der zweiten Zeile ein Leerzeichen oder Satzzeichen zurückgeben kann. 'explode ('', ...)' war richtig, es sei denn, es gibt ein bisschen Chinesisch, das mir nicht bewusst ist. Ich denke auch, Sie hätten meine Lösung akzeptieren können, da Sie die zwei Code-Fixes verwendet haben, die es enthält. Es stimmt, dass Sie Informationen hinzugefügt haben, aber das könnte in Kommentaren geschehen sein (und ich hätte auch meine Lösung bearbeiten können). –

+0

OK, jetzt sehe ich, was die "Eigenart" der chinesischen Schrift ist: Es gibt im Allgemeinen keine Leerzeichen zwischen Wörtern. Eine Möglichkeit, sich für Ihre Zwecke in "Wörter" aufzuteilen, könnte etwa so aussehen: 'preg_split ("/((? <=) | (? = \ P {Han}) (? = \ PL))/u ", $ str, -1, PREG_SPLIT_NO_EMPTY) ', die die Zeichenfolge nach Leerzeichen oder vor Han" Buchstaben "(tatsächlich Wörter)" schneidet ", aber die abschließenden Leerzeichen sollten getrennt gehandhabt werden (nur wenn keine Zeilen getrennt werden) tritt ein). Hinweis: Es gibt ein Leerzeichen nach '? <='. –

+1

Die obige Regex sollte erweitert werden, damit bestimmte Zeichen keine Zeile beenden können (diese Zeichen sind äquivalent zu westlichen Zeichen, denen normalerweise ein Leerzeichen vorangestellt ist, wie öffnende Klammern oder öffnende Anführungszeichen - siehe zB [hier] (http: //msdn.microsoft.com/en-us/goglobal/bb688158.aspx)) –

3

Ich fürchte, Sie werden eine TTF wählen müssen, die chinesische unterstützen Codepunkte. Es gibt viele Quellen für diese, hier sind zwei:

http://www.wazu.jp/gallery/Fonts_ChineseTraditional.html

http://wildboar.net/multilingual/asian/chinese/language/fonts/unicode/non-microsoft/non-microsoft.html

+0

Was meinen Sie mit Codepunkten? –

+0

@kimsia http://inamidst.com/stuff/unidata/ –

+0

@kimsia: oder [Unicode] (http://en.wikipedia.org/wiki/Unicode#Architecture_and_terminology) in Wikipedia –

5

Das Problem ist Sie ImageMagick die Ausgabe eines "Splitter" (wordWrapAnnotation) füttern, zu der Sie utf8_decode ing die Texteingabe. Dies ist mit Sicherheit falsch, wenn Sie mit chinesischem Text zu tun haben. utf8_decode kann nur mit UTF-8-Text umgehen, der in ISO-8859-1 (die gebräuchlichste 8-Bit-Erweiterung von ASCII) konvertiert werden kann.

Jetzt hoffe ich, dass Sie Text UTF-8 codiert ist. Wenn dies nicht der Fall, könnten Sie in der Lage sein, es so zu konvertieren:

$text = mb_convert_encoding($text, 'UTF-8', 'BIG-5'); 

oder ähnliche

$text = mb_convert_encoding($text, 'UTF-8', 'GB18030'); // only PHP >= 5.4.0 

(im Code $text sind eher $text1 und $text2).

Dann gibt es (mindestens) zwei Dinge in Ihrem Code zu beheben:

  1. den Text übergeben "wie er ist" (ohne utf8_decode) zu wordWrapAnnotation,
  2. Änderung des Argument von setTextEncoding von "utf-8" zu "UTF-8" nach specs

ich hoffe, dass alle Variablen in Ihrem Code in einigen fehlt ein Teil davon initialisiert werden. Mit den beiden obigen Änderungen (die zweite ist vielleicht nicht notwendig, aber Sie wissen nie ...), und mit den fehlenden Teilen an Ort und Stelle, sehe ich keinen Grund, warum Ihr Code nicht funktionieren sollte, es sei denn Ihre TTF-Datei ist kaputt oder die Imagick Bibliothek ist kaputt (imagemagick, auf der Imagick basiert, ist eine große Bibliothek, so halte ich diese letzte Möglichkeit eher unwahrscheinlich).

EDIT:

Ihre Anfrage Nach, ich meine Antwort aktualisieren mit

a) die Tatsache, dass mb_internal_encoding('utf-8') Einstellung für die Lösung sehr wichtig ist, wie Sie in Ihrem answer sagen, und

b) mein Vorschlag für einen besseren Liniensplitter, der für westliche Sprachen und für Chinesisch akzeptabel funktioniert, und das ist wahrscheinlich ein guter Ausgangspunkt für andere Sprachen mit Han-Logogrammen (japanisches Kanji und koreanisches Hanja):

In Worten: Die Eingabe wird zuerst bereinigt, indem alle Whitespaces, einschließlich Zeilenumbrüche, durch ein einzelnes Leerzeichen ersetzt werden, mit Ausnahme von führenden und nachfolgenden Whitespaces, die entfernt werden. Dann wird es entweder in Leerzeichen oder direkt vor Han-Zeichen aufgeteilt, denen keine "führenden" Zeichen vorangestellt sind (wie öffnende Klammern oder öffnende Anführungszeichen) oder direkt vor "führenden" Zeichen. Zeilen werden so zusammengestellt, dass sie nicht mehr als $maxWidth Pixel horizontal gerendert werden, außer wenn dies durch die Aufteilungsregeln nicht möglich ist (in diesem Fall wird das endgültige Rendering wahrscheinlich überlaufen). Eine Modifikation, um das Aufteilen in Überlauffälle zu erzwingen, ist nicht schwierig. Beachten Sie, dass z. B. chinesische Interpunktionszeichen in Unicode nicht als Han klassifiziert werden, so dass mit Ausnahme der "führenden" Interpunktionszeichen keine Zeilenumbrüche vor dem Algorithmus eingefügt werden können.

+0

Dies ist der wahrscheinlichste Grund für eine fehlerhafte Codierung. –

+0

Hallo Walter, deine Antwort hat mir geholfen, die endgültige Lösung zu finden. Ich möchte Ihnen für Ihre Hilfe danken. –

+0

Ich habe übrigens die mb_convert_encoding-Lösung nicht benutzt. –