Browse Source

未整理的 自定义图片水印

master
xuhuajiao 2 years ago
parent
commit
08f660a581
  1. BIN
      src/assets/1.jpg
  2. BIN
      src/assets/3.png
  3. 31
      src/components/HelloWorld.vue
  4. 10
      src/utils/index.js
  5. 121
      src/utils/waterMark.js
  6. 112
      src/vendors/pdf/PdfView.vue

BIN
src/assets/1.jpg

After

Width: 546  |  Height: 186  |  Size: 11 KiB

BIN
src/assets/3.png

After

Width: 1604  |  Height: 508  |  Size: 167 KiB

31
src/components/HelloWorld.vue

@ -1,5 +1,5 @@
<template> <template>
<div :class="{ hidden }">
<div class="box">
<div class="banner"> <div class="banner">
<div class="container"> <div class="container">
<h1 style="flex:1"> <h1 style="flex:1">
@ -49,6 +49,7 @@ export default {
}, },
data() { data() {
return { return {
logo: require('../assets/3.png'),
// //
loading: false, loading: false,
// //
@ -146,12 +147,22 @@ export default {
} }
// //
const maskDiv = document.getElementsByClassName('mask_div') const maskDiv = document.getElementsByClassName('mask_div')
for(var i = maskDiv.length - 1; i >= 0; i--){
document.body.removeChild(maskDiv[i])
const imgMaskDiv = document.getElementsByClassName('weterbox')
console.log(maskDiv)
console.log(imgMaskDiv)
console.log(imgMaskDiv.length)
console.log(document.getElementsByClassName('box'))
// for(var i = maskDiv.length - 1; i >= 0; i--){
// document.body.removeChild(maskDiv[i])
// }
for(var j = imgMaskDiv.length - 1; j >= 0; j--){
document.getElementsByClassName('box')[0].removeChild(imgMaskDiv[j])
} }
if(!extend.includes('pdf')){ if(!extend.includes('pdf')){
watermark({watermark_txt:"xuhuajiao" + timeFormate()});
// watermark({watermark_txt:"" + timeFormate()},'box','text');
watermark({watermark_txt: this.logo},'box','img')
} }
const child = output.appendChild(node) const child = output.appendChild(node)
@ -196,9 +207,19 @@ export default {
} }
} }
</script> </script>
<style>
@media print {
@page {
size: auto;
}
body, html {
height: auto !important;
}
}
</style>
<!-- Add "scoped" attribute to limit CSS to this component only --> <!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped> <style scoped>
.banner { .banner {
overflow: hidden; overflow: hidden;
text-align: center; text-align: center;

10
src/utils/index.js

@ -167,3 +167,13 @@ export function timeFormate() {
let D = date.getDate() < 10 ? '0' + date.getDate() : date.getDate() let D = date.getDate() < 10 ? '0' + date.getDate() : date.getDate()
return Y + M + D return Y + M + D
} }
// 下载文件
export function saveByteArray(fileName, byte) {
var blob = new Blob([byte], { type: "application/pdf" });
var link = document.createElement("a");
link.href = window.URL.createObjectURL(blob);
// var fileName = reportName;
link.download = fileName;
link.click();
}

121
src/utils/waterMark.js

@ -1,5 +1,5 @@
// 水印添加 // 水印添加
export const watermark = (settings) => {
export const watermark = (settings, className, type) => {
//默认设置 //默认设置
var defaultSettings = { var defaultSettings = {
watermark_txt: settings.watermark_txt, watermark_txt: settings.watermark_txt,
@ -18,20 +18,6 @@
watermark_angle: 15, //水印倾斜度数 watermark_angle: 15, //水印倾斜度数
} }
//采用配置项替换默认值,作用类似jquery.extend
// if (arguments.length === 1 && typeof arguments[0] === 'object') {
// var src = arguments[0] || {}
// for (var keyS in src) {
// if (
// src[keyS] &&
// defaultSettings[keyS] &&
// src[keyS] === defaultSettings[keyS]
// )
// continue
// else if (src[keyS]) defaultSettings[keyS] = src[keyS]
// }
// }
var oTemp = document.createDocumentFragment() var oTemp = document.createDocumentFragment()
//获取页面最大宽度 //获取页面最大宽度
@ -39,11 +25,7 @@
var cutWidth = page_width * 0.015 var cutWidth = page_width * 0.015
page_width = page_width - cutWidth page_width = page_width - cutWidth
//获取页面最大高度 //获取页面最大高度
var page_height =
Math.max(
document.body.scrollHeight,
document.body.clientHeight
) + 650
var page_height = Math.max( document.body.scrollHeight, document.body.clientHeight ) + 650
// var page_height = document.body.scrollHeight+document.body.scrollTop; // var page_height = document.body.scrollHeight+document.body.scrollTop;
//如果将水印列数设置为0,或水印列数设置过大,超过页面最大宽度,则重新计算水印列数和水印x轴间隔 //如果将水印列数设置为0,或水印列数设置过大,超过页面最大宽度,则重新计算水印列数和水印x轴间隔
if ( if (
@ -91,46 +73,56 @@
(defaultSettings.watermark_height + (defaultSettings.watermark_height +
defaultSettings.watermark_y_space) defaultSettings.watermark_y_space)
) )
defaultSettings.watermark_y_space = parseInt(
(page_height -
defaultSettings.watermark_y -
defaultSettings.watermark_height *
defaultSettings.watermark_rows) /
(defaultSettings.watermark_rows - 1)
)
defaultSettings.watermark_y_space = parseInt( (page_height - defaultSettings.watermark_y - defaultSettings.watermark_height * defaultSettings.watermark_rows) / (defaultSettings.watermark_rows - 1) )
} }
var x var x
var y var y
for (var i = 0; i < defaultSettings.watermark_rows; i++) { for (var i = 0; i < defaultSettings.watermark_rows; i++) {
y =
defaultSettings.watermark_y +
(defaultSettings.watermark_y_space +
defaultSettings.watermark_height) *
i
y = defaultSettings.watermark_y + (defaultSettings.watermark_y_space + defaultSettings.watermark_height) * i
for (var j = 0; j < defaultSettings.watermark_cols; j++) { for (var j = 0; j < defaultSettings.watermark_cols; j++) {
x =
defaultSettings.watermark_x +
(defaultSettings.watermark_width +
defaultSettings.watermark_x_space) *
j
x = defaultSettings.watermark_x + (defaultSettings.watermark_width + defaultSettings.watermark_x_space) * j
let dom = document.getElementsByClassName(className)
let canvas = document.createElement('canvas')
let cxt = canvas.getContext('2d')
let divImg = document.createElement('div')
let imgScale = 0.5
// canvas.width = 200
var mask_div = document.createElement('div') var mask_div = document.createElement('div')
mask_div.id = 'mask_div' + i + j mask_div.id = 'mask_div' + i + j
mask_div.className = 'mask_div' mask_div.className = 'mask_div'
mask_div.appendChild(
document.createTextNode(defaultSettings.watermark_txt)
mask_div.appendChild(document.createTextNode(defaultSettings.watermark_txt))
if(type=="img"){
//创建新的图片对象
let img = new Image();
//指定图片的URL
img.src = defaultSettings.watermark_txt;
//浏览器加载图片完毕后再绘制图片
img.onload = function() {
//cxt.drawImage(img,0,0);
cxt.rotate(-20 * Math.PI / 180)
let whScale = img.width / img.height
cxt.clearRect(0, 0, canvas.width, canvas.height);
cxt.drawImage(img, //规定要使用的图像、画布或视频。
0, 0, //开始剪切的 x 坐标位置。
img.width, img.height, //被剪切图像的高度。
0, 100,//在画布上放置图像的 x 、y坐标位置。
img.width * imgScale, img.height * imgScale //要使用的图像的宽度、高度
) )
divImg.style.opacity = 0.5
divImg.style.background = 'url(' + canvas.toDataURL('image/png') + ') left top repeat'
drawImage(divImg,dom)
}
}else{
//设置水印div倾斜显示 //设置水印div倾斜显示
mask_div.style.webkitTransform =
'rotate(-' + defaultSettings.watermark_angle + 'deg)'
mask_div.style.MozTransform =
'rotate(-' + defaultSettings.watermark_angle + 'deg)'
mask_div.style.msTransform =
'rotate(-' + defaultSettings.watermark_angle + 'deg)'
mask_div.style.OTransform =
'rotate(-' + defaultSettings.watermark_angle + 'deg)'
mask_div.style.transform =
'rotate(-' + defaultSettings.watermark_angle + 'deg)'
mask_div.style.webkitTransform = 'rotate(-' + defaultSettings.watermark_angle + 'deg)'
mask_div.style.MozTransform = 'rotate(-' + defaultSettings.watermark_angle + 'deg)'
mask_div.style.msTransform = 'rotate(-' + defaultSettings.watermark_angle + 'deg)'
mask_div.style.OTransform = 'rotate(-' + defaultSettings.watermark_angle + 'deg)'
mask_div.style.transform = 'rotate(-' + defaultSettings.watermark_angle + 'deg)'
mask_div.style.visibility = '' mask_div.style.visibility = ''
mask_div.style.position = 'absolute' mask_div.style.position = 'absolute'
mask_div.style.left = x + 'px' mask_div.style.left = x + 'px'
@ -138,19 +130,40 @@
mask_div.style.overflow = 'hidden' mask_div.style.overflow = 'hidden'
mask_div.style.zIndex = '9999' mask_div.style.zIndex = '9999'
mask_div.style.pointerEvents = 'none' //pointer-events:none 让水印不遮挡页面的点击事件 mask_div.style.pointerEvents = 'none' //pointer-events:none 让水印不遮挡页面的点击事件
//mask_div.style.border="solid #eee 1px";
mask_div.style.opacity = defaultSettings.watermark_alpha mask_div.style.opacity = defaultSettings.watermark_alpha
mask_div.style.fontSize = defaultSettings.watermark_fontsize mask_div.style.fontSize = defaultSettings.watermark_fontsize
mask_div.style.fontFamily = defaultSettings.watermark_font mask_div.style.fontFamily = defaultSettings.watermark_font
mask_div.style.color = defaultSettings.watermark_color mask_div.style.color = defaultSettings.watermark_color
mask_div.style.textAlign = 'center' mask_div.style.textAlign = 'center'
mask_div.style.width =
defaultSettings.watermark_width + 'px'
mask_div.style.height =
defaultSettings.watermark_height + 'px'
mask_div.style.width = defaultSettings.watermark_width + 'px'
mask_div.style.height = defaultSettings.watermark_height + 'px'
mask_div.style.display = 'block' mask_div.style.display = 'block'
oTemp.appendChild(mask_div) oTemp.appendChild(mask_div)
} }
} }
}
document.body.appendChild(oTemp) document.body.appendChild(oTemp)
} }
var drawImage = function (div,dom) {
div.style.pointerEvents = 'none'
div.className = 'weterbox'
div.style.top = 0
div.style.left = 0
div.style.position = 'absolute'
div.style.zIndex = '100000'
div.style.width = '100%'
div.style.height = '100%'
// console.log(dom)
if( dom.length > 0){
for(let i = 0; i< dom.length;i++){
let child = dom[i].getElementsByClassName('weterbox')
if(child.length > 0){
dom[i].removeChild(child[0])
}
dom[i].appendChild(div.cloneNode(true))
// console.log(i,dom[i])
}
}
}

112
src/vendors/pdf/PdfView.vue

@ -3,6 +3,7 @@
<div class="pdf_down"> <div class="pdf_down">
<div class="pdf_set_left" @click="scaleD()"></div> <div class="pdf_set_left" @click="scaleD()"></div>
<div class="pdf_set_middle" @click="scaleX()"></div> <div class="pdf_set_middle" @click="scaleX()"></div>
<button @click="downFile">保存并下载pdf</button>
<!-- <div class="pdf-pre" @click="prePage">上一页</div> <!-- <div class="pdf-pre" @click="prePage">上一页</div>
<div class="pdf-next" @click="nextPage">下一页</div> --> <div class="pdf-next" @click="nextPage">下一页</div> -->
</div> </div>
@ -26,6 +27,7 @@ import { degrees, PDFDocument, rgb, StandardFonts } from 'pdf-lib';
import { TextLayerBuilder, EventBus } from 'pdfdist-mergeofd/web/pdf_viewer' import { TextLayerBuilder, EventBus } from 'pdfdist-mergeofd/web/pdf_viewer'
import 'pdfdist-mergeofd/web/pdf_viewer.css'; import 'pdfdist-mergeofd/web/pdf_viewer.css';
PDFJS.GlobalWorkerOptions.workerSrc = require("pdfdist-mergeofd/build/pdf.worker.entry.js"); PDFJS.GlobalWorkerOptions.workerSrc = require("pdfdist-mergeofd/build/pdf.worker.entry.js");
import { saveByteArray } from '@/utils/index'
export default { export default {
name: "PdfView", name: "PdfView",
@ -34,6 +36,7 @@ export default {
}, },
data() { data() {
return { return {
logo: require('../../assets/logo.png'),
pdf_scale: 1.0, //pdf pdf_scale: 1.0, //pdf
pdf_pages: [], pdf_pages: [],
pdf_div_width: "", pdf_div_width: "",
@ -88,6 +91,10 @@ export default {
const helveticaFont = await pdfDoc.embedFont(StandardFonts.Helvetica) const helveticaFont = await pdfDoc.embedFont(StandardFonts.Helvetica)
const pages = pdfDoc.getPages() const pages = pdfDoc.getPages()
// let canvas = document.createElement('canvas')
// const png = canvas.toDataURL('img/png')
// const imagePDF = await pdfDoc.embedPng(png)
// //
const drawTextParams = { const drawTextParams = {
lineHeight: 50, lineHeight: 50,
@ -97,6 +104,7 @@ export default {
rotate: degrees(15), rotate: degrees(15),
opacity: 0.3 opacity: 0.3
} }
for (let index = 0; index < pages.length; index++) { for (let index = 0; index < pages.length; index++) {
const currentPage = pages[index]; const currentPage = pages[index];
// //
@ -106,11 +114,11 @@ export default {
let lineNum = 0 let lineNum = 0
for (let iy = 50; iy <= height; iy += 200) { // for (let iy = 50; iy <= height; iy += 200) { //
lineNum++ lineNum++
currentPage.drawText(`xuhuajiao`+ this.formateTime(), {
x: lineNum & 1 ? ix : ix + 60,
y: iy,
...drawTextParams
})
// currentPage.drawText(`xuhuajiao`+ this.formateTime(), {
// x: lineNum & 1 ? ix : ix + 60,
// y: iy,
// ...drawTextParams
// })
} }
} }
} }
@ -120,6 +128,57 @@ export default {
this.pdf_pages = this.pdfDoc.numPages; this.pdf_pages = this.pdfDoc.numPages;
console.log('pdf_pages',this.pdf_pages) console.log('pdf_pages',this.pdf_pages)
this.$nextTick(() => this.renderPagePdf()); this.$nextTick(() => this.renderPagePdf());
let dom = document.getElementsByClassName('page')
let canvas = document.createElement('canvas')
let cxt = canvas.getContext('2d')
let divImg = document.createElement('div')
let imgScale = 0.3
//
let img = new Image();
//URL
img.src = this.logo;
//
img.onload = function() {
//cxt.drawImage(img,0,0);
cxt.rotate(-20 * Math.PI / 180)
let whScale = img.width / img.height
cxt.clearRect(0, 0, canvas.width, canvas.height);
cxt.drawImage(img, //使
0, 0, // x
img.width, img.height, //
0, 50,// x y
img.width * imgScale, img.height * imgScale //使
)
divImg.style.opacity = 0.3
divImg.style.background = 'url(' + canvas.toDataURL('image/png') + ') left top repeat'
drawImage2(divImg,dom)
}
function drawImage2 (div,dom) {
div.style.pointerEvents = 'none'
div.className = 'weterbox'
div.style.top = 0
div.style.left = 0
div.style.position = 'absolute'
div.style.zIndex = '100000'
div.style.width = '100%'
div.style.height = '100%'
// console.log(dom)
if( dom.length > 0){
for(let i = 0; i< dom.length;i++){
let child = dom[i].getElementsByClassName('weterbox')
if(child.length > 0){
dom[i].removeChild(child[0])
}
dom[i].appendChild(div.cloneNode(true))
// console.log(i,dom[i])
}
}
}
}, },
async renderPagePdf(num = 1) { async renderPagePdf(num = 1) {
this.currentPage = num; this.currentPage = num;
@ -192,6 +251,49 @@ export default {
// this.renderPage(this.currentPage - 1); // this.renderPage(this.currentPage - 1);
// } // }
// }, // },
// PDF
async downFile() {
/*2.pdfarrarybuffer
可请求后台接口返回的base64文件流然后转成arrayBuffer类型
可访问前端项目中的本地文件不能直接访问服务器链接文件会有跨域问题*/
// try {
// 1.urlpdfarrarybuffer
// const existingPdfBytes = await fetch(this.fileUrl).then((res) => res.arrayBuffer());
// 2.arraybufferpdf
const pdfDoc = await PDFDocument.load(this.data);
// 3.1 , ()
const fontkitFile = await pdfDoc.embedFont(StandardFonts.Helvetica);
// 3.2 使fontkit
// .ttf访(访)
// const fontBytes = await fetch("/fonts/SourceHanSansCN-Normal.ttf").then((res) => res.arrayBuffer());
// pdfDoc.registerFontkit(fontkit); // fontkit
// const fontkitFile = await pdfDoc.embedFont(fontBytes);
// 4. pdf
const pages = pdfDoc.getPages();
for (let i = 0; i < pages.length; i++) {
const noPage = pages[i];
const { width, height } = noPage.getSize();
for (let i = 0; i < 10; i++) {
for (let j = 0; j < 3; j++) {
noPage.drawText('张三-2023-01-01', {
x: 230 * j,
y: (height / 4) * i,
font: fontkitFile,
size: 16,
color: rgb(0.46, 0.53, 0.6),
rotate: degrees(45),
opacity: 0.3,
});
}
}
}
//5. pdfunit64Arrary
const pdfBytes = await pdfDoc.save();
saveByteArray( "水印PDF.pdf", pdfBytes);
// } catch (error) {
// this.$message.warning("");
// }
},
}, },
}; };
</script> </script>

Loading…
Cancel
Save