GD库画小票打印图片
<?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();
        }
    }
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇