前端怎么将多张图片插入到pdf?
我现在有一个数组,里面放的是图片的base64编码,想通过jspdf这个插件把这些图片生成一个pdf,但是现在遇到的问题就是,两张图片就要占一页,如果有三张图片的话,就需要调用addPage方法,增加一页pdf,把第三张图片插入,但是如果有很多图片的话,就不知道何时去调用addPage方法。
这个是我目前搜到的教程,希望有人给出答案。
<template>
<div>
<video ref="video" autoplay width="400" height="300">video>
<button @click="btnTakePhotoClicked()">Take photobutton>
<canvas ref="canvas" width="400" height="300">canvas>
<a href="" download="canvas.jpeg" id="save_herf">
<img src="" id="save_img" alt="">
a>
<button @click="addpage">增页button>
<button @click="inserImg">图片插入button>
<button @click="getSize">获取图片高度button>
<button @click="savePDF">保存button>
div>
template>
<script>
import {jsPDF} from 'jspdf';
const recordPdf = new jsPDF('p', 'px')
export default {
data() {
return {
imgList: [],
currentW: 1,
currentH: 1,
currentImg: ""
}
},
mounted(){
this._initVueApp();
this.btnTakePhotoClicked();
},
methods:{
async _initVueApp(){
this.$refs.video.srcObject= await navigator.mediaDevices.getUserMedia({video:true,audio:false});
this._context2d=this.$refs.canvas.getContext("2d");
this.canvas=this.$refs.canvas;
},
btnTakePhotoClicked(){
this._context2d.drawImage(this.$refs.video,0,0,400,300)
var img = document.createElement("img"); // 创建img元素
img.src =this.canvas.toDataURL("image/png"); // 截取视频第一帧
var svaeHref = document.getElementById("save_herf");
console.log(img.src)
this.imgList.push(img.src)
this.currentImg = img.src
var sd=document.getElementById("save_img");
svaeHref.href = img.src;
sd.src=img.src
},
addpage() {
recordPdf.addPage()
},
async inserImg() {
for(let url of this.imgList) {
let { width, height } = await this.getImgWidthHeight(url)
recordPdf.addImage(url, 'png', 1, this.currentH, width, height)
this.currentH = height
this.currentW = width
}
// recordPdf.addImage(this.currentImg, 'png', 1, 1)
// this.saveToPDF()
},
savePDF() {
recordPdf.save("PDF存档.pdf")
},
async getSize() {
const { width, height } = await this.getImgWidthHeight(this.currentImg)
console.log(width);
console.log(height);
},
async saveToPDF() {
// 生成pdf
// 第一个参数:l横向,p纵向
// 第二个参数:计量单位: cm mm px等
// 第三个参数:格式: 默认a4
// this.saveLoading = false
// const { maxWidth, maxHeight } = await this.getAllHeight()
const recordPdf = new jsPDF('p', 'px')
// 从top的位置开始加图片
for (let i = 0; i < this.imgList.length; i++) {
const { url } = this.imgList[i]
const { width, height } = await this.getImgWidthHeight(url)
recordPdf.addImage(url, 'png', 1, 1, width, height)
recordPdf.addPage()
}
// 删除最后一页留白
// const targetPage = recordPdf.internal.getNumberOfPages()
// recordPdf.deletePage(targetPage)
recordPdf.save('PDF存档.pdf')
},
// 获取图片数组里面最大的宽度和高度
async getMaxWidthHeight() {
const widthList = []
const heightList = []
let maxHeight = 0
let maxWidth = 0
for (let i = 0; i < this.imgList.length; i++) {
const { url } = this.imgList[i]
const { width, height } = await this.getImgWidthHeight(url)
widthList.push(width)
heightList.push(height)
}
// 把数组变成升序然后倒过来取第一个就是拿最大宽度
maxWidth = widthList.sort().reverse()[0]
maxHeight = heightList.sort().reverse()[0]
return {
maxWidth,
maxHeight,
}
},
//获取图片宽高
getImgWidthHeight(src) {
return new Promise((resolve, reject) => {
const img = new Image()
img.src = src
// 图片是否有缓存 如果有缓存可以直接拿 如果没有缓存 需要从onload拿
if (img.complete) {
const { width, height } = img
resolve({
width,
height,
})
} else {
img.onload = function () {
const { width, height } = img
resolve({
width,
height,
})
}
}
})
},
}
}
script>
https://www.jianshu.com/p/43d69b8ff8e8
如果可以,也可以上传到后台去处理。
基于new Bing的回答:
你可以在遍历图片数组时,检查当前页面已经插入的图片数量,如果达到了每页图片数量的上限,就调用addPage()方法增加一页pdf,然后把新的图片插入到新的一页上。你可以定义一个变量来记录每页应该插入的图片数量,比如说:
const IMAGES_PER_PAGE = 2; // 每页插入两张图片
const doc = new jsPDF();
let imageCount = 0; // 当前页面已经插入的图片数量
imageArray.forEach(image => {
// 插入图片到pdf
doc.addImage(image, 'JPEG', x, y, width, height);
// 更新图片数量
imageCount++;
// 如果当前页面已经插入了足够数量的图片,就增加一页pdf
if (imageCount === IMAGES_PER_PAGE) {
doc.addPage();
imageCount = 0; // 重置图片数量
}
});
// 保存pdf文件
doc.save('my_images.pdf');
这段代码会在每插入两张图片时自动增加一页pdf。你可以根据需要修改IMAGES_PER_PAGE变量来调整每页图片数量。
先计算出每页能容纳的图片数量,然后根据这个数量动态地添加新页
<template>
<div>
<button @click="addImage">添加图片</button>
<button @click="savePDF">保存为 PDF</button>
</div>
</template>
<script>
import { jsPDF } from 'jspdf';
export default {
data() {
return {
images: [],
maxImagesPerPage: 2,
};
},
methods: {
async addImage() {
const image = await this.getImage(); // 获取图片
this.images.push(image); // 添加到图片数组
},
async getImage() {
const canvas = document.createElement('canvas');
const context = canvas.getContext('2d');
const img = new Image();
img.src = 'data:image/png;base64,<image_base64>';
await new Promise((resolve) => img.onload = resolve);
canvas.width = img.width;
canvas.height = img.height;
context.drawImage(img, 0, 0);
return canvas.toDataURL('image/jpeg', 0.8);
},
async savePDF() {
const doc = new jsPDF();
let pageIndex = 1;
let imageIndex = 0;
let x = 10;
let y = 10;
const maxPerPage = this.maxImagesPerPage;
while (imageIndex < this.images.length) {
const images = this.images.slice(imageIndex, imageIndex + maxPerPage);
for (let i = 0; i < images.length; i++) {
const image = images[i];
const img = await this.loadImage(image);
const width = doc.internal.pageSize.width / maxPerPage - 20;
const height = (img.height * width) / img.width;
doc.addImage(image, 'JPEG', x, y, width, height);
x += width + 10;
}
// 增加一页
doc.addPage();
pageIndex++;
x = 10;
y = 10;
imageIndex += maxPerPage;
}
doc.deletePage(pageIndex); // 删除最后一页,因为它是空的
doc.save('images.pdf');
},
loadImage(url) {
return new Promise((resolve, reject) => {
const img = new Image();
img.onload = () => resolve(img);
img.onerror = reject;
img.src = url;
});
},
},
};
</script>
可以通过设置每一页的图片数量来解决这个问题,比如每一页最多放两张图片,当添加第三张图片时,就调用addPage方法增加一页。具体实现可以参考以下代码:
async inserImg() {
let count = 0
for(let url of this.imgList) {
let { width, height } = await this.getImgWidthHeight(url)
recordPdf.addImage(url, 'png', 1, this.currentH, width, height)
this.currentH += height
count++
if (count % 2 === 0) {
recordPdf.addPage()
this.currentH = 1
}
}
}
在这段代码中,我们设置了一个count变量来记录当前页已经插入了多少张图片,当count为2的倍数时就调用addPage方法增加一页,并把currentH设置为1,从新一页的顶部开始插入图片。这样就可以保证每一页最多只有两张图片了。
首先,我们需要将所有的图片插入到 PDF 中,同时保证每两张图片占用一页,也就是说,每当我们插入一张图片时,需要判断当前页是否还有剩余空间,如果没有,就调用 addPage() 方法增加一页,然后将图片插入到新页中。因此,我们需要一个计算当前页剩余空间的函数,代码如下:
function getAvailableSpaceOnPage(doc) {
const totalPages = doc.getNumberOfPages();
const currentPage = doc.internal.getCurrentPageInfo().pageNumber;
const pageHeight = doc.internal.pageSize.height;
const y = currentPage === 1 ? 0 : doc.internal.pageSize.height;
const availableHeight = pageHeight - (y + doc.internal.getVerticalCoordinateString(doc.internal.pageSize.height));
return availableHeight;
}
接下来,我们需要一个循环来遍历所有图片,将它们插入到 PDF 中。对于每一张图片,我们需要计算它的宽度和高度,并根据当前页剩余空间的大小,判断是否需要调用 addPage() 方法。代码如下:
async function insertImages(doc, imageUrls) {
for (let i = 0; i < imageUrls.length; i++) {
const imageUrl = imageUrls[i];
const { width, height } = await getImageSize(imageUrl);
const availableHeight = getAvailableSpaceOnPage(doc);
if (height > availableHeight) {
doc.addPage();
}
doc.addImage(imageUrl, 'JPEG', 0, 0, width, height);
}
}
其中,getImageSize() 函数用于获取图片的宽度和高度,具体实现可以参考这个问题的另一个回答。
最后,我们可以在 Vue 组件中调用以上两个函数,将所有图片插入到 PDF 中,并保存 PDF 文件,代码如下:
import { jsPDF } from 'jspdf';
export default {
data() {
return {
imageUrls: [], // 图片的 URL 数组
};
},
methods: {
async generatePDF() {
const doc = new jsPDF('p', 'pt', 'a4');
await insertImages(doc, this.imageUrls);
doc.save('images.pdf');
},
},
};
这样,我们就可以将多张图片插入到 PDF 中了。希望这个解答能够帮助到你!
该回答参考ChatGPT:
可以通过循环遍历数组中的每张图片,然后在每一次循环中先判断当前页面已经插入了多少张图片,如果数量已经到达一页上限,则调用addPage方法添加新的一页,接着再将当前图片插入到pdf中即可。具体代码示例如下:
var doc = new jsPDF();
var imgDataArray = ["base64_1", "base64_2", "base64_3", ...];
var imgWidth = 210; // 图片宽度
var pageHeight = 295; // 页面高度
var imgHeight = imgWidth / doc.internal.pageSize.width * doc.internal.pageSize.height; // 图片高度
var currentPage = 1;
var maxImgPerPage = Math.floor(pageHeight / imgHeight);
for (var i = 0; i < imgDataArray.length; i++) {
if (i % maxImgPerPage === 0) {
doc.addPage();
currentPage++;
}
doc.addImage(imgDataArray[i], 'JPEG', 0, (i % maxImgPerPage) * imgHeight, imgWidth, imgHeight);
}
doc.save('images.pdf');
其中,imgWidth为图片宽度,pageHeight为页面高度,imgHeight根据图片宽度和页面高度计算得到,currentPage保存当前页数,maxImgPerPage保存每页最多能够插入的图片数量。在循环中,先判断当前页数已经插入的图片数量是否达到了一页上限,如果是则调用addPage方法添加新的一页,同时更新当前页数,然后将当前图片插入到pdf中。最后调用save方法将生成的pdf保存到本地。
```javascript
<!DOCTYPE html>
<html>
<head>
<title>Insert multiple images to PDF using jsPDF</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.3.1/jspdf.umd.min.js"></script>
</head>
<body>
<div id="pdfContainer"></div>
<script>
// 用于保存图片的URL数组
const imageURLs = [
'https://example.com/image1.png',
'https://example.com/image2.png',
'https://example.com/image3.png',
];
// 创建一个新的PDF文档
const doc = new jsPDF();
// 将所有图片插入到PDF中
Promise.all(imageURLs.map(url => fetch(url)))
.then(responses => Promise.all(responses.map(res => res.blob())))
.then(blobs => {
blobs.forEach((blob, i) => {
const reader = new FileReader();
reader.onload = () => {
doc.addImage(reader.result, 'PNG', 10, 10 + i * 50, 50, 50);
if (i === blobs.length - 1) {
doc.save('images.pdf'); // 将PDF保存到本地
}
};
reader.readAsDataURL(blob);
});
});
</script>
</body>
</html>
```
以下答案由GPT-3.5大模型与博主波罗歌共同编写:
首先,在添加图片时,我们需要知道当前页面的高度,以便选择新建页面或将图片插入到当前页面。因此,我们可以创建一个变量 currentPageHeight
来记录当前页面的高度,并在插入图片后更新它。
同时,我们需要知道当前图片的高度以便将其插入到合适的位置。因此,我们可以在插入图片前使用 getImageHeight()
方法获取当前图片的高度。
基于此,以下是实现该功能的代码:
<template>
<div>
<!-- ... -->
<button @click="insertImages">插入图片到PDF</button>
<button @click="savePDF">保存PDF</button>
</div>
</template>
<script>
import jsPDF from 'jspdf'
export default {
data() {
return {
imgList: [], // 图片 base64 编码列表
currentPageHeight: 0, // 当前页的高度
}
},
methods: {
// 获取图片高度
async getImageHeight(src) {
const img = new Image()
img.src = src
await img.decode() // 等待图片加载完成
return (img.height * 72) / img.yDPI * 1.33333 // 像素转单位(以 PDF 为例,1像素=0.75pt)
},
// 将图片列表插入到 PDF 中
async insertImages() {
const pdf = new jsPDF('p', 'pt', 'a4')
for (let i = 0; i < this.imgList.length; i++) {
const imgUrl = this.imgList[i]
const imgHeight = await this.getImageHeight(imgUrl)
if (this.currentPageHeight + imgHeight > pdf.internal.pageSize.height) {
// 插入图片会超出当前页,需要新建一页
pdf.addPage()
this.currentPageHeight = 0
}
pdf.addImage(imgUrl, 'JPEG', 0, this.currentPageHeight, pdf.internal.pageSize.width, imgHeight)
this.currentPageHeight += imgHeight
}
// 下载PDF
pdf.save('test.pdf')
},
// 将 canvas 保存为图片
saveAsImage(canvas) {
canvas.toBlob((blob) => {
const imageUrl = URL.createObjectURL(blob)
this.imgList.push(imageUrl)
}, 'image/jpeg', 0.95)
},
// 拍照按钮点击事件
async btnTakePhotoClicked() {
// ...拍照并将截图保存到 canvas...
this.saveAsImage(this.canvas)
},
savePDF() {
this.insertImages()
},
},
}
</script>
说明:
在 getImageHeight()
方法中,我们创建了一个 Image 对象来获取图片信息。使用 await img.decode()
等待图片信息获取完成,因为在调用该方法前,图片可能没有加载完成,如果没有完成可能会导致获取的高度不准确。
在 insertImages()
方法中,我们在插入图片之前使用 this.currentPageHeight
变量检查当前页是否有足够的空间插入图片。如果没有,则新建一页。
使用 pdf.addImage()
方法将图片插入 PDF。将其 x
和 y
坐标设置为 0
和当前页面的高度,以便将其放在当前页的最底部。
在 saveAsImage()
方法中我们将 canvas 转换为图片,并将其 base64 编码保存到 imgList
中。
savePDF()
方法将 imgList
中的图片插入到 PDF 中并进行下载。
希望这个解答能够帮助到您!
如果我的回答解决了您的问题,请采纳!
引用chatGPT作答,你可以使用addImage方法将base64编码的图片插入到pdf中。对于每个图片,你可以在插入前获取其高度和宽度,然后将其添加到pdf中,如果添加此图像会导致超出页面边界,则调用addPage方法添加新页面,并在新页面上添加图像。这里是一个基本示例:
import { jsPDF } from 'jspdf'
// 创建新的PDF文档
const doc = new jsPDF()
// 图像列表
const images = ['image1.png', 'image2.png', 'image3.png']
// 逐个添加图像
for (const img of images) {
// 加载图像
const image = await loadImage(img)
// 获取图像大小
const width = image.width
const height = image.height
// 如果当前页无法容纳该图像,则添加新页
if (doc.getHeight() < height) {
doc.addPage()
}
// 将图像添加到当前页
doc.addImage(image.src, 'PNG', 10, 10, width, height)
}
// 保存PDF
doc.save('images.pdf')
// 加载图像
function loadImage(url) {
return new Promise((resolve, reject) => {
const img = new Image()
img.onload = () => resolve(img)
img.onerror = reject
img.src = url
})
}
这个示例加载图像并逐个将它们添加到PDF中。如果当前页无法容纳图像,则添加新页。最后,整个PDF将被保存为文件。要让它适应你的用例,你需要从images数组中替换图像,并调整x和y坐标以控制图像的位置和间距。
不知道你这个问题是否已经解决, 如果还没有解决的话:如何将多个图片合成一个pdf
可以借鉴下
https://blog.csdn.net/qq_33537961/article/details/124959386