Monday, May 25, 2009

PHP string to image utf-8 unicode

PHP string to image utf-8 unicode
<?php
### str to image.
// Path to our font file
$font = 'mingliu.ttc';

$size = 10;
$width = 465;
$width_padding = 15;

$text = "How To Become A Hacker Why This Document? As editor of the Jargon File, I often get email requests from enthusiastic network newbies asking (in effect) \"how can I learn to be a wizard hacker?\". Oddly enough there don't seem to be any FAQs or Web documents that address this vital question, so here's mine. 身為 Jargon File 的編輯, 常有一些網路新手發 mail 問我 \"如何成為一個厲害的 hacker?\". 但, 很奇怪的, 似乎沒有任何的 FAQs 或 Web documents 說明這麼重要 的問題, 所以我寫了一份我自己的看法. If you are reading a snapshot of this document offline, the current version lives at href=\"http://www.ccil.org/~esr/faqs/hacker-howto.html. 如果你是以 offline 的方式在看這一份文件的某一個版本, 那麼你可以在 \"http://www.ccil.org/~esr/faqs/hacker-howto.html\" 找到這份文件的目前最新版本. What Is A Hacker? 怎麼樣才算是一位 Hacker ?? The Jargon File contains a bunch of definitions of the term 'hacker', most having to do with technical adeptness and a delight in solving problems and overcoming limits. If you want to know how to become a hacker, though, only two are really relevant. 在 Jargon File 裏有一堆關於 'hacker' 這個名詞的定義, 大部份必須是技術上的 行家或熱衷於解決問題, 克服限制的人. 然而, 如果你想知道如何成為一位 hacker, 有兩件事是很有關連的.";

$textArr = _mb_wordwrap($text, $font, $size, $width);
$heightTmp = count($textArr) * 20;
$height = $heightTmp + 50;

$text = '';
foreach ($textArr as $line) {
$text .= $line . "\n";
}


// Create a 300x150 image
$im = imagecreatetruecolor($width + $width_padding, $height);
$black = imagecolorallocate($im, 0, 0, 0);
$white = imagecolorallocate($im, 255, 255, 255);
$red = imagecolorallocate($im, 255, 0, 0);
$green = imagecolorallocate($im, 0, 128, 0);

// Set the background to be white
imagefilledrectangle($im, 0, 0, $width + 20, $height, $white);

$x = 10;
$y = 20;
$angle = 0; // ### The angle in degrees, with 0 degrees being left-to-right reading text. Higher values represent a counter-clockwise rotation. For example, a value of 90 would result in bottom-to-top reading text.

// Write it
imagettftext($im, $size, $angle, $x, $y, $black, $font, $text);

$textTmp = "Copyright © 2009 www.randomdomain.com\n";
$textTmp .= "All right reserved. 版權所有,未經同意,不得翻印";
imagettftext($im, $size, $angle, $x, $y + $heightTmp, $green, $font, $textTmp);

// Set the content-type
// if you want to output to browser, uncomment following line, and remove the file name from next line.
header('Content-type: image/png');

// Using imagepng() results in clearer text compared with imagejpeg()
imagepng($im);
imagedestroy($im);

/**
* Mickey9801 at ComicParty dot com:
* Most of functions shared here seems only work with western language and
* is not suitable for multibyte characters (like Chinese). I have written
* a function using mb_string functions to match the need of multibyte character
* word wrapping.
* I also added some machanism so that English word won't be cut off at the
* end of line. Of couse you must use unicode string on GD.

* @param
* @return
*/
function _mb_wordwrap($txt,$font,$size,$width, $encoding = 'UTF-8') {
$pointer = 0;
$this_line_start = 0;
$this_line_strlen = 1;
$single_byte_stack = "";
$result_lines = array();
$txtLen = mb_strlen($txt, 'UTF-8');
while ($pointer <= $txtLen) {
$this_char = mb_substr($txt, $pointer, 1, $encoding);
$tmp_line = mb_substr($txt, $this_line_start, $this_line_strlen, $encoding);
$tmp_line_bbox = imagettfbbox($size,0 ,$font ,$tmp_line);
$this_line_width = $tmp_line_bbox[2]-$tmp_line_bbox[0];
if ($this_line_width > $width) {
// If last word is alphanumeric, put it to next line rather then cut it off
if ($single_byte_stack != "") {
$stack_len = mb_strlen($single_byte_stack, $encoding);
$this_line_strlen -= $stack_len;
$pointer -= $stack_len;
}
$result_lines[] = mb_substr($txt, $this_line_start, $this_line_strlen-1, $encoding);
$this_line_start = $pointer;
$this_line_strlen = 1;
$single_byte_stack = "";
} else {
// Prevent to cut off english word at the end of line
// if this character is a alphanumeric character or open bracket, put it into stack
if (
(ord($this_char)>=48 && ord($this_char)<=57) ||
(ord($this_char)>=65 && ord($this_char)<=91) ||
(ord($this_char)>=97 && ord($this_char)<=123) ||
ord($this_char)==40 ||
ord($this_char)==60 ||
($single_byte_stack=="" && (ord($this_char)==34 || ord($this_char)==39))
) $single_byte_stack .= $this_char;
else $single_byte_stack = ""; // Clear stack if met multibyte character and not line end
$this_line_strlen++;
$pointer++;
}
}
// Move remained word to result
$result_lines[] = mb_substr($txt, $this_line_start, $txtLen, $encoding);

return $result_lines;
}
?>

No comments: