You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

PHP API实现指定位置合并图片及添加文字的问题求助

解决图片合并布局混乱及文字位置错误的问题

我看了你的代码,问题主要出在图片位置计算错误缩放参数不正确以及文字位置和颜色设置不当上。下面我会一步步帮你修正这些问题,实现你想要的布局效果:

首先,梳理你的需求对应代码需要调整的点:

  • 底图覆盖黑色背景:把背景色从白色改成黑色
  • 第二张图置于右上角(近顶部):计算右上角的坐标,确保图片贴顶靠右
  • 第三张图置于左下角:坐标设为左下角位置
  • 文字标注在第三张图片下方:基于第三张图的位置计算文字的Y坐标,同时调整文字颜色保证可见

修正后的完整代码:

public function upload(Request $request) {
    $canvasWidth = 600;
    $canvasHeight = 600;
    $smallImageSize = 100; // 假设第二、三张图缩放后的尺寸是100x100,可根据需求调整

    // 验证请求参数
    $validation = $request->validate([
        'title' => 'string',
        'image' => 'required|file|image|mimes:jpeg,png,gif,webp|max:2048'
    ]);

    // 获取上传的第三张图
    $uploadedFile = $validation['image'];
    $thirdImagePath = $uploadedFile->getRealPath();
    $third = imagecreatefromstring(file_get_contents($thirdImagePath));
    if (!$third) {
        return response()->json(['error' => 'Failed to load uploaded image'], 400);
    }

    // 加载预设的底图和第二张图(这里你可以根据实际路径调整)
    $firstPath = storage_path('app/uploads/images/mm-image-1552822080.png');
    $secondPath = storage_path('app/uploads/images/mm-image-1552936505.png');
    $first = imagecreatefrompng($firstPath);
    $second = imagecreatefrompng($secondPath);
    if (!$first || !$second) {
        return response()->json(['error' => 'Failed to load preset images'], 400);
    }

    // 创建画布并设置黑色背景
    $outputImage = imagecreatetruecolor($canvasWidth, $canvasHeight);
    $black = imagecolorallocate($outputImage, 0, 0, 0);
    imagefill($outputImage, 0, 0, $black);

    // 1. 粘贴底图,覆盖整个画布
    imagecopyresized(
        $outputImage, $first,
        0, 0, // 目标坐标:左上角
        0, 0, // 原图起始坐标
        $canvasWidth, $canvasHeight, // 目标尺寸
        imagesx($first), imagesy($first) // 原图实际尺寸,避免变形
    );

    // 2. 粘贴第二张图到右上角(近顶部)
    $secondDstX = $canvasWidth - $smallImageSize; // 靠右:画布宽度 - 图片宽度
    $secondDstY = 10; // 近顶部,留10px间距
    imagecopyresized(
        $outputImage, $second,
        $secondDstX, $secondDstY,
        0, 0,
        $smallImageSize, $smallImageSize,
        imagesx($second), imagesy($second)
    );

    // 3. 粘贴第三张图到左下角
    $thirdDstX = 10; // 靠左,留10px间距
    $thirdDstY = $canvasHeight - $smallImageSize - 10; // 靠下:画布高度 - 图片高度 - 间距
    imagecopyresized(
        $outputImage, $third,
        $thirdDstX, $thirdDstY,
        0, 0,
        $smallImageSize, $smallImageSize,
        imagesx($third), imagesy($third)
    );

    // 4. 添加文字到第三张图下方
    $text = $request->title ?? 'School Name Here';
    $font = storage_path('app/public/tahoma.ttf');
    $textColor = imagecolorallocate($outputImage, 255, 255, 255); // 白色文字,在黑色背景上可见
    $textSize = 16;
    // 计算文字位置:第三张图的X坐标,Y坐标为第三张图Y + 图片高度 + 10px间距
    $textX = $thirdDstX;
    $textY = $thirdDstY + $smallImageSize + 15;
    imagettftext(
        $outputImage, $textSize, 0,
        $textX, $textY,
        $textColor, $font, $text
    );

    // 保存生成的图片
    $filename = storage_path('app/uploads/images/'.round(microtime(true)).'.png');
    imagepng($outputImage, $filename);
    
    // 清理资源
    imagedestroy($outputImage);
    imagedestroy($first);
    imagedestroy($second);
    imagedestroy($third);

    // 返回成功响应
    return response()->json([
        'message' => 'Image merged successfully',
        'path' => str_replace(storage_path('app'), '', $filename)
    ]);
}

关键修正点说明:

  1. 图片位置计算
    • 右上角图片:$canvasWidth - $smallImageSize 确保图片右边缘对齐画布,$secondDstY = 10 保留顶部间距
    • 左下角图片:$thirdDstY = $canvasHeight - $smallImageSize - 10 确保图片下边缘靠近画布底部,同时留间距
  2. 缩放参数修复:用imagesx($image)imagesy($image)获取原图实际宽高,避免硬编码600导致图片变形
  3. 文字位置与颜色:文字Y坐标基于第三张图的位置向下偏移,同时把文字颜色设为白色(适配黑色背景),保证文字清晰可见
  4. 资源处理:添加了图片加载失败的判断,以及最后销毁所有图像资源,避免内存泄漏

内容的提问来源于stack exchange,提问作者Payne

火山引擎 最新活动