当前位置: 首页 > Web前端 > JavaScript

照片水印功能

时间:2023-03-27 14:19:53 JavaScript

核心代码importEXIFfrom"exif-js";//入口constwaterMarkToPanel=async(panelFile,waterMarkFile)=>{constorientation=awaitgetOrientation(panelFile);constpanelBase64Url=awaitgetBase64(panelFile);constwaterMarkBase64Url=awaitgetBase64(waterMarkFile);//获取面板图片的原始宽高和图片元素constpanelNatureData=awaitgetNatureData(panelBase64Url);//获取水印图像的原始宽高和图像元素constwaterMarkNatureData=awaitgetNatureData(waterMarkBase64Url);//处理画布旋转/水印returnstartDraw(orientation,panelNatureData,waterMarkNatureData);};//开始处理画布并添加水印conststartDraw=(orientation,panelNatureData,waterMarkNatureData)=>{constcanvas=document.createElement("canvas");constctx:any=canvas.getContext("2d");//面板图像数据const{naturalWidth,naturalHeight,element:panelEle}=panelNatureData;//waterMark图像数据const{naturalWidth:wNatureWidth,naturalHeight:wNatureHeight,element:waterMarkEle}=waterMark自然数据;//处理canvas旋转,移动端有一些兼容,比如iosswitch(Number(orientation)){case6:console.log("图片顺时针旋转270度");canvas.width=naturalHeight;//这里注意画布的宽度其实就是图片的高度,因为图片的方向旋转了270度。下面的类尝试canvas.height=naturalWidth;ctx.rotate((90*Math.PI)/180);//由于照片的方向已经顺时针旋转了270度,再旋转90度,相当于一共转了360度,相当于没有旋转。这是正确的方向。ctx.translate(0,-canvas.width);//转了90度,位置是不是也变了?想想第一象限的图片,绕原点顺时针转90度,然后到第二象限,这时需要把ctx往supery方向上移。drawImage(panelEle,0,0,canvas.height,canvas.width);//绘制图片//恢复坐标绘制图片后,需要将画布恢复到原来的位置。我不会解释的。这有点令人困惑。ctx.translate(0,canvas.width);ctx.rotate((-90*Math.PI)/180);休息;case8:console.log("照片顺时针旋转90度");canvas.width=naturalHeight;canvas.height=naturalWidth;ctx.rotate((-90*Math.PI)/180);ctx.translate(-canvas.height,0);ctx.drawImage(panelEle,0,0,canvas.height,canvas.width);//恢复坐标ctx.翻译(画布。高度,0);ctx.rotate((90*Math.PI)/180);休息;case3:console.log("照片顺时针旋转180度");canvas.width=自然宽度;canvas.height=naturalHeight;ctx.rotate((180*Math.PI)/180);ctx.translate(-canvas.width,-canvas.height);ctx.drawImage(panelEle,0,0,canvas.width,canvas.height);//恢复坐标ctx.translate(canvas.width,canvas.height);ctx.rotate((-180*Math.PI)/180);休息;默认值:canvas.width=naturalWidth;canvas.height=naturalHeight;ctx.drawImage(panelEle,0,0,canvas.width,canvas.height);休息;}//给画布添加水印canvas.drawImagehttps://www.runoob.com/try/try.php?filename=tryhtml5_canvas_drawimagectx.drawImage(waterMarkEle,(40/750)*canvas.width,canvas.height-((40+wNatureHeight)/750)*canvas.width,(wNatureWidth/750)*canvas.width,(wNatureHeight/750)*canvas.width);consturl=canvas.toDataURL("图像/jpeg");//最终图像urlconstfile=dataURItoBlob(url);//最终图像文件return{url,file}};实用函数//获取照片方向constgetOrientation=(file)=>{returnnewPromise((resolve,reject)=>{constcurrentVersion=getVersion();//ios版本号constsupport=testVersion(currentVersion,"13.4.1");//ios版本号大于13.4.1,不作特殊处理requiredif(browserInfo.versions.ios&&support){resolve(1);}else{EXIF.getData(file,()=>{resolve(EXIF.getTag(file,"Orientation"));});}});};//获取base64constgetBase64=(file)=>{returnnewPromise((resolve,reject)=>{constreader=newFileReader();reader.addEventListener("load",()=>resolve(reader.result));reader.readAsDataURL(file);});};//获取原始图片大小constgetNatureData=(imgUrl)=>{returnnewPromise((resolve,reject)=>{constimg=newImage();img.setAttribute("crossOrigin","Anonymous");img.onload=(e:any)=>{resolve({element:imgnaturalWidth:e.target.naturalWidth,naturalHeight:e.target.naturalHeight,});};img.src=imgUrl;});};//判断ios版本preVersion是否大于lastVersionexportconsttestVersion=(preVersion:string="",lastVersion:string="")=>{constsources=preVersion.split(".");constdests=lastVersion.split(".");constmaxL=Math.max(sources.length,dests.length);letresult=true;for(leti=0;ii?sources[i]:"0";letpreNum=isNaN(Number(preValue))?preValue.charCodeAt(0):Number(preValue);letlastValue=dests.length>i?dests[i]:"0";让lastNum=isNaN(Number(lastValue))?lastValue.charCodeAt(0):Number(lastValue);if(preNumlastNum){result=true;休息;}}返回结果;};导出constgetVersion=()=>{conststr=navigator.userAgent.toLowerCase();constversion=str.match(/cpuiphoneos(.*?)likemacos/);让currentVersion="0.0.0";//ios版本号if(version&&version[1]){currentVersion=version[1].replace(/_/g,".");}returncurrentVersion;};//转换为blob直接传输暂时无用exportconstdataURItoBlob=(dataURI:string)=>{//将base64转换为字符串中的原始二进制数据//不处理URLEncodedDataURIsvarbyteString=atob(dataURI.split(",")[1]);//分离出mime组件varmimeString=dataURI.split(",")[0].split(":")[1].split(";")[0];//将字符串的字节写入ArrayBuffervarab=newArrayBuffer(byteString.length);varia=newUint8Array(ab);对于(vari=0;i