<?php
namespace Libraries\common;
use Picqer\Barcode\BarcodeGeneratorPNG;
/**
* 生成面单图片
composer require picqer/php-barcode-generator
* ! 使用:
$make_img = new MakeImg();
$make_img->drawCenteredText(80, "淘宝面单", 20, $make_img->getBlackColor());
// 绘制第一个条形码
// $generator = new BarcodeGeneratorPNG();
$code = 'SF0000';
$make_img->drawBarcode(20, $code);
$make_img->drawCenteredText(25, $code, 14, $make_img->getBlackColor());
$make_img->drawCenteredText(60, '该面单请联系快递员打印', 32, $make_img->getBlackColor());
$make_img->drawAlignedRow(40, "需求鉴别单号:", "1212121", 16, $make_img->getBlackColor());
$make_img->drawAlignedRow(46, "需求鉴别单号:", "1212121", 16, $make_img->getBlackColor());
$make_img->drawWrappedText(40, '1212121', 16, $make_img->getBlackColor(), 40);
$res = $make_img->getImg();
file_put_contents(BASE_PATH . '/1.html', '<img style="display: inline-block;" src="' . $res . '"/>');
* @author lxx
*/
class MakeImg
{
private $config = [
'image_width' => (76 - 0) * 8,// 1mm≈8px
'image_height' => (130 - 0) * 8,// 1mm≈8px
'padding' => 130,
'font' => BASE_PATH . '/public/simsun.ttf'
];
private $image = null;
private $y = 0; // 距离顶部的总距离, 每次设置
public function __construct($_config = [])
{
$this->config = array_merge($this->config, $_config);
$this->image = imagecreatetruecolor($this->config['image_width'], $this->config['image_height']);
// 背景
imagefill($this->image, 0, 0, $this->getWhiteColor());
}
/**
* 每次设置y的值更新总的y顶部距离
*
* @param int $_y
* @return int 总的y顶部距离
* @author lxx
*/
public function addY($_y)
{
$this->y = $this->y + $_y;
return $this->y;
}
/**
* 黑色
*
* @return int
* @author lxx
*/
public function getBlackColor()
{
return imagecolorallocate($this->image, 0, 0, 0);
}
/**
* 白色
*
* @return int
* @author lxx
*/
public function getWhiteColor()
{
return imagecolorallocate($this->image, 255, 255, 255);
}
/**
* 获取生成的图片
*
* @param resource $im imagecreatetruecolor 数据
* @param bool $get_base64 是否获取base64字符串
* @return string|resource base64字符串或者图片资源
* @author lxx
*/
public function getImg($get_base64 = true)
{
ob_start();
imagepng($this->image);
$imageData = ob_get_contents(); // 获取图像数据
ob_end_clean(); // 关闭并清空输出缓冲区
// 将图像数据转换为 BASE64
$base64 = base64_encode($imageData);
// 清理资源
imagedestroy($this->image);
if ($get_base64) {
return 'data:image/png;base64,' . $base64;
} else {
return $imageData;
}
}
// 添加文本换行函数
public function wrapText($text, $font_size, $max_width)
{
$lines = [];
$current_line = '';
foreach (preg_split('//u', $text, -1, PREG_SPLIT_NO_EMPTY) as $char) {
$testline = $current_line . $char;
$bbox = imagettfbbox($font_size, 0, $this->config['font'], $testline);
$text_width = $bbox[2] - $bbox[0];
if ($text_width > $max_width) {
$lines[] = $current_line;
$current_line = $char;
} else {
$current_line .= $char;
}
}
if ($current_line !== '') {
$lines[] = $current_line;
}
return $lines;
}
// 修改绘制对齐行的函数,支持长文本换行
public function drawAlignedRow($padding_top, $label, $content, $size, $color, $padding_lr = 40)
{
$this->addY($padding_top);
$y = $this->y;
$image_width = $this->config['image_width'];
// ! 计算内容最大宽度(图片宽度的60%)
$content_max_width = ($image_width - (3 * $padding_lr)) * 0.6;
// 绘制左对齐的标签
imagettftext($this->image, $size, 0, $padding_lr, $y, $color, $this->config['font'], $label);
// 如果内容需要换行
$bbox = imagettfbbox($size, 0, $this->config['font'], $content);
$text_width = $bbox[2] - $bbox[0];
if ($text_width > $content_max_width) {
// 换行处理
$lines = $this->wrapText($content, $size, $content_max_width);
foreach ($lines as $index => $line) {
// var_dump($size);
$bbox = imagettfbbox($size, 0, $this->config['font'], $line);
$line_width = $bbox[2] - $bbox[0];
$x = $image_width - $line_width - $padding_lr;
imagettftext($this->image, $size, 0, $x, $y + ($index * ($size + 5)), $color, $this->config['font'], $line);
}
// 返回最后一行的Y坐标
return $y + (count($lines) - 1) * ($size + 5);
} else {
// 单行处理,右边靠
$x = $image_width - $text_width - $padding_lr;
imagettftext($this->image, $size, 0, $x, $y, $color, $this->config['font'], $content);
return $y;
}
}
// 修改普通文本绘制函数,支持换行
public function drawWrappedText($padding_top, $text, $size, $color, $padding_lr)
{
$y = $this->addY($padding_top);
$image_width = $this->config['image_width'];
$max_width = $image_width - (2 * $padding_lr);
$lines = $this->wrapText($text, $size, $max_width);
foreach ($lines as $index => $line) {
imagettftext($this->image, $size, 0, $padding_lr, $y + ($index * ($size + 10)), $color, $this->config['font'], $line);
}
$this->addY($y + (count($lines) - 1) * ($size + 5));
}
// 绘制居中文本
public function drawCenteredText($padding_top, $text, $size, $color)
{
$y = $this->addY($padding_top);
$bbox = imagettfbbox($size, 0, $this->config['font'], $text);
$text_width = $bbox[2] - $bbox[0];
$x = (int)(($this->config['image_width'] - $text_width) / 2);
imagettftext($this->image, $size, 0, $x, $y, $color, $this->config['font'], $text);
}
// 绘制条形码
public function drawBarcode($padding_top, $code, $height = 120, $code_one_width = 3)
{
$y = $this->addY($padding_top);
// 生成条形码
$generator = new BarcodeGeneratorPNG();
$barcode = $generator->getBarcode($code, $generator::TYPE_CODE_128, $code_one_width, $height);
$barcodeWidth = imagesx(imagecreatefromstring($barcode));
$barcodeHeight = imagesy(imagecreatefromstring($barcode));
$barcode_img = imagecreatefromstring($barcode);
// 合并图层
if ($this->config['image_width'] - $barcodeWidth < 0) {
throw new \Exception('条形码内容太长了!');
}
$x = ($this->config['image_width'] - $barcodeWidth) / 2;
imagecopy($this->image, $barcode_img, intval($x), $y, 0, 0, $barcodeWidth, $barcodeHeight);
imagedestroy($barcode_img);
$this->addY($height);
}
}