Laravle 证件照排版

php 复制代码
<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;

class PhotoController extends Controller
{
    // 默认配置(可被请求参数覆盖)
    protected $config = [
        'paper_width' => 1500,    // 5寸照片纸宽度 (5*300)
        'paper_height' => 1050,   // 5寸照片纸高度 (3.5*300)
        'photo_width' => 280,     // 1寸照片宽度
        'photo_height' => 390,    // 1寸照片高度
        'margin' => 50,           // 边距
        'spacing' => 20,          // 照片间距
        'photos_per_row' => 5,    // 每行照片数
        'rows' => 2               // 行数
    ];

    public function printOneInchPhotos(Request $request)
    {

        // $this->config['photo_width'] = 300;


        try {
            // 更新配置参数(从请求获取或使用默认值)
            $this->updateConfig($request);
            
            // 验证输入照片
            $photoPath = '1cun.jpg';
            
            // 创建画布
            $canvas = $this->createCanvas();
            
            // 加载并处理照片
            $photo = $this->loadAndResizePhoto($photoPath);
            
            // 在画布上排列照片
            $this->arrangePhotosCompact($canvas, $photo);
            
            // 输出结果
            return $this->outputImage($canvas);
            
        } catch (\Exception $e) {
            return $this->handleError($e);
        }
    }

    /**
     * 从请求更新配置
     */
    protected function updateConfig(Request $request)
    {
        $this->config = array_merge($this->config, [
            'paper_width' => $request->input('paper_width', $this->config['paper_width']),
            'paper_height' => $request->input('paper_height', $this->config['paper_height']),
            'photo_width' => $request->input('photo_width', $this->config['photo_width']),
            'photo_height' => $request->input('photo_height', $this->config['photo_height']),
            'margin' => $request->input('margin', $this->config['margin']),
            'spacing' => $request->input('spacing', $this->config['spacing']),
            'photos_per_row' => $request->input('photos_per_row', $this->config['photos_per_row']),
            'rows' => $request->input('rows', $this->config['rows'])
        ]);
    }

    /**
     * 紧凑排列照片
     */
    protected function arrangePhotosCompact($canvas, $photo)
    {
        // 计算总使用宽度和高度
        $totalWidth = $this->config['photos_per_row'] * $this->config['photo_width'] 
                     + ($this->config['photos_per_row'] - 1) * $this->config['spacing'];
        $totalHeight = $this->config['rows'] * $this->config['photo_height'] 
                      + ($this->config['rows'] - 1) * $this->config['spacing'];
        
        // 计算起始位置(居中)
        $startX = ($this->config['paper_width'] - $totalWidth) / 2;
        $startY = ($this->config['paper_height'] - $totalHeight) / 2;
        
        // 排列照片
        for ($row = 0; $row < $this->config['rows']; $row++) {
            for ($col = 0; $col < $this->config['photos_per_row']; $col++) {
                $x = $startX + $col * ($this->config['photo_width'] + $this->config['spacing']);
                $y = $startY + $row * ($this->config['photo_height'] + $this->config['spacing']);
                
                imagecopy(
                    $canvas, $photo,
                    $x, $y,
                    0, 0,
                    $this->config['photo_width'], $this->config['photo_height']
                );
            }
        }
        
        imagedestroy($photo);
    }

    /**
     * 创建画布
     */
    protected function createCanvas()
    {
        $canvas = imagecreatetruecolor($this->config['paper_width'], $this->config['paper_height']);
        $white = imagecolorallocate($canvas, 255, 255, 255);
        imagefill($canvas, 0, 0, $white);
        return $canvas;
    }

    /**
     * 加载并调整照片尺寸
     */
    protected function loadAndResizePhoto($path)
    {
        $photo = @imagecreatefromjpeg($path);
        if (!$photo) {
            throw new \RuntimeException("无法加载照片,可能不是有效的JPEG文件");
        }
        
        // 调整照片尺寸
        $resized = imagecreatetruecolor($this->config['photo_width'], $this->config['photo_height']);
        imagecopyresampled(
            $resized, $photo,
            0, 0, 0, 0,
            $this->config['photo_width'], $this->config['photo_height'],
            imagesx($photo), imagesy($photo)
        );
        imagedestroy($photo);
        
        return $resized;
    }

    /**
     * 验证照片路径
     */
    protected function validatePhotoPath($path)
    {
        if (empty($path)) {
            throw new \InvalidArgumentException("未提供照片路径");
        }
        
        $fullPath = storage_path('app/public/' . ltrim($path, '/'));
        
        if (!file_exists($fullPath)) {
            throw new \RuntimeException("照片文件不存在: " . $path);
        }
        
        return $fullPath;
    }

    /**
     * 输出图像
     */
    protected function outputImage($canvas)
    {
        ob_start();
        imagejpeg($canvas, null, 95);
        $imageData = ob_get_clean();
        imagedestroy($canvas);
        
        return response($imageData)
            ->header('Content-Type', 'image/jpeg')
            ->header('Content-Disposition', 'inline; filename="photo_print.jpg"');
    }

    /**
     * 错误处理
     */
    protected function handleError(\Exception $e)
    {
        $errorImage = imagecreatetruecolor(600, 100);
        $bgColor = imagecolorallocate($errorImage, 255, 255, 255);
        $textColor = imagecolorallocate($errorImage, 255, 0, 0);
        imagefill($errorImage, 0, 0, $bgColor);
        
        $lines = str_split($e->getMessage(), 80);
        foreach ($lines as $i => $line) {
            imagestring($errorImage, 5, 10, 20 + $i * 20, $line, $textColor);
        }
        
        ob_start();
        imagejpeg($errorImage);
        $imageData = ob_get_clean();
        imagedestroy($errorImage);
        
        return response($imageData)
            ->header('Content-Type', 'image/jpeg')
            ->header('Content-Disposition', 'inline; filename="error.jpg"');
    }
}

路由

php 复制代码
Route::get('cun','Api\PhotoController@printOneInchPhotos');
相关推荐
两个人的幸福1 天前
Windows 桌面应用自研 PHP 队列(下):完整代码与六大工程化优化
php
BingoGo3 天前
PHP 泛型之殇 泛型 RFC 提案被拒绝
后端·php
JaguarJack3 天前
PHP 泛型之殇 泛型 RFC 提案被拒绝
后端·php
用户3074596982074 天前
PHP 扩展——从入门到理解
php
鹏仔先生5 天前
拷贝漫画APP下载页PHP程序,后台带免费AI写作
php
云水一下5 天前
从零开始学 PHP 系列(一):PHP 的前世今生与开发环境搭建
开发语言·php
xingpanvip5 天前
星盘接口开发文档:本命盘接口指南
android·开发语言·css·php·lua
酉鬼女又兒5 天前
零基础入门计算机网络运输层:端到端通信核心作用、端口号分类规则、复用分用工作机制及UDP与TCP协议全方位对比详解
网络·网络协议·tcp/ip·计算机网络·考研·udp·php
dog2505 天前
不要再继续优化 TCP
网络协议·tcp/ip·php
Channing Lewis5 天前
PHP 解析 Excel 的那些坑:一次“行号错位”引发的数据丢失
开发语言·php·excel