md
This commit is contained in:
parent
e905c50b62
commit
646d92b554
235
src/utils/pdfjsUtils.js
Normal file
235
src/utils/pdfjsUtils.js
Normal file
@ -0,0 +1,235 @@
|
||||
import * as pdfjs from 'pdfjs-dist';
|
||||
import * as pdfjsWorker from 'pdfjs-dist/build/pdf.worker.entry';
|
||||
/**
|
||||
* pdf转图片获取pdf页数,用于渲染页面
|
||||
* @param {file} file - 文件
|
||||
*/
|
||||
export function getPdfnum(file) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const imgFiles = [];
|
||||
if (file.type === 'application/pdf') {
|
||||
let reader = new FileReader();
|
||||
reader.readAsDataURL(file); //将文件读取为 DataURL
|
||||
reader.onload = function () {
|
||||
//文件读取成功完成时触发
|
||||
const loadingTask = pdfjs.getDocument(reader.result);
|
||||
loadingTask.promise.then(async (pdf) => {
|
||||
const pageNum = pdf.numPages;
|
||||
if (pageNum > 10) {
|
||||
reject('此pdf页数过多,请线下合并');
|
||||
}
|
||||
//准备图片
|
||||
for (let i = 1; i <= pageNum; i++) {
|
||||
imgFiles.push(i);
|
||||
}
|
||||
resolve(imgFiles);
|
||||
});
|
||||
};
|
||||
reader.onerror = function () {
|
||||
// 如果文件读取失败,拒绝Promise
|
||||
reject(new Error('Failed to read the file'));
|
||||
};
|
||||
} else {
|
||||
resolve([]);
|
||||
}
|
||||
});
|
||||
}
|
||||
//pdf转图片
|
||||
export function PdfToImg(file) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const newimgList = [];
|
||||
const fileName = file.name.substring(0, file.name.lastIndexOf('.'));
|
||||
if (file.type === 'application/pdf') {
|
||||
let reader = new FileReader();
|
||||
reader.readAsDataURL(file); //将文件读取为 DataURL
|
||||
reader.onload = function () {
|
||||
//文件读取成功完成时触发
|
||||
const loadingTask = pdfjs.getDocument(reader.result);
|
||||
loadingTask.promise.then(async (pdf) => {
|
||||
let pageNum = pdf.numPages;
|
||||
// 处理
|
||||
for (let i = 1; i <= pageNum; i++) {
|
||||
let canvasItem = '';
|
||||
pdf.getPage(i).then(async (page) => {
|
||||
const canvas = document.getElementById('pdf_canvas_' + i);
|
||||
const ctx = canvas.getContext('2d');
|
||||
const viewport = page.getViewport({ scale: 4 });
|
||||
canvas.height = viewport.height;
|
||||
canvas.width = viewport.width;
|
||||
const destWidth = 298;
|
||||
const destheight = destWidth * (viewport.height / viewport.width);
|
||||
canvas.style.width = destWidth + 'px';
|
||||
canvas.style.height = destWidth * (viewport.height / viewport.width) + 'px';
|
||||
newimgList.push(canvas);
|
||||
await page.render({ canvasContext: ctx, viewport });
|
||||
// 使用file对象进行后续操作
|
||||
if (i === pageNum) {
|
||||
setTimeout(async () => {
|
||||
const res = await savePdfImage(newimgList, destWidth, destheight, fileName);
|
||||
resolve(res);
|
||||
}, 500);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
reader.onerror = function () {
|
||||
// 如果文件读取失败,拒绝Promise
|
||||
reject(new Error('Failed to read the file'));
|
||||
};
|
||||
} else {
|
||||
const reader = new FileReader();
|
||||
reader.onload = function (e) {
|
||||
let pngData = e.target.result;
|
||||
let obj = {
|
||||
url: pngData,
|
||||
name: fileName,
|
||||
};
|
||||
resolve(obj);
|
||||
};
|
||||
// 开始读取文件
|
||||
reader.readAsDataURL(file);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* pdf保存图片
|
||||
* @param {Array} newimgList - canvas列表
|
||||
* @param {Number} x - 页面展示宽
|
||||
* @param {Number} y - 页面展示高
|
||||
* @param {String}fileName - 文件名称
|
||||
*/
|
||||
function savePdfImage(newimgList, x, y, fileName) {
|
||||
return new Promise((resolve, reject) => {
|
||||
let allcanvas = document.getElementById('canvas');
|
||||
let allctx = allcanvas.getContext('2d');
|
||||
allcanvas.style.width = x;
|
||||
allcanvas.style.height = y * newimgList.length;
|
||||
const subCanvasWidth = newimgList[0].width;
|
||||
const subCanvasHeight = newimgList[0].height;
|
||||
allcanvas.width = subCanvasWidth;
|
||||
allcanvas.height = subCanvasHeight * newimgList.length;
|
||||
newimgList.forEach((subCanvas, index) => {
|
||||
// 计算当前图片在Canvas中的垂直位置
|
||||
const yPosition = index * subCanvasHeight;
|
||||
// 绘制图片
|
||||
// 使用drawImage的四个参数版本来指定绘制的源图像区域和目标区域
|
||||
allctx.drawImage(subCanvas, 0, yPosition, subCanvasWidth, subCanvasHeight);
|
||||
if (index === newimgList.length - 1) {
|
||||
let pngData = allcanvas.toDataURL('image/png');
|
||||
let obj = {
|
||||
url: pngData,
|
||||
name: fileName,
|
||||
};
|
||||
resolve(obj);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 合并图片
|
||||
* @param {file} filelist - 文件列表
|
||||
* @param {Number} realWidth - 合并后的文件宽度
|
||||
*
|
||||
*/
|
||||
export function MeargeImg(filelist, realWidth) {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
if (!filelist.length) {
|
||||
reject('材料不能为空,请检查');
|
||||
}
|
||||
let canvas = document.getElementById('myCanvas');
|
||||
const ctx = canvas.getContext('2d');
|
||||
let x = 0;
|
||||
let y = 0;
|
||||
//获取图片信息
|
||||
const dpr = window.devicePixelRatio;
|
||||
const res = await getImginfo(filelist, realWidth);
|
||||
//展示高度
|
||||
canvas.style.width = realWidth;
|
||||
canvas.style.height = res;
|
||||
canvas.width = realWidth * dpr;
|
||||
canvas.height = res * dpr;
|
||||
for (let i = 0; i < filelist.length; i++) {
|
||||
const img = new Image();
|
||||
img.src = filelist[i].url;
|
||||
img.crossOrigin = 'anonymous';
|
||||
img.onload = async () => {
|
||||
let { imgWidth, imgHeight } = await setPosition(x, y, img, realWidth);
|
||||
//获取比例
|
||||
ctx.drawImage(img, x, y, imgWidth, imgHeight);
|
||||
y += imgHeight;
|
||||
if (i === filelist.length - 1) {
|
||||
// 下载图片
|
||||
let pngData = canvas.toDataURL('image/png');
|
||||
let filename = filelist[0].name + '.png' || '合并图片.png';
|
||||
let fileimg = await base64ToFile(pngData, filename);
|
||||
let obj = {
|
||||
target: {
|
||||
files: [fileimg],
|
||||
},
|
||||
};
|
||||
resolve({ data: obj });
|
||||
}
|
||||
};
|
||||
}
|
||||
ctx.scale(dpr, dpr);
|
||||
});
|
||||
}
|
||||
//获取实际位置,宽高
|
||||
function setPosition(x, y, img, realWidth) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const scaledpr = img.width / realWidth;
|
||||
let imgWidth = img.width;
|
||||
let imgHeight = img.height;
|
||||
if (scaledpr > 1) {
|
||||
imgWidth = img.width / scaledpr;
|
||||
imgHeight = img.height / scaledpr;
|
||||
}
|
||||
resolve({
|
||||
imgWidth: imgWidth,
|
||||
imgHeight: imgHeight,
|
||||
});
|
||||
});
|
||||
}
|
||||
//获取所有图片的总高度
|
||||
function getImginfo(filelist, realWidth) {
|
||||
return new Promise((resolve, reject) => {
|
||||
let allHeight = 0;
|
||||
let loadedCount = 0; // 用于追踪已加载图片数量
|
||||
let totalImages = filelist.length; // 图片总数
|
||||
for (let i = 0; i < totalImages; i++) {
|
||||
const img = new Image();
|
||||
img.crossOrigin = 'anonymous';
|
||||
img.src = filelist[i].url;
|
||||
img.onload = () => {
|
||||
const scaledpr = img.width / realWidth;
|
||||
let imgHeight = img.height;
|
||||
if (scaledpr > 1) {
|
||||
imgHeight = img.height / scaledpr;
|
||||
}
|
||||
allHeight += imgHeight;
|
||||
loadedCount++; // 增加已加载图片计数
|
||||
if (loadedCount === totalImages) {
|
||||
resolve(allHeight);
|
||||
}
|
||||
};
|
||||
img.onerror = (error) => {
|
||||
reject(error);
|
||||
};
|
||||
}
|
||||
});
|
||||
}
|
||||
//base64转file文件
|
||||
function base64ToFile(base64, filename) {
|
||||
filename = filename || String(new Date().getTime());
|
||||
let arr = base64.split(',');
|
||||
let mime = arr[0].match(/:(.*?);/)[1];
|
||||
let bstr = atob(arr[1]);
|
||||
let n = bstr.length;
|
||||
let u8arr = new Uint8Array(n);
|
||||
while (n--) {
|
||||
u8arr[n] = bstr.charCodeAt(n);
|
||||
}
|
||||
return new File([u8arr], filename, { type: mime });
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user