精华内容
下载资源
问答
  • canvas图片绘制

    2018-11-30 14:16:54
    所以就用了canvas图片合成的功能。 绘制之前,我们先了解下canvas的绘制图片方法。 HTML5中引入新的元素canvas,其drawImage 方法允许在 canvas 中插入其他图像( img 和 canvas 元素) 。drawImage函数有三种函数原型...

    H5的img标签可以在手机端自动保存,但是我需求是这样子的,一张图片上有优惠码,可以点击复制,有合成的照片,长按要整体保存。所以就用了canvas图片合成的功能。
    绘制之前,我们先了解下canvas的绘制图片方法。
    HTML5中引入新的元素canvas,其drawImage 方法允许在 canvas 中插入其他图像( img 和 canvas 元素) 。drawImage函数有三种函数原型

    drawImage(image, dx, dy) 
    drawImage(image, dx, dy, dw, dh) 
    drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh)
    

    第一个参数image可以用HTMLImageElement,HTMLCanvasElement或者HTMLVideoElement作为参数。dx和dy是image在canvas中定位的坐标值;dw和dh是image在canvas中即将绘制区域(相对dx和dy坐标的偏移量)的宽度和高度值;sx和sy是image所要绘制的起始位置,sw和sh是image所要绘制区域(相对image的sx和sy坐标的偏移量)的宽度和高度值。
    下面开始上代码

    	drawimg() {
    		var that = this;
    		var canvas = document.createElement('canvas');
    		var ctx = canvas.getContext('2d');
    		canvas.width = 624;//canvas画布的宽度
    		canvas.height = 1103;//canvas画布大小
    		var img1 = new Image();
    		img1.crossOrigin = "";//解决跨域
    		img1.src = 'http://morefun.image.alimmdn.com/neateest/background.png'
    		img1.onload = function () {
    		//把图片画到canvas上
    			ctx.drawImage(
    				this, 0, 0
    			);
    			var img2 = new Image();
    			img2.crossOrigin = "";
    			img2.src = "http://morefun.image.alimmdn.com/youmai/xuxu/photo.png"
    			img2.onload = function () {
    				ctx.drawImage(
    					this, 12, 12
    				)
    				//canvas写入文字
    				ctx.font = "bold 44px 方正粗圆简体";
    				ctx.fillStyle = "#890a0a";
    				for (var i = 0; i < that.promocode.length; i++) {
    					ctx.fillText(that.promocode[i], 40 + i * 37, 997);
    				}
    				that.canvasimg = canvas.toDataURL("image/png")//此时的路径是base64格式,ios可以直接长按保存,但是在安卓上就要把base64格式转为url就可以了
    			}
    		}
    

    这样一个canvas就绘制好了。

    展开全文
  • canvas 图片跨域

    千次阅读 2018-08-29 13:15:27
    问题:canvas 图片跨域。 解决办法:采用所有图片路径,转化为base64流,来处理。相对于本地图片了。此时,就避开了跨域问题。 图片路径,转base64,后端处理,更方便。 eg: php /** * @param $ur...

    在项目中,需要生成海报。有动态信息(微信头像、微信昵称、上传图片(oss链接)、二维码)+ 海报背景图生成一张海报。

    技术支持:canvas 生成。

    问题:canvas 图片跨域。

    解决办法:采用所有图片路径,转化为base64流,来处理。相对于本地图片了。此时,就避开了跨域问题。
    图片路径,转base64,后端处理,更方便。
    eg: php

    /**
     * @param $url
     * @return bool|string
     * Name: master_imgUrl_base64
     * User: wangjiapeng
     * Date: 2018/04/12
     * Explain:CDN远程图片URL下载,并转化为base64
     */
    protected function master_imgUrl_base64($url){
        if($url){
            $header = array(
                'User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:45.0) Gecko/20100101 Firefox/45.0',
                'Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3',
                'Accept-Encoding: gzip, deflate',);
    
            $curl = curl_init();
            curl_setopt($curl, CURLOPT_URL, $url);
            curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
            curl_setopt($curl, CURLOPT_ENCODING, 'gzip');
            curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
            $data = curl_exec($curl);
            $code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
            curl_close($curl);
            if ($code == 200) {//把URL格式的图片转成base64_encode格式的!
                $imgBase64Code = "data:image/jpeg;base64," . base64_encode($data);
                 return $imgBase64Code;
            }else{
                 return false;
            }
        }else{
            return false;
        }
    }

    附加,海报中需要生成二维码。

    技术支持:jquery.qrcode.min.js

    方法:1.html 中放入盒子

    <div style="display: none;" id="qrcode">
    1. js
    $("#qrcode").qrcode({
        render: "canvas",
        text: data.info.u_url  (要生成的url:例 https://blog.csdn.net/qq_37837134)
    });
    var codeCanvas=document.getElementById("qrcode").getElementsByTagName("canvas")[0];
    var codeContext = codeCanvas.getContext("2d");
    var imgsSrc1 = codeCanvas.toDataURL('image/jpg');
    
    do_canvasa(data.info,imgsSrc1);    //  此方法  为canvas 生成海报   参数一:微信头像、微信昵称等     参数二:二维码

    3.

    function do_canvasa(data,imgsSrc1) {
        //获取canvas
        var canvas = document.getElementById('canvas');
    //设置宽高
    //想获取高清图请*2,一般的直接等于Width就行
        var Height = window.innerHeight*2;
        var Width = window.innerWidth*2;
    //canvas绘制需要的对象
        var ctx = canvas.getContext("2d");
        canvas.width = Width;
        canvas.height = Height;
    //获取图片
        var mainImg = document.getElementById('mainImg');
    //获取图片
    
        var imgs = {
            bg: data.img_posters, //大背景
            via: data.wx_img, //头像
            pho:data.upload_img, //照片
            qrCode: imgsSrc1, //二维码
        };
    
        var draw = {};
        ```
    //载入图片
        draw.into = function(){
            var imgNum = 0;
            for(var key in imgs){
                var img = new Image();
                img.crossOrigin = "";
                img.src = imgs[key];
                imgs[key] = img;
                imgs[key].onload = function(){
                    imgNum++;
                    if(imgNum == Object.keys(imgs).length) draw.drawImg();
                }
            }
        }
        //绘制canvas
        draw.drawImg = function(){
            //背景图
            ctx.drawImage(imgs.bg, 0, 0, Width, Height);
            //头像
            ctx.save();
            ctx.arc(Width*0.14, Height*0.12, Width*0.075, 0, 360);
            ctx.clip();
            ctx.drawImage(imgs.via, Width*0.065, Height*0.07, Width*0.16, calcHeight(imgs.via, Width*0.16));
            ctx.restore();
            //昵称5
            //颜色
            ctx.fillStyle = '#fff';
            //字体设置 三个参数,font-weight font-size font-family
            ctx.font = '26px microsoft yahei';
            //说明
            // (scaled-0.62)
            ctx.fillText(''+data.wx_name+'', Width*0.225, Height*0.105);
            ctx.font = '24px microsoft yahei';
            ctx.fillStyle = 'red';
            ctx.textAlign="center";
            ctx.fillText(''+data.order_num+'', Width*0.34, Height*0.134);
            //照片
            ctx.save();
            ctx.strokeStyle = '#fff';
            ctx.lineWidth = 20;
            ctx.lineJoin = "round";
            if(imgs.pho.height > imgs.pho.width) {
                ctx.strokeRect((Width-Height*0.3 / imgs.pho.height * imgs.pho.width)/2, (Height-Height*0.3)/2 + 80, Height*0.3 / imgs.pho.height * imgs.pho.width, Height*0.3 );
                ctx.fillRect((Width-Height*0.3 / imgs.pho.height * imgs.pho.width)/2, (Height-Height*0.3)/2 + 80, Height*0.3 / imgs.pho.height * imgs.pho.width, Height*0.3 );
                ctx.drawImage(imgs.pho, (Width-Height*0.3 / imgs.pho.height * imgs.pho.width)/2, (Height-Height*0.3)/2 + 80, Height*0.3 / imgs.pho.height * imgs.pho.width, Height*0.3);
            } else if(imgs.pho.height < imgs.pho.width){
                ctx.strokeRect((Width-Width*0.7)/2, (Height - Width*0.7 / imgs.pho.width * imgs.pho.height) / 2 + 80, Width*0.7, Width*0.7 / imgs.pho.width * imgs.pho.height);
                ctx.fillRect((Width-Width*0.7)/2, (Height - Width*0.7 / imgs.pho.width * imgs.pho.height) / 2 + 80, Width*0.7, Width*0.7 / imgs.pho.width * imgs.pho.height);
                ctx.drawImage(imgs.pho, (Width-Width*0.7)/2,(Height - Width*0.7 / imgs.pho.width * imgs.pho.height) / 2 + 80, Width*0.7, Width*0.7 / imgs.pho.width * imgs.pho.height);
            } else {
                ctx.strokeRect((Width-440)/2, (Height-Width*0.7)/2 + 120, 440, 440);
                ctx.fillRect((Width-440)/2, (Height-Width*0.7)/2 + 120, 440, 440);
                ctx.drawImage(imgs.pho, (Width-440)/2, (Height-Width*0.7)/2 + 120, 440, 440);
            }
    
            ctx.restore();
            //二维码
            ctx.drawImage(imgs.qrCode, (Width-Width*0.22)/2 , Height*0.76, Width*0.22, calcHeight(imgs.qrCode, Width*0.22));
            //获取base64格式的src
            var imgSrc = canvas.toDataURL('image/jpg');
            mainImg.src = imgSrc;
        }
    
        draw.into();
    
        function calcHeight(obj, w){
            return w / obj.width * obj.height;
        }
    
    }
    展开全文
  • Canvas图片跨域问题

    2019-06-05 10:11:33
    解决JS操作图片 跨域错误问题,Canvas 图片裁剪保存跨域错误 const ctx = document.getElementById('canvas').getContext('2d'); const img = new Image(); img.onload = () => { ctx!.dra...

    解决JS操作图片 跨域错误问题,Canvas 图片裁剪保存跨域错误

     

    const ctx = document.getElementById('canvas').getContext('2d');
                const img = new Image();
                img.onload = () => {
                    ctx!.drawImage(img, 0, 0); //canvas操作图片

                    console.log(ctx!.canvas.toDataURL('image/png', 1));
                };

                let xhr = new XMLHttpRequest(); //下载图片
                xhr.onloadend = e => {
                    const tg = e.target as any;
                    img.src = URL.createObjectURL(tg.response); //加载图片数据转src
                };
                xhr.timeout = 10000; // 设置超时时间,0表示永不超时
                xhr.responseType = 'blob';
                // 初始化请求
                xhr.open('GET', 'https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=2859753920,13388660&fm=26&gp=0.jpg');
                xhr.send(null);
     

    展开全文
  • canvas 图片处理(缩放、旋转、裁剪、合并、文字)

    万次阅读 多人点赞 2018-11-03 17:32:16
    canvas 图片处理(缩放、旋转、裁剪、合并、文字)图片旋转以图片中心作旋转示例未完待续。。。。。。 图片旋转 tupian图片旋转主要调用的是canvas的rotate()方法 rotate()旋转当前的绘图。 语法:context....

    图片旋转

    tupian图片旋转主要调用的是canvas的rotate()方法
    rotate()旋转当前的绘图。
    语法:context.rotate(angle)
    参数:angle旋转角度,以弧度计(n*Math.PI)
    举例:假如想要旋转60度,可以context.rotate(Math.PI/3)进行表示;
    旋转的中心是在整个画布的左上角(0,0),旋转的正方向是顺时针,旋转的反方向是逆时针

    重点:canvas中的rotate方法是绕画布左上角(0,0)进行旋转的,而且会受到translate的影响

    以图片中心作旋转

    想要以图片中心旋转,首先要使用translate()方法将画布的中心移至图片的中心

    示例

    旋转前
    在这里插入图片描述
    旋转后
    在这里插入图片描述
    先贴代码
    html:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script type="text/javascript" src="js/jquery-1.11.1.min.js"></script>
        <script type="text/javascript" src="js/test.js"></script>
     <style>
           body{
                background-color: black;
            }
        </style>
    </head>
    <body>
    <canvas id="myCanvas" width="800" height="600" style="background-color: white"></canvas>
    
    <div class="square">
        <input type="text" id="rotateDegree">
        <button id="rotateBtn" class="icon rotate-icon">旋转</button>
    </div>
    </body>
    </html>
    

    js

    let myImage;
    let ctx;
    let img;
    window.onload = function () {
        myImage = document.getElementById("myCanvas");
        ctx = myImage.getContext("2d");
    
        img = new Image();
        img.src = "eg_tulip.jpg";
        img.onload = function () {
            ctx.drawImage(img, myImage.width / 2 - img.width / 2, myImage.height / 2 - img.height / 2);
        };
    
        let degree = 0;
        $("#rotateBtn").click(function () {
            let rotateInput = $("#rotateDegree").val();
            degree += parseInt(rotateInput);
            degree %= 360;
    
            ctx.save();
            ctx.clearRect(0, 0, myImage.width, myImage.height);
            ctx.translate(myImage.width / 2, myImage.height / 2);
            ctx.rotate(degree / 180 * Math.PI);
            ctx.translate(-myImage.width / 2, -myImage.height / 2);
            ctx.drawImage(img, myImage.width / 2 - img.width / 2, myImage.height / 2 - img.height / 2);
            ctx.restore();
        });
    };
    

    代码解释:

    ctx.drawImage(img, myImage.width / 2 - img.width / 2, myImage.height / 2 - img.height / 2);
    

    这一行代码将图片画在了画布中心

    ctx.save();
    ctx.clearRect(0, 0, myImage.width, myImage.height);        ctx.translate(myImage.width / 2, myImage.height / 2);        ctx.rotate(degree / 180 * Math.PI);        
    ctx.translate(-myImage.width / 2, -myImage.height / 2);        
    ctx.drawImage(img, myImage.width / 2 - img.width / 2, myImage.height / 2 - img.height / 2);
    ctx.restore();
    

    在这一部分我们可以看到,我们先是使用translate将画布中心从(0,0)移至(myImage.width / 2, myImage.height / 2)
    然后将画布旋转degree度
    再将画布中心从(myImage.width / 2, myImage.height / 2)移至(0,0)
    然后将图片画在画布中间就可以看到图片旋转了degree度,并且可以接着输入,接着旋转
    假设myImage.width = 800 myImage.height = 600 img.width = 400 myImage.height = 300
    ctx.translate(myImage.width / 2, myImage.height / 2);
    在这里插入图片描述ctx.rotate(degree / 180 * Math.PI);
    在这里插入图片描述ctx.translate(-myImage.width / 2, -myImage.height / 2);
    在这里插入图片描述 为什么坐标系会往右上跑呢?
    因为此时向下为x正轴,则向上为负,向左为y正轴,则向右为y负轴,我们传递的是负数参数,所以会往右上跑。
    这时候,当我们调用drawImage的时候,被画出来的图片就会跟着坐标系旋转相应的度数
    因为这只是一部分,所以使用restore(),save()让图片其他的操作不受影响

    Reference:

    1. translate()和rotate()的相互影响可以参考这篇文章https://segmentfault.com/a/1190000013969871?utm_source=tag-newest
    2. 实现图片旋转以及对canvas旋转的探究可以参考这篇文章http://www.php.cn/css-tutorial-384975.html
    3. 程序的编写参考的是这篇https://blog.csdn.net/XIAOZHUXMEN/article/details/50732038

    图片缩放

    图片缩放是所有操作中最简单的一个,调用的主要是canvas的scale()方法

    示例

    缩放前
    在这里插入图片描述
    拖动下面的input框进行缩放

    在这里插入图片描述 先贴上代码
    html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script type="text/javascript" src="jquery-1.11.1.min.js"></script>
        <script type="text/javascript" src="test.js"></script>
    
        <style>
           body{
                background-color: black;
            }
        </style>
    </head>
    <body>
    <canvas id="myCanvas" width="800" height="600" style="background-color: white"></canvas>
    <div class="rangeContainer">
        <input type="range" id="scale-range" min="0.5" max="3.0" step="0.01" value="1.0" style="display: block;">
    </div>
    </body>
    </html>
    

    js

    let myImage;
    let ctx;
    let img;
    window.onload = function () {
        myImage = document.getElementById("myCanvas");
        ctx = myImage.getContext("2d");
    
        img = new Image();
        img.src = "eg_tulip.jpg";
        img.onload = function () {
            ctx.drawImage(img, myImage.width / 2 - img.width / 2, myImage.height / 2 - img.height / 2);
        };
    
        $("#scale-range").mousemove(function () {
            let scaleInput = $("#scale-range").val();
            ctx.clearRect(0, 0, myImage.width, myImage.height);
            ctx.save();
            ctx.translate(myImage.width / 2 - img.width / 2 * scaleInput, myImage.height / 2 - img.height / 2 * scaleInput);
            ctx.scale(scaleInput, scaleInput);
            ctx.drawImage(img, 0, 0);
            ctx.restore();
        });
    };
    

    因为canvas的scale()像rotate()一样,会影响画布,所有为了实现围绕图片的中心进行缩放,我们先使用translate将画布中心放在画布中间。

    Reference:
    画布缩放和图片缩放可以参考这篇文章,横纵坐标都会同时被scale相同的倍数,所以drawImage()时,即使传进去的参数是一样的,在画布上的位置也会不一样https://blog.csdn.net/dayewandou/article/details/78242964?locationNum=5&fps=1

    图片裁剪

    图片裁剪的代码借鉴于一位博主,在canvas图片上会出现一个矩形框,通过拖拽这个矩形框可以选择要裁剪的图片的大小,最后再使用drawImage的第三个重载方法,将裁剪后的图片画在画布上
    context.drawImage(img,sx,sy,swidth,sheight,x,y,width,height);

    重点:sx,sy是相对于图片的坐标,即图片左上角为sx,sy的坐标系,而不是画布左上角(0,0)为坐标系

    示例

    裁剪前
    在这里插入图片描述

    裁剪后
    在这里插入图片描述
    html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script type="text/javascript" src="jquery-1.11.1.min.js"></script>
        <script type="text/javascript" src="test.js"></script>
    
        <style>
           body{
                background-color: black;
            }
        </style>
    </head>
    <body>
    <canvas id="myCanvas" width="800" height="600" style="background-color: white"></canvas>
    <div class="square">
        <button id="clipBtn" class="icon clip-icon">裁剪</button>
        <button type="button" id="clipEndBtn">裁剪完成</button>
    </div>
    </body>
    </html>
    
    let myImage;
    let ctx;
    let img;
    let orignWidth;
    let orignHeight;
    window.onload = function () {
        myImage = document.getElementById("myCanvas");
        ctx = myImage.getContext("2d");
    
        img = new Image();
        img.src = "eg_tulip.jpg";
        img.onload = function () {
            ctx.drawImage(img, myImage.width / 2 - img.width / 2, myImage.height / 2 - img.height / 2);
            orignWidth = img.naturalWidth;
            orignHeight = img.naturalHeight;
        };
    
        const ID = function (id) {
            return document.getElementById(id);
        };
    
        //拖拽与拉伸方法
        //拖拽拉伸所需参数
        let params = {
            left: 0,
            top: 0,
            width: 0,
            height: 0,
            currentX: 0,
            currentY: 0,
            flag: false,
            kind: "drag"
        };
        //获取相关CSS属性方法
        let getCss = function (o, key) {
            return o.currentStyle ? o.currentStyle[key] : document.defaultView.getComputedStyle(o, false)[key];
        };
    
        document.getElementById("clipBtn").onclick = function () {
            var clickFlag = false;
    
            var iCurWidth = img.width;
            var iCurHeight = img.height;
    
            var oRelDiv = document.createElement("div");
            oRelDiv.style.position = "absolute";
            oRelDiv.style.width = iCurWidth + "px";
            oRelDiv.style.height = iCurHeight + 30 + "px";
            oRelDiv.style.top = "30px";
            oRelDiv.id = "cropContainer";
    
            var iOrigWidth = orignWidth, iOrigHeight = orignHeight;
            var scaleX = iCurWidth / iOrigWidth;
            var scaleY = iCurHeight / iOrigHeight;
    
            myImage.parentNode.insertBefore(oRelDiv, myImage);
    
            //初始化坐标与剪裁高宽
            var cropW = 80, cropH = 80;
            var posX = (myImage.offsetLeft + myImage.width / 2 - cropW / 2),
                posY = myImage.offsetTop + myImage.height / 2 - cropH / 2;
            var sInnerHtml =
                '<div id="zxxCropBox" style="height:' + cropH + 'px; width:' + cropW + 'px; position:absolute; left:' + posX + 'px; top:' + posY + 'px; border:1px solid black;">' +
                '<div id="zxxDragBg" style="height:100%; background:white; opacity:0.3; filter:alpha(opacity=30); cursor:move"></div>' +
                '<div id="dragLeftTop" style="position:absolute; width:4px; height:4px; border:1px solid #000; background:white; overflow:hidden; left:-3px; top:-3px; cursor:nw-resize;"></div>' +
                '<div id="dragLeftBot" style="position:absolute; width:4px; height:4px; border:1px solid #000; background:white; overflow:hidden; left:-3px; bottom:-3px; cursor:sw-resize;"></div>' +
                '<div id="dragRightTop" style="position:absolute; width:4px; height:4px; border:1px solid #000; background:white; overflow:hidden; right:-3px; top:-3px; cursor:ne-resize;"></div>' +
                '<div id="dragRightBot" style="position:absolute; width:4px; height:4px; border:1px solid #000; background:white; overflow:hidden; right:-3px; bottom:-3px; cursor:se-resize;"></div>' +
                '<div id="dragTopCenter" style="position:absolute; width:4px; height:4px; border:1px solid #000; background:white; overflow:hidden; top:-3px; left:50%; margin-left:-3px; cursor:n-resize;"></div>' +
                '<div id="dragBotCenter" style="position:absolute; width:4px; height:4px; border:1px solid #000; background:white; overflow:hidden; bottom:-3px; left:50%; margin-left:-3px; cursor:s-resize;"></div>' +
                '<div id="dragRightCenter" style="position:absolute; width:4px; height:4px; border:1px solid #000; background:white; overflow:hidden; right:-3px; top:50%; margin-top:-3px; cursor:e-resize;"></div> ' +
                '<div id="dragLeftCenter" style="position:absolute; width:4px; height:4px; border:1px solid #000; background:white; overflow:hidden; left:-3px; top:50%; margin-top:-3px; cursor:w-resize;"></div>' +
                '</div>' +
                '<input type="hidden" id="cropPosX" value="' + posX / scaleX + '" />' +
                '<input type="hidden" id="cropPosY" value="' + posY / scaleY + '" />' +
                '<input type="hidden" id="cropImageWidth" value="' + cropW / scaleX + '" />' +
                '<input type="hidden" id="cropImageHeight" value="' + cropH / scaleY + '" />';
    
            oRelDiv.innerHTML = sInnerHtml;
    
            var startDrag = function (point, target, kind) {
                //point是拉伸点,target是被拉伸的目标,其高度及位置会发生改变
                //此处的target与上面拖拽的target是同一目标,故其params.left,params.top可以共用,也必须共用
                //初始化宽高
                params.width = getCss(target, "width");
                params.height = getCss(target, "height");
                //初始化坐标
                if (getCss(target, "left") !== "auto") {
                    params.left = getCss(target, "left");
                }
                if (getCss(target, "top") !== "auto") {
                    params.top = getCss(target, "top");
                }
                //target是移动对象
                point.onmousedown = function (event) {
                    params.kind = kind;
                    params.flag = true;
                    clickFlag = true;
                    if (!event) {
                        event = window.event;
                    }
                    var e = event;
                    params.currentX = e.clientX;
                    params.currentY = e.clientY;
                    //防止IE文字选中,有助于拖拽平滑
                    point.onselectstart = function () {
                        return false;
                    };
    
                    document.onmousemove = function (event) {
                        let e = event ? event : window.event;
                        clickFlag = false;
                        if (params.flag) {
                            var nowX = e.clientX, nowY = e.clientY;
                            var disX = nowX - params.currentX, disY = nowY - params.currentY;
                            if (params.kind === "n") {
                                //上拉伸
                                //高度增加或减小,位置上下移动
                                target.style.top = parseInt(params.top) + disY + "px";
                                target.style.height = parseInt(params.height) - disY + "px";
                            } else if (params.kind === "w") {//左拉伸
                                target.style.left = parseInt(params.left) + disX + "px";
                                target.style.width = parseInt(params.width) - disX + "px";
                            } else if (params.kind === "e") {//右拉伸
                                target.style.width = parseInt(params.width) + disX + "px";
                            } else if (params.kind === "s") {//下拉伸
                                target.style.height = parseInt(params.height) + disY + "px";
                            } else if (params.kind === "nw") {//左上拉伸
                                target.style.left = parseInt(params.left) + disX + "px";
                                target.style.width = parseInt(params.width) - disX + "px";
                                target.style.top = parseInt(params.top) + disY + "px";
                                target.style.height = parseInt(params.height) - disY + "px";
                            } else if (params.kind === "ne") {//右上拉伸
                                target.style.top = parseInt(params.top) + disY + "px";
                                target.style.height = parseInt(params.height) - disY + "px";
                                target.style.width = parseInt(params.width) + disX + "px";
                            } else if (params.kind === "sw") {//左下拉伸
                                target.style.left = parseInt(params.left) + disX + "px";
                                target.style.width = parseInt(params.width) - disX + "px";
                                target.style.height = parseInt(params.height) + disY + "px";
                            } else if (params.kind === "se") {//右下拉伸
                                target.style.width = parseInt(params.width) + disX + "px";
                                target.style.height = parseInt(params.height) + disY + "px";
                            } else {//移动
                                target.style.left = parseInt(params.left) + disX + "px";
                                target.style.top = parseInt(params.top) + disY + "px";
                            }
                        }
    
                        document.onmouseup = function () {
    
                            params.flag = false;
                            if (getCss(target, "left") !== "auto") {
                                params.left = getCss(target, "left");
                            }
                            if (getCss(target, "top") !== "auto") {
                                params.top = getCss(target, "top");
                            }
                            params.width = getCss(target, "width");
                            params.height = getCss(target, "height");
    
                            //给隐藏文本框赋值
                            posX = parseInt(target.style.left);
                            posY = parseInt(target.style.top);
                            cropW = parseInt(target.style.width);
                            cropH = parseInt(target.style.height);
                            if (posX < 0) {
                                posX = 0;
                            }
                            if (posY < 0) {
                                posY = 0;
                            }
                            if ((posX + cropW) > iCurWidth) {
                                cropW = iCurWidth - posX;
                            }
                            if ((posY + cropH) > iCurHeight) {
                                cropH = iCurHeight - posY;
                            }
                            //赋值
                            ID("cropPosX").value = posX;
                            ID("cropPosY").value = posY;
                            ID("cropImageWidth").value = parseInt(ID("zxxCropBox").style.width);
                            ID("cropImageHeight").value = parseInt(ID("zxxCropBox").style.height);
    
                        };
                    }
                };
    
    
            };
    
    
            //绑定拖拽
            startDrag(ID("zxxDragBg"), ID("zxxCropBox"), "drag");
            //绑定拉伸
            startDrag(ID("dragLeftTop"), ID("zxxCropBox"), "nw");
            startDrag(ID("dragLeftBot"), ID("zxxCropBox"), "sw");
            startDrag(ID("dragRightTop"), ID("zxxCropBox"), "ne");
            startDrag(ID("dragRightBot"), ID("zxxCropBox"), "se");
            startDrag(ID("dragTopCenter"), ID("zxxCropBox"), "n");
            startDrag(ID("dragBotCenter"), ID("zxxCropBox"), "s");
            startDrag(ID("dragRightCenter"), ID("zxxCropBox"), "e");
            startDrag(ID("dragLeftCenter"), ID("zxxCropBox"), "w");
    
    
            //图片不能被选中,目的在于使拖拽顺滑
            ID("myCanvas").onselectstart = function () {
                return false;
            };
            img.onselectstart = function () {
                return false;
            };
        };
    
        $("#clipEndBtn").click(function () {
            console.log("clipend......");
            var tx = myImage.offsetLeft + (myImage.width - img.width) / 2;
            var ty = myImage.offsetTop + (myImage.height - img.height) / 2;
    
            var x = parseInt(ID("zxxCropBox").style.left) - tx,
                y = ID("zxxCropBox").offsetTop + ID("zxxCropBox").parentNode.offsetTop - ty,
                w = document.getElementById("cropImageWidth").value,
                h = document.getElementById("cropImageHeight").value;
    
    
            cropImage(img, x, y, parseInt(w), parseInt(h));
    
        });
    
        function cropImage(img, cropPosX, cropPosY, width, height) {
            var cropContainer = ID("cropContainer");
            cropContainer.parentNode.removeChild(cropContainer);
            ctx.clearRect(0, 0, myImage.width, myImage.height);
            //sx,sy 是相对于图片的坐标。巨坑
    
            ctx.drawImage(img, cropPosX, cropPosY, width, height, myImage.width / 2 - width / 2, myImage.height / 2 - height / 2, width, height);
    
            img.src = myImage.toDataURL("image/png");
        }
    };
    

    难点在于在canvas画布上制作一个矩形框,并可对其进行拖拽

    图片合并

    图片合成拖拽部分基本和图片剪辑一致,只是增加了可以旋转的中心,旋转时通过js控制
    style.transform 可以得到旋转的度数

    document.getElementById("rotateCenter").onclick = function (ev) {
                   var oldY = null;
                   var isdown = true;
                   oldY = ev.clientY;
                   $("html").mousemove(function (e) {
                       if (isdown) {
                           $("#zxxCropBox").css("transform", "rotate(" + (e.clientY - oldY) + "deg)");
                       }
                   });
                   $("html").mouseup(function (e) {
                       isdown = false;
                       oldY = null;
                   });
               }
    

    示例

    合并前
    在这里插入图片描述
    合并后
    在这里插入图片描述

    重要js代码:

    $("#meldEndBtn").click(function () {
           //旋转度数
           var rotateDegree = ID("zxxCropBox").style.transform;
           rotateDegree = rotateDegree.substring(7, rotateDegree.indexOf('d'));
    
           var zxxCropBox = ID("zxxCropBox");
           //放大倍数
           var orignWidth = 80;
           var orignHeight = 80;
           var curWidth = parseInt(zxxCropBox.style.width);
           var curHeight = parseInt(zxxCropBox.style.height);
    
           var scaleWidthRate = curWidth / orignWidth;
           var scaleHeightRate = curHeight / orignHeight;
    
           //当前位置
           var posX = zxxCropBox.offsetLeft;
           var posY = zxxCropBox.offsetTop;//zxxCropBox.parentNode.offsetTop;
           //中心位置
           var centerX = ID("rotateCenter").offsetLeft + posX;
           var centerY = ID("rotateCenter").offsetTop + posY;
    
           var newImg = new Image();
           newImg.src = meldImg.src;
    
           newImg.onload = function () {
               ctx.save();
               ctx.translate(centerX, centerY);
               ctx.rotate(rotateDegree / 180 * Math.PI);
               ctx.drawImage(newImg, -ID("rotateCenter").offsetLeft, -ID("rotateCenter").offsetTop, newImg.width * scaleWidthRate, newImg.height * scaleHeightRate);
               ctx.restore();
    
               var meldContainer = ID("meldContainer");
               meldContainer.parentNode.removeChild(meldContainer);
           }
       });
    

    首先要计算放大倍数,这里要注意style.width得到的是string类型,所以要转为int类型,不然运算后就变成NAN

    把新元素加上去的时候要先translate到旋转中心,因为其他点的位置都因为旋转而变得不精确,但是旋转时rotateCenter这个点的坐标是不变的。
    然后rotate旋转相应度数
    最后drawImg时,ID(“rotateCenter”).offsetLeft/Top即矩形框的左上角的坐标。
    这样就可以把新元素画在自己想画的位置上

    summary:中心点不变,那么就可以作为画新元素的坐标基点

    canvas 透明处理

    此处记录一下透明处理,得到context的imageData,然后遍历,将每一个data的第四个值置为0,将前三个值置为255,就可以变成透明的

    var imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
    var data = imageData.data;
    for (var i = 0; i < imageData.width * imageData.height * 4; i += 4) 
    	if (data[i] >= 250 && data[i + 1] >= 250 && data[i + 2] >= 250) {
    		data[i + 3] = 0;
            }
    }
    ctx.putImageData(imageData, 0, 0);
    

    因为最近半年都在忙着其他事,所以很少看CSDN,对没能及时帮上忙的各位感到抱歉。以下放出github链接。
    https://github.com/Vendredimatin/imgEdit.git
    注:因为这是一个课设,而图片编辑只是课设的一部分,所以里面的代码不仅仅有图片编辑的,建议只看./public/imageEdit.js就好;另外,因为当时赶时间,所以只关注了实现效果,代码易读性极差并且非常冗余,写的很垃圾。所以不一定能帮到各位。。。

    展开全文
  • Canvas 图片加载

    千次阅读 2018-08-01 15:31:56
    canvas方法加载图片,占用内存最小,效果最佳。   关于canvas加载,我的方法是,将文章中所有用到图片的地方,都用canvas代替,给canvas一个data-src,里面存放img的路径,通过canvas方法渲染图片。因为图片渲染...
  • html页面生成canvas图片

    2019-01-17 16:26:01
    最近产品提出了一个新的需求,希望从app分享出来的h5页面在微信或者浏览器中打开后,可以点击按钮将html整个页面生成一张图片,用户长按...html页面生成canvas图片&lt;/div&gt;  &lt;div&gt;html...
  • canvas 图片跨域(一)

    万次阅读 2018-04-16 11:12:14
    在项目中,需要生成海报。有动态信息(微信头像、...问题:canvas 图片跨域。解决过程(填坑历程): 1.从网上存在如图解决办法 img.crossOrigin = "" (专业采坑,数年)。亲测无效。很是不解。 ...
  • canvas图片合成,支持右键[另存为] 一、合成内容 1.图片 背景图 专属二维码 用户头像(圆形) 2.用户名 二、项目地址 https://github.com/StavinLi/canvas-Synthetic-picture 三、效果预览 ...
  • vue中解决html2canvas图片跨域问题

    千次阅读 2019-08-29 10:33:16
    vue中解决html2canvas图片跨域问题 html2canvas在截图的过程中,如果遇到html中有跨域地址的图片,即图片地址非本地,截图的时候将不会显示图片 解决方法: html <div ref="imageDom"> <!-- 支持跨域的...
  • HTML5画布Canvas图片抽取、像素信息获取、命中检测

    万次阅读 多人点赞 2017-01-14 20:30:46
    首先我仍然需要创建画布<canvas id="myCanvas" width=500 height=500></canvas>图片抽取首先要明确的一点是 toDataURL()是canvas对象自身的方法而不是环境对象的 这个方法会将canvas的内容抽取为一张图片(base
  • canvas 图片圆角问题

    2020-07-13 08:44:27
    如果只是想要显示圆角的效果,设置 border-radius 就可以了,但如果要让 canvas 合成的图片显示为圆角,这种 css 方式不行。这是示例,扫描访问二维码如下。 在网上查询资料,发现同样的问题,解决的方式是用 ...
  • html2canvas 图片合成模糊问题解决

    万次阅读 热门讨论 2018-06-20 14:28:54
    做项目时,用到了html2canvas来...网上找了下方法,主要是通过把canvas容器扩大,再将和成的图片进行缩放。具体的代码: getCanvasImg(obj){ var doc = window.document; var width = obj.content.offsetWi...
  • canvas图片合成模糊变清晰的方法

    千次阅读 2019-03-15 09:54:38
    昨天刚刚发现之前合成的图片不是很清晰,就上网上找了一下关于canvas图片清晰度的问题,然后刚刚解决就附上部分的对比代码,希望可以帮助和我一样遇到这个问题的朋友 &lt;div class="content" style=...
  • html2canvas 图片合成模糊以及保存为图片背景图丢失问题解决 注意 作为背景的图片必须放在服务器,存放在本地会出现截图的时候背景图丢失的问题; 背景图必须放在img里面里面,通过定位处理成和背景一样,否则会可能出现...
  • <div id="canvasImg"> ... ... ... </div> 引入html2canvas.js就不在多说了,直接使用。 html2canvas(document.querySelector("#capture")).then(canvas => { ...
  • 几个用于前端canvas图片查看编辑的js插件 1 tui.image-editor 2 Konva 3 AlloyImage 4 zwibbler 5 canvasPS 6 Photo Editor 1 tui.image-editor https://nhn.github.io/tui.image-editor/latest/ tui.image-editor:...
  • Canvas 图片平铺设置

    2019-10-26 18:04:37
    /** * 图片平铺 */ function initDemo7(){ var canvas = document.getElementById("demo7"); if (!ca...
  • canvas图片问题 做的一个项目需要将两张图片合成一张图片输出,想到可以用canvas来实现图片的合成 var self = this; var codeImg = document.getElementById("qrcode").getElementsByTagName("img")[0]; var bgImg ...
  • Canvas图片模糊效果(学习笔记)

    千次阅读 2017-02-15 17:55:19
    Canvas图片模糊效果学习视频:http://www.imooc.com/learn/601 Demo和学习笔记 index.html canvas玩儿转红包照片 <!-- 手机端适配 --> content="height=device-height, width=device-width,
  • 求段代码,画布canvas图片绕中心转。 即抽奖箭头(是张图片),不用写背景,只需要这个箭头绕中心转就好。起点为12点钟,每格36度,转三圈后到第二格(1-2点钟的位置)停下就可以了。 在线等
  • 手机上调试canvas转化成图片是空白的,canvas没有内容。望大神们驻足帮助一下
  • canvas图片加圆角

    2020-09-04 20:27:59
    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>...canvas
  • 很多情况下用户上传的图片都需要经过裁剪,比如头像啊什么的。但以前实现这类需求都很复杂,往往需要先把图片上传到服务器,然后返回给用户,让用户确定裁剪坐标,发送给服务器,服务器裁剪完再返回给用户,来回需要...
  • canvas图片跨域问题

    2017-11-25 14:47:00
    canvas的drawImage使用跨域图片时候,会报错,解决方法如下: 1. 使用base64替换跨域图片 如果图片不大,且只有几张,可以使用base64,来代替跨域引用图片。 2. 设置image的crossOrigin属性,并且设置服务端的...
  • Canvas 图片切割 语法: ctx.clip(); 从画布中剪切任意形状和尺寸。 需要注意的是: 剪切之后,除设定Canvas “状态” 外, 一般都会在裁剪后的图形里绘制。 这个不难理解,直接来个示例代码吧: ...
  • canvas图片滚轮放大缩小

    千次阅读 2018-11-27 18:16:19
    &lt;canvas id="canvas" style="display: block;margin: 0 auto;border: 1px solid #ccc;"... 你的浏览器不支持canvas ... let canvas = document.querySelectorAll('#canvas')[0] let cont...
  • html2canvas图片截图截屏功能,附demo地址,下载点击:https://github.com/ybx13579...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 15,680
精华内容 6,272
关键字:

canvas图片