<?php
namespace addon\printer\service;
use GDText\Box;
use GDText\Color;
class GD
{
// private $fontFile = 'msyh.ttf';
private $fontFile = 'malgun.ttf';
private $dir = 'upload/printer/temp';
private $filename = '1.jpg';
private $width = 360;
private $height = 300;
private $content = [];
private $imgObj;
private $bgColor;
private $color;
private $use_height = 0;//已画高度
private $defaultSize = 16;
private $defaultPaddingTop = 30;
public function __construct()
{
dir_mkdir($this->dir);
}
public function setHeight()
{
$height = 0;
foreach ($this->content as $line){
if(empty($line['columns'])){
$size = $line['size'] ?? $this->defaultSize;
$paddingTop = $line['paddingTop'] ?? $this->defaultPaddingTop;
$lineHeight = $size + $paddingTop / 2;
$height += $lineHeight;
}else{
foreach ($line['columns'] as $k=>$column){
if($k == 0){
$size = $column['size'] ?? $this->defaultSize;
$paddingTop = $column['paddingTop'] ?? $this->defaultPaddingTop;
$lineHeight = $size + $paddingTop / 2;
$height += $lineHeight;
}
}
}
}
$this->height = $height + 20;
}
public function setBgColor()
{
$this->bgColor = imagecolorallocate ($this->imgObj, 255, 255, 255); //设置背景颜色
}
public function setColor()
{
$this->color = imagecolorallocate ($this->imgObj, 0, 0, 0); //设置字体颜色
}
public function setDir($dir)
{
dir_mkdir($dir);
$this->dir = $dir;
}
public function setFilename($filename)
{
$this->filename = $filename;
}
public function getPath()
{
return $this->dir . '/' .$this->filename;
}
// 获取居中的XY
public function getCenterXY($line)
{
$size = $line['size'] ?? $this->defaultSize; // 字体大小
$angle = $line['angle'] ?? 0; // 角度大小
$content = $line['title'];
$a = imagettfbbox($size, $angle, $this->fontFile, $content); //得到字符串虚拟方框四个点的坐标
$len = $a[2] - $a[0];
$x = ($this->width-$len)/2;
$y = $a[3]-$a[5];
return [$x,$y];
}
// 获取居右的XY
public function getRightXY($line)
{
$size = $line['size'] ?? $this->defaultSize; // 字体大小
$angle = $line['angle'] ?? 0; // 角度大小
$content = $line['title'];
$a = imagettfbbox($size, $angle, $this->fontFile, $content); //得到字符串虚拟方框四个点的坐标
$len = $a[2] - $a[0];
$x = $this->width-$len;
$y = $a[3]-$a[5];
return [$x,$y];
}
//设置输出一行文字
public function setLineText($line)
{
//2. 开始绘画
$size = $line['size'] ?? $this->defaultSize; // 字体大小
$angle = $line['angle'] ?? 0; // 角度大小
$content = $line['title'];
$paddingTop = $line['paddingTop'] ?? $this->defaultPaddingTop;
$lineHeight = $size + $paddingTop / 2;
$x = 0;
$y = $this->use_height + $lineHeight;
if(!empty($line['align'])){
if($line['align'] == 'center'){
list($x,$y2) = $this->getCenterXY($line);
} elseif ($line['align'] == 'right'){
list($x,$y2) = $this->getRightXY($line);
}
}
if(empty($line['allow_line'])){
imagettftext($this->imgObj, $size,$angle, $x, $y, $this->color,$this->fontFile,$content);
$this->use_height += $lineHeight;
}else{
//需要换行,用另一个函数
$box = new Box($this->imgObj);
$font = realpath($this->fontFile);
//显示的文字
$text = $content;
$box->setFontFace($font);
$box->setFontColor(new Color(0, 0, 0));//字体颜色
$box->setFontSize($size);//字体大小
// $box->setLineHeight(1.5);//行高
//下面为关键函数:画一个文本框:
$box->setBox($x, $this->use_height, $this->width, $lineHeight * 2);//文本框起始点(x,y),长宽
//第一个参数设置水平:靠左-left,居中-center,靠右-right;第二个参数设置垂直:靠左-left,居中-center,靠右-right
$box->setTextAlign('left', 'top');
$box->draw($text,true);
$this->use_height += $lineHeight * 2;
}
}
//设置输出一行图片
public function setLineImg($line)
{
}
//画虚线
public function setDashedline($line)
{
$size = $line['size'] ?? 2; // 字体大小
$angle = $line['angle'] ?? 0; // 角度大小
$paddingTop = $line['paddingTop'] ?? $this->defaultPaddingTop;
$lineHeight = $size + $paddingTop / 2;
$x1 = 0;
$y1 = $this->use_height + $lineHeight;
$x2 = $this->width;
$y2 = $this->use_height + $lineHeight;
/* 画一条虚线,5 个红色像素,5 个白色像素 */
$w = imagecolorallocate($this->imgObj, 0, 0, 0);
$b = imagecolorallocate($this->imgObj, 255, 255, 255);
$style = array($b,$b,$b,$b,$b,$w,$w,$w,$w,$w);
imagesetstyle($this->imgObj, $style);
imageline($this->imgObj, $x1, $y1, $x2, $y2, IMG_COLOR_STYLED);
$this->use_height += $lineHeight;
}
//设置输出一行多列
public function setLineColumn($line)
{
$size = $line['size'] ?? $this->defaultSize; // 字体大小
$angle = $line['angle'] ?? 0; // 角度大小
$paddingTop = $line['paddingTop'] ?? $this->defaultPaddingTop;
$lineHeight = $size + $paddingTop / 2;
$use_width = 0;
foreach ($line['columns'] as $k=>$column){
$x = $use_width;
$y = $this->use_height + $lineHeight;
$content = $column['title'];
if(!empty($column['align'])){
if($column['align'] == 'right'){
list($x) = $this->getColumnRightXY($column,$use_width);
}
}
imagettftext($this->imgObj, $size,$angle, $x, $y, $this->color,$this->fontFile,$content);
$use_width += $column['maxWidth'];
}
$this->use_height += $lineHeight;
}
// 获取列居右的XY
public function getColumnRightXY($line,$use_width)
{
$size = $line['size'] ?? $this->defaultSize; // 字体大小
$angle = $line['angle'] ?? 0; // 角度大小
$content = $line['title'];
$a = imagettfbbox($size, $angle, $this->fontFile, $content); //得到字符串虚拟方框四个点的坐标
$len = $a[2] - $a[0];
$x = $use_width + $line['maxWidth'] - $len;
$y = $a[3]-$a[5];
return [$x,$y];
}
public function setContent($content = [])
{
$this->content = $content;
}
public function setContentTest($content = [])
{
$content = [
['title'=>'小票名称','align'=>'center','paddingTop'=>40],
['title'=>'-','type'=>'dashedline'],
['title'=>'商城名称','size'=>32,'align'=>'center','paddingTop'=>40],
['title'=>'-','type'=>'dashedline'],
['title'=>'订单时间:2021-04-15 12:12:12'],
['title'=>'订单编号:202104151212125565'],
['title'=>'-','type'=>'dashedline'],
[
'columns'=>[
['title'=>'商品名称','maxWidth'=>200],
['title'=>'数量','maxWidth'=>50,'align'=>'right'],
['title'=>'金额','maxWidth'=>100,'align'=>'right'],
]
],
['title'=>'-','type'=>'dashedline'],
[
'columns'=>[
['title'=>'烤土豆(超级辣)','maxWidth'=>200],
['title'=>'x3','maxWidth'=>50,'align'=>'right'],
['title'=>'100000','maxWidth'=>100,'align'=>'right'],
]
],
[
'columns'=>[
['title'=>'烤土豆(超级辣)','maxWidth'=>200],
['title'=>'x3','maxWidth'=>50,'align'=>'right'],
['title'=>'100000','maxWidth'=>100,'align'=>'right'],
]
],
[
'columns'=>[
['title'=>'烤土豆(超级辣)','maxWidth'=>200],
['title'=>'x3','maxWidth'=>50,'align'=>'right'],
['title'=>'100000','maxWidth'=>100,'align'=>'right'],
]
],
['title'=>'-','type'=>'dashedline'],
['title'=>'商品总额:500000'],
['title'=>'订单共8件商品,总计30'],
['title'=>'-','type'=>'dashedline'],
['title'=>'买家留言:微辣,多放孜然','size'=>32,'allow_line'=>true],
['title'=>'-','type'=>'dashedline'],
['title'=>'谢谢惠顾,欢迎下次光临','align'=>'center'],
];
$this->content = $content;
}
public function render()
{
//1. 创建画布
$this->setHeight();
$this->imgObj = imagecreate($this->width,$this->height);
$this->setBgColor();
$this->setColor();
echo '高度:'.$this->height."<br/>";
imagefill($this->imgObj, 0, $this->height, $this->bgColor);//填充背景
//2. 开始绘画
foreach ($this->content as $line){
if(empty($line['columns'])){
if(!isset($line['type'])){
//输入文字
$this->setLineText($line);
}elseif ($line['type'] == 'img'){
//输入图片
$this->setLineImg($line);
}elseif ($line['type'] == 'dashedline'){
//画虚线
$this->setDashedline($line);
}
}else{
$this->setLineColumn($line);
}
}
//3. 输出图像
header('Content-type: image/jpeg');
imagejpeg ($this->imgObj,$this->getPath()); //以 PNG 格式将图像输出
imagecolortransparent($this->imgObj,$this->bgColor);//将之前的背景颜色都填充为透明色
//4. 释放资源
imagedestroy($this->imgObj);
echo '完成';
}
public function getUrl()
{
return request()->domain().'/'.$this->getPath();
}
}
使用方法:
// 图文打印
public function YlyprintImg($order_info, $printer, $shop_info)
{
//打印模板
$print_template_model = new PrinterTemplate();
$print_template_data = $print_template_model->getPrinterTemplateInfo([['template_id', '=', $printer['template_id']]]);
$print_template = $print_template_data['data'];
$config = new YlyConfig($printer['open_id'], $printer['apikey']);
$printer_model = new Printer();
$access_token = $printer_model->getYlyToken($config, $printer['site_id']);
$machine_code = $printer['printer_code']; //商户授权机器码
$origin_id = $order_info['order_no']; //内部订单号(32位以内)
$content = [
['title'=>$printer['print_num'],'align'=>'center','paddingTop'=>40],
];
//小票名称
if ($print_template['title'] != '') {
$content[] = ['title'=>$print_template['title'],'align'=>'center','paddingTop'=>40];
$content[] = ['title'=>'-','type'=>'dashedline'];
}
//商城名称
if ($print_template['head'] == 1) {
$content[] = ['title'=>$print_template['site_name'],'size'=>32,'align'=>'center','paddingTop'=>40];
$content[] = ['title'=>'-','type'=>'dashedline'];
}
$content[] = ['title'=>getLang("ORDER_TIME").":" . date("Y-m-d H:i", $order_info['pay_time'])];
$content[] = ['title'=>getLang("ORDER_NUMBER").":" . $order_info['order_no']];
$content[] = ['title'=>'-','type'=>'dashedline'];
$content[] = [
'columns'=>[
['title'=>getLang('PRODUCT_NAME'),'maxWidth'=>200],
['title'=>getLang("NUMBER"),'maxWidth'=>50,'align'=>'right'],
['title'=>getLang("PRICE"),'maxWidth'=>100,'align'=>'right'],
]
];
$content[] = ['title'=>'-','type'=>'dashedline'];
foreach ($order_info['order_goods'] as $goods) {
$sku_name_list = $this->r_str_pad_1($goods['sku_name'], $n = 7);
foreach ($sku_name_list as $index => $value) {
if ($index == 0) {
$content[] = [
'columns'=>[
['title'=>$value,'maxWidth'=>200],
['title'=>'x'.$goods['num'],'maxWidth'=>50,'align'=>'right'],
['title'=>'₩'.(int)$goods['price'],'maxWidth'=>100,'align'=>'right'],
]
];
} else {
$content[] = ['title'=>$value];
}
}
}
$content[] = ['title'=>'-','type'=>'dashedline'];
if ($order_info["goods_money"] > 0) {
$content[] = ['title'=>getLang('GOODS_MONEY').": ₩" . $order_info['goods_money']];
}
if ($order_info["coupon_money"] > 0) {
$content[] = ['title'=>getLang('COUPON_MONEY').": ₩" . $order_info['coupon_money']];
}
if ($order_info["promotion_money"] > 0) {
$content[] = ['title'=>getLang('PROMOTION_MONEY').": ₩" . $order_info['promotion_money']];
}
if ($order_info["point_money"] > 0) {
$content[] = ['title'=>getLang('POINT_MONEY').": ₩" . $order_info['point_money']];
}
if ($order_info["adjust_money"] > 0) {
$content[] = ['title'=>getLang('ADJUST_MONEY').": ₩" . $order_info['adjust_money']];
}
if ($order_info["delivery_money"] > 0) {
$content[] = ['title'=>getLang('DELIVERY_MONEY').": ₩" . $order_info['delivery_money']];
}
if ($order_info["invoice_money"] > 0) {
$content[] = ['title'=>getLang('INVOICE_MONEY').": ₩" . $order_info['invoice_money']];
}
if ($order_info["invoice_delivery_money"] > 0) {
$content[] = ['title'=>getLang('INVOICE_DELIVERY_MONEY').": ₩" . $order_info['invoice_delivery_money']];
}
if ($order_info["goods_num"] > 0) {
$content[] = ['title'=>getLang('ORDER_GOODS_NUM_TIPS',['goods_num'=> $order_info['goods_num']])." ₩" . $order_info['order_money']];
}
$content[] = ['title'=>'-','type'=>'dashedline'];
/******************** 备注信息 **************************/
//买家留言
if ($print_template['buy_notes'] == 1) {
['title'=>getLang('BUYER_MESSAGE').': '.$order_info["buyer_message"],'size'=>32,'allow_line'=>true];
$content[] = ['title'=>'-','type'=>'dashedline'];
}
//卖家留言
// if($print_template['seller_notes'] == 1){
// $content .= "<FH2>卖家留言:".$order_info["remark"]."</FH2>\n";
// $content .= str_repeat('.', 32);
// }
/******************** 买家信息 **************************/
//买家姓名
if ($print_template['buy_name'] == 1) {
$content[] = ['title'=>$order_info["name"]];
}
//联系方式
if ($print_template['buy_mobile'] == 1) {
$content[] = ['title'=>$order_info["mobile"]];
}
//地址
if ($print_template['buy_address'] == 1) {
$content[] = ['title'=>$order_info['full_address'] . "-" . $order_info['address']];
}
if ($print_template['buy_name'] == 1 || $print_template['buy_mobile'] == 1 || $print_template['buy_address'] == 1) {
$content[] = ['title'=>'-','type'=>'dashedline'];
}
/******************** 商城信息 **************************/
//联系方式
if ($print_template['shop_mobile'] == 1) {
$content[] = ['title'=>$shop_info['mobile'] ];
}
//地址
if ($print_template['shop_address'] == 1) {
// $content .= "" . $shop_info['province_name'] . $shop_info['city_name'] . $shop_info['district_name'] . $shop_info['address'] . "\n";
}
if ($print_template['shop_mobile'] == 1 /*|| $print_template['shop_address'] == 1*/) {
$content[] = ['title'=>'-','type'=>'dashedline'];
}
//二维码
if ($print_template['shop_qrcode'] == 1) {
// $content .= "<QR>" . $print_template['qrcode_url'] . "</QR>";
// $content .= str_repeat('.', 32);
}
/******************** 门店信息 **************************/
if ($order_info['delivery_store_id'] > 0 && !empty($order_info['delivery_store_name']) && !empty($order_info['delivery_store_info'])) {
$store_info = json_decode($order_info['delivery_store_info'], true);
$content[] = ['title'=>$order_info['delivery_store_name'] ];//门店名称
$content[] = ['title'=>$store_info['telphone'] ];//门店电话
$content[] = ['title'=>$store_info['full_address'] ];//门店地址
$content[] = ['title'=>'-','type'=>'dashedline'];
}
//底部内容
if (!empty($print_template['bottom'])) {
$content[] = ['title'=>$print_template['bottom'],'align'=>'center'];
}
try {
/**图文接口开始**/
$print = new PicturePrintService($access_token, $config);
$gd = new GD();
$gd->setContent($content);
$gd->setDir('upload/printer/'.date('Ymd'));
$gd->setFilename($origin_id.'.jpg');
$gd->render();
$url = $gd->getUrl();
$res = $print->index($machine_code, $url, $origin_id);
} catch (\Exception $e) {
echo $e->getMessage();
}
}