PHP使用imagecreate拼接上传瓦片生成瓦片地图的报错及坐标问题
问题根因
- 数组遍历逻辑错误:PHP默认多文件上传结构中,
$_FILES['myFiles']['tmp_name']是一维数组,键为文件上传顺序的数字索引,值为对应文件的临时存储路径字符串。原代码对字符串做第二层foreach遍历,自然抛出类型错误。 - 画布尺寸计算逻辑颠倒:每行最多放置30个32px瓦片时,画布固定宽度为
30*32=960px,高度应为ceil(总瓦片数 / 30) * 32,原代码写反了分子分母,计算出的高度完全不符合像素要求。 - 放置坐标计算错误:原代码嵌套循环的行、列映射关系完全错误,正确的坐标需要根据每个瓦片的顺序索引计算,而非嵌套循环的键值。
修正后可直接运行的代码
<?php // 基础配置 $tileSize = 32; $maxPerRow = 30; // 统计上传瓦片总数 $totalTiles = count($_FILES['myFiles']['tmp_name']); // 计算需要的总行数 $totalRows = ceil($totalTiles / $maxPerRow); // 创建对应尺寸的画布 $canvas = imagecreate($maxPerRow * $tileSize, $totalRows * $tileSize); // 遍历所有上传瓦片 foreach ($_FILES['myFiles']['tmp_name'] as $index => $tmpFilePath) { // 读取瓦片图片,非png格式可自行替换对应读取函数 $tile = @imagecreatefrompng($tmpFilePath); if (!$tile) continue; // 计算当前瓦片所在行列与目标坐标 $col = $index % $maxPerRow; $row = floor($index / $maxPerRow); $destX = $col * $tileSize; $destY = $row * $tileSize; // 将瓦片拷贝到画布对应位置 imagecopy($canvas, $tile, $destX, $destY, 0, 0, $tileSize, $tileSize); // 释放单瓦片资源避免内存占用 imagedestroy($tile); } // 输出拼接完成的png图片 header('Content-Type: image/png'); imagepng($canvas); // 释放画布资源 imagedestroy($canvas);
逻辑说明
- 坐标计算规则:第N个瓦片(索引从0开始)的列号为
N对30取余,行号为N除以30向下取整,乘以单瓦片尺寸32px即为最终放置坐标。例如上传120张图片时,总共有4行,索引0-29放在第一行(Y坐标0)、30-59放在第二行(Y坐标32)、60-89放在第三行(Y坐标64)、90-119放在第四行(Y坐标96),排列完全符合要求。 - 代码增加了无效文件跳过逻辑与资源释放逻辑,避免无效文件导致脚本中断、大数量上传时内存溢出问题。
- 如果存在jpg/gif等其他格式瓦片,可根据文件后缀替换
imagecreatefrompng为imagecreatefromjpeg/imagecreatefromgif即可。
内容的提问来源于stack exchange,提问作者Graigner Jaamesy
相关产品推荐
相关产品推荐

