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');
相关推荐
暴雨课堂3 小时前
tp5 tp6被攻击篡改后恢复
linux·服务器·php
lhh_qrsly4 小时前
OTA 加密完整方案(嵌入式 IoT 常用)
开发语言·物联网·php
lhh_qrsly5 小时前
TI CCS(Code Composer Studio,德州仪器嵌入式 IDE)2015~2026 版本总览
ide·php·composer
比兔代理5 小时前
纯净IP是什么?从IP信誉、黑名单与ASN角度原理解析
开发语言·php
IM架构师1 天前
# 一次老旧PHPCMS网站入侵排查:从SQL注入到PHP后门,以及IP白名单止血
sql·tcp/ip·php
码途行者1 天前
处理超时未支付订单:两套轻量化方案,附 PHP 极简实现
开发语言·redis·php
vx_Biye_Design1 天前
PHP中医养生馆预约系统60841-计算机课程设计、毕业设计
vue.js·spring boot·后端·mysql·php·课程设计·express
.Bryce.1 天前
你了解 Blackboard(黑板系统)吗?听说过基于黑板系统实现的智能体吗?
java·网络·gpt·php·agent·codex·黑板系统
yu_zhidun2 天前
企业电脑监控软件怎么选:别只看功能清单,先看这 6 个底层能力
开发语言·电脑·php·域智盾系统
李纲明2 天前
WordPress 白屏排查手册:关插件、换主题、开调试、查 PHP(附停手信号)
开发语言·php·wordpress·故障排查·白屏·插件冲突