图片转 PDF
多张 JPG / PNG / WebP 按顺序合并为 PDF
多图合一 PDF
多张 JPG / PNG / WebP 按顺序合并为 PDF
了解工具定位 · 使用场景 · 对比优势
将多张图片合并为一个 PDF 文件,支持 JPG、PNG、WebP 等常见格式。适合整理扫描件、课件截图、聊天记录等零散图片,生成一份可打印、可分享的文档。图片上传后由服务端处理,不保留原始文件,处理完成后自动删除。
企业行政人员需将多页合同、协议逐页扫描为图片,再合并为一份 PDF 发给法务或客户。逐张发送图片易丢失、顺序错乱,且对方接收后无法直接批注。使用本工具一次性上传所有扫描件,自动按文件名或拖拽顺序合并为单文件 PDF,文件体积比原图缩小 60%-80%,便于邮件附件传输和长期存档。
学生用手机拍摄黑板板书或教材多页,课后需将零散照片整理为可打印的笔记。单独保存图片占用相册空间,且打印时需逐张调整尺寸。本工具将多张照片按拍摄顺序合并为 PDF,自动将横向图片旋转为统一方向,生成 A4 标准尺寸文档,直接发送至打印机或分享给同学。
财务人员每月需收集数十张电子发票截图、报销单照片,分别保存为图片时,文件夹混乱且无法全文搜索。利用本工具将所有发票图片合并为单文件 PDF,配合 OCR 软件可对 PDF 内文字进行检索,同时保留原始图片分辨率,满足税务审计对发票清晰度的要求。
电商运营需将多款产品的白底图、详情页截图组合为一份发给美工或客户审阅。逐一发送图片无法保证对方按顺序查看,且微信传输会压缩画质。本工具支持原图上传,合并后保持每张图片的原始分辨率与色彩,生成连贯的图册 PDF,客户可直接在 PDF 内标注修改意见。
申请签证、入职或贷款时,需将身份证、户口本、学历证书等多页证件照片合并为一个 PDF 文件上传至政务平台。每张图片需单独命名且大小不超过 5MB。本工具自动将多张图片压缩至平台要求尺寸内,合并后文件大小可控,避免因单张上传遗漏或格式不符被退回。
| 维度 | 本工具 | 竞品 A | 传统方法 |
|---|---|---|---|
| 数据隐私 | 纯浏览器处理,文件不上传服务器 | 上传至云端服务器处理 | 文件经手多人,存在泄露风险 |
| 处理速度 | 即时完成(毫秒级) | 依赖上传下载,5-15 秒 | 手动操作,数分钟至数小时 |
| 离线可用 | 完全离线,无需网络 | 必须联网 | 无需网络 |
| 大小限制 | 取决于浏览器内存,通常 100MB+ | 通常 10-50MB 免费限制 | 无硬性限制 |
| 收费模式 | 免费无限制 | 免费版有水印/页数限制 | 需购买软件或打印店付费 |
| 批量处理 | 支持多图一键合并 | 部分支持,免费版有限 | 逐张添加,效率低 |
| 平台兼容 | 所有现代浏览器(PC/手机) | 需安装客户端或特定浏览器 | 依赖电脑及专业软件 |
上手步骤 · 输入输出 · 避坑提示
| 输入 | 输出 | 说明 |
|---|---|---|
| 上传 3 张 JPG 图片(尺寸 1920×1080,总大小 5MB) | 生成一个包含 3 页的 PDF 文件,每页对应一张原图,保持原始分辨率 | 典型场景:多图合并为一份 PDF 文档 |
| 上传 1 张 PNG 图片(透明背景,尺寸 800×600) | 生成一个单页 PDF 文件,透明背景自动转为白色 | 边界 case:单张图片也支持,透明背景会被填充 |
| 上传 10 张图片(包含 JPG、PNG、WEBP 格式,总大小 50MB) | 生成一个包含 10 页的 PDF 文件,混合格式自动统一处理 | 典型场景:不同格式图片混合上传 |
| 上传 1 张图片(文件名含中文和空格,如「我的照片 2024.jpg」) | 生成 PDF 文件,文件名保持原样,无乱码 | 易错 case:中文文件名不会导致编码错误 |
| 上传 0 张图片(直接点击「开始转换」) | 提示「请至少选择一张图片」 | 边界 case:空输入会触发校验提示 |
| 上传 1 张超大图片(分辨率 10000×10000,单文件 100MB) | 生成 PDF 文件,但处理时间较长(约 10-30 秒),PDF 体积可能超过 50MB | 边界 case:超大图片会显著影响处理速度 |
| 上传 5 张图片(其中 1 张为损坏的 .jpg 文件) | 生成一个包含 4 页的 PDF,跳过损坏图片并提示「第 3 张图片无法读取」 | 易错 case:损坏文件会被自动跳过并给出提示 |
直接拖入一个 .pdf 或 .docx 文件只上传 .jpg / .png / .webp / .bmp / .gif 等图片格式工具后端用 Go 处理图片,非图片文件无法解码为像素数据,会直接返回格式错误或空结果
上传一张 120MB 的 4K 照片先用图片压缩工具将单张图片控制在 50MB 以内服务端内存有限,超大图片会触发 OOM 或请求超时(默认 30s),建议单张不超过 50MB
文件名为「风景#1.jpg」或「test?file.png」重命名为纯英文或数字,如「scenery1.jpg」「testfile.png」URL 中 # 被当作锚点,? 被当作查询参数,服务端解析文件名时会丢失或截断
透明 PNG 直接转 PDF,背景变成黑色或棋盘格先对透明 PNG 做「填充白色背景」处理,再上传PDF 不支持透明通道,Go 图片解码后透明像素会被渲染为黑色(默认背景色),非预期效果
手机拍摄的竖屏照片(EXIF 方向标记为 6)直接上传上传前用图片编辑软件旋转为正确方向,或确认工具是否支持 EXIF 方向读取当前工具未实现 EXIF 方向解析,图片按原始像素数据排列,横竖方向不会被自动修正
一次选择 200 张图片点击上传分批上传,每次不超过 100 张服务端并发处理上限为 100 个文件,超量会触发请求体过大(413)或部分文件被丢弃
上传 CMYK 模式的 TIFF 图片,期望 PDF 中颜色不变先将图片转为 sRGB 模式再上传Go 标准库 image 包不支持 CMYK 解码,会转为 RGB,导致颜色偏移或饱和度变化
上传一个 10 帧的 WebP 动图,期望生成多页 PDF先提取每一帧为独立静态图片,再批量上传工具按文件数量生成 PDF 页数,动图只解码第一帧,后续帧不会被处理
公式推导 · 流程图解 · 依据出处
PDF = merge(IMG₁, IMG₂, ..., IMGₙ, options)
IMG₁..IMGₙ — 输入的图片文件列表,n ≥ 1options — 页面尺寸、边距、排序等参数PDF — 输出的多页 PDF 文件用户上传 3 张图片:IMG₁=封面.png (1920×1080),IMG₂=正文1.jpg (2480×3508),IMG₃=正文2.jpg (2480×3508)。options 设为 A4 纵向、无边距、按文件名排序。工具将每张图片逐页嵌入 PDF,输出一个 3 页的 PDF 文件,第 1 页为封面,第 2-3 页为正文。
适用于任意常见图片格式(JPEG/PNG/WebP/BMP/GIF)合并为 PDF。不支持加密图片、损坏图片或超大分辨率(单边>10000px)图片,此类图片可能导致转换失败或页面异常。
3 种主流语言 · 复制即用
from PIL import Image
import sys
# 将多张图片合并为一个 PDF
images = []
for path in ["page1.jpg", "page2.png", "page3.webp"]:
try:
img = Image.open(path).convert("RGB") # PDF 需要 RGB 模式
images.append(img)
except FileNotFoundError:
print(f"文件未找到: {path}", file=sys.stderr)
sys.exit(1)
if images:
# 第一张图作为 PDF 基础,其余追加
images[0].save("output.pdf", save_all=True, append_images=images[1:])
print("已生成 output.pdf")
else:
print("没有有效的图片", file=sys.stderr)package main
import (
"image"
"image/jpeg"
"image/png"
"os"
"strings"
"github.com/signintech/gopdf"
)
func main() {
pdf := &gopdf.GoPdf{}
pdf.Start(gopdf.Config{PageSize: *gopdf.PageSizeA4})
files := []string{"img1.jpg", "img2.png"}
for _, f := range files {
img, err := loadImage(f)
if err != nil {
panic(err)
}
pdf.AddPage()
pdf.Image(f, 0, 0, &gopdf.Rect{W: float64(img.Bounds().Dx()), H: float64(img.Bounds().Dy())})
}
pdf.WritePdf("output.pdf")
}
func loadImage(path string) (image.Image, error) {
f, err := os.Open(path)
if err != nil {
return nil, err
}
defer f.Close()
if strings.HasSuffix(path, ".png") {
return png.Decode(f)
}
return jpeg.Decode(f)
}const PDFDocument = require('pdfkit');
const fs = require('fs');
const sharp = require('sharp');
async function imagesToPdf(imagePaths, outputPath) {
const doc = new PDFDocument({ autoFirstPage: false });
const stream = fs.createWriteStream(outputPath);
doc.pipe(stream);
for (const path of imagePaths) {
// 用 sharp 获取图片尺寸,避免 PDF 页面大小不匹配
const metadata = await sharp(path).metadata();
doc.addPage({ size: [metadata.width, metadata.height] });
doc.image(path, 0, 0, { width: metadata.width, height: metadata.height });
}
doc.end();
return new Promise((resolve, reject) => {
stream.on('finish', resolve);
stream.on('error', reject);
});
}
// 使用示例
imagesToPdf(['photo1.jpg', 'photo2.png'], 'combined.pdf')
.then(() => console.log('PDF 已生成'))
.catch(console.error);9 个高频疑问