web pdf 图片拖动图片合成
先看效果
前端
合成后
1.原理
以前写过相关的帖子,使用的是 canva
但是这次换了一个思路使用的是图片
1.先把pdf转成图片
2.把pdf图片和目标图片传到浏览器
3.原理就和图片合成一样了。见上一篇帖子
4.后端也一样只不过这次是将位置和pdf进行合并
2. 前端
这里要注意pdf的比例是和图片不一样的,转换的时候要把比例传过来
目标图片的比例要保持一致
这样才能保证浏览器图片的大小和pdf中图片大小一致
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<style>
body{
margin: 0;
}
#pdfContent {
width: 100%;
}
#pdf-page{
}
.tool{
text-align: center;
padding: 5rem 0 0 0;
font-size: 30px;
line-height: 2;
background-color: aliceblue;
}
#btn-list{
padding: 2rem;
}
.btn-list{
padding: 0.5rem;
margin: 0.2rem;
}
</style>
</head>
<body>
<div id="pdfContent">
<div id="pdf-left" class="tool">
<div>
当前页:<span id="now-page"></span>
</div>
<div>
总页数:<span id="total"></span>
</div>
<div id="btn-list"></div>
</div>
<div id="pdf-page" >
<img id="img">
</div>
<div id="pdf-right" class="tool ">
<button class="btn-list" onclick="downFile()">合成并下载</button>
</div>
</div>
<script th:src="@{/imgView/pdfIndex.js}"></script>
</body>
</html>
var w_width,w_height,g_total,l_width
var result_x,result_y
var g_scale_x,g_scale_y
var pageWidth,pageHeight
var g_pdfName = 'pdf.pdf'
window.onload = function(){
w_width = window.innerWidth
w_height = window.innerHeight
source(0)
}
function downFile(){
var page = parseInt(document.getElementById('now-page').innerHTML) -1
http('/img/action/submitPdf',
{
'page': page,
'result_x':result_x,
'result_y':result_y,
'targetName':'b.png',
'pdfName':g_pdfName,
'scale_x':g_scale_x,
'scale_y':g_scale_y,
'pageWidth':pageWidth,
'pageHeight':pageHeight
})
.then(function(){
alert('生成成功')
})
}
function setTarget(){
http('/img/action/getSrc', {'name': 'b.png'})
.then(function (res) {
var ret = res.data.data
var imgSrc = 'data:image/jpeg;base64,' + ret.baseStr
var img = document.getElementById('target-img')
if(img){
img.remove();
}
img = document.createElement('img')
img.id='target-img'
img.setAttribute('src',imgSrc)
img.style.width = ret.width + 'px'
img.style.height = ret.height + 'px'
img.style.position = 'absolute'
img.style.top = '0px'
img.style.left = l_width + 'px'
var source = document.getElementById('pdf-page')
source.append(img)
var moveFlag = false
img.onmousedown = function (ev){
moveFlag = !moveFlag
result_x = ev.pageX - l_width
result_y = ev.pageY
if(moveFlag){
img.style.opacity = 0.8
img.style.filter = 'alpha(opacity=80)'
}else{
img.style.opacity = 1
img.style.filter = 'alpha(opacity=100)'
}
}
source.onmousemove = function (ev){
if(!moveFlag){
return
}
var sourceWidth = source.offsetWidth
var sourceHeight = source.offsetHeight
var imgHeight2 = ret.height/2
var imgTop = ev.pageY - imgHeight2
var imgLeft = ev.pageX - ret.width/2
if(imgLeft < l_width){
imgLeft = l_width
}
g_scale_x = ret.width/sourceWidth
g_scale_y = ret.height/sourceHeight
if(imgLeft - l_width > sourceWidth - ret.width){
imgLeft = sourceWidth + l_width - ret.width
}
if(imgTop <= 0){
imgTop = 0
}
if(imgTop > sourceHeight - imgHeight2){
imgTop = sourceHeight - ret.height
}
img.style.top = imgTop + 'px'
img.style.left = imgLeft + 'px'
}
})
}
function setPage(){
var div = document.getElementById('btn-list')
div.innerHTML = ''
for(var i=0;i<g_total;i++){
var btn = document.createElement('button')
btn.innerHTML = i+1
btn.className = 'btn-list'
btn.setAttribute('data-number',i)
btn.onclick=clickPage
div.appendChild(btn)
}
}
function clickPage(){
source(parseInt(this.innerHTML)-1)
}
function source(page){
http('/img/action/pdf/img', {'name': g_pdfName,'page':page})
.then(function(res){
var ret = res.data.data
g_total = ret.size
var img = document.getElementById('img')
img.setAttribute('src','data:image/jpeg;base64,' + ret.baseStr)
var source = document.getElementById('pdf-page')
img.style.width = ret.width + 'px'
img.style.height = ret.height + 'px'
document.getElementById('pdfContent').style.height = ret.width + 'px'
pageWidth = ret.width
pageHeight = ret.height
source.style.width = ret.width
source.style.height = ret.height
source.style.float = 'left'
var left = document.getElementById('pdf-left')
var right = document.getElementById('pdf-right')
console.log(left.getBoundingClientRect())
l_width = (w_width - ret.width)/2
left.style.width = l_width + 'px'
right.style.width = (l_width-20) + 'px'
left.style.height = ret.height + 'px'
right.style.height = ret.height + 'px'
left.style.float = 'left'
right.style.float = 'left'
document.getElementById('now-page').innerHTML = ret.page+1
document.getElementById('total').innerHTML = ret.size
setPage()
setTarget()
})
}
function http(path, data) {
return axios.post(path, data)
}
3.后端
public void submitPdf(JSONObject body) throws IOException {
int pageNum = body.getInteger("page");
float result_x = body.getFloat("result_x");
float result_y = body.getFloat("result_y");
float scale_x = body.getFloat("scale_x");
float scale_y = body.getFloat("scale_y");
File tarImg = getFile(body.getString("targetName"));
File pdfFile = new File(ResourceUtils.getURL(ResourceUtils.CLASSPATH_URL_PREFIX).getPath() + body.getString("pdfName"));
PDDocument document = PDDocument.load(pdfFile);
PDPage page = document.getPage(pageNum);
PDPageContentStream contentStream = new PDPageContentStream(document,page,PDPageContentStream.AppendMode.APPEND,false,false);
PDImageXObject image = PDImageXObject.createFromByteArray(document, Files.readAllBytes(tarImg.toPath()),"插入图片");
float pageWidth = page.getMediaBox().getWidth();
float pageHeight = page.getMediaBox().getHeight();
float imageWidth = pageWidth * scale_x;
float imageHeight = pageHeight *scale_y;
BufferedImage bufferedImage = ImageIO.read(tarImg);
image.setWidth(bufferedImage.getWidth());
image.setHeight(bufferedImage.getHeight());
float x = result_x/scale - imageWidth/2;
float y = result_y/scale;
contentStream.drawImage(image,x,pageHeight-y- imageHeight/2,imageWidth,imageHeight);
contentStream.close();
new File("new.pdf").delete();
document.save(new FileOutputStream("new.pdf"));
document.close();
4.最后
我这里使用的是pdfbox 当然pdf相关的类库很多,可以用其他的