<head><meta c...">
最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 【实例】canvas之图片区域性选择并下载

    正文概述 掘金(小潘同学)   2021-07-25   573

    【实例】canvas之图片区域性选择并下载

    主要是通过鼠标来对图片进行区域选择,然后将图片进行下载和灰度处理

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>加水印</title>
        <style>
        .container{
            margin-top: 50px;
        }
        .edit{
            display: flex;
            align-items: center;
            justify-content: center;
        }
    
        .edit-item{
            position: relative;
            width: 100px;
            height: 34px;
            background-color: salmon;
            color: #fff;
            line-height: 34px;
            text-align: center;
            border-radius: 5px;
            cursor: pointer;
            margin-right: 20px;
        }
        .edit-item input{
            position: absolute;
            left: 0;
            right: 0;
            bottom: 0;
            top: 0;
            width: 100%;
            height: 100%;
            opacity: 0
        }
        .previwe{
            display: flex;
            align-items: center;
            margin-top: 100px;
        }
    
        canvas{
            width: 800px;
            display: block;
            background-color: #eee;
        }
        img{
            object-fit: contain;
            margin-left: 100px;
        }
        </style>
    </head>
    <body>
        <div class="container">
            <div class="edit">
                <div class="edit-item">
                    <span>上传背景图片</span>
                    <input type="file" id="bgImage">
                </div>
                <div class="edit-item" id="selected">
                    <span>下载选中区域</span>
                </div>
                <div class="edit-item" id="gray">
                    <span>灰度处理</span>
                </div>
            </div>
            <div class="previwe">
                <canvas id="myCanvas" width="800" height="600"></canvas>
                <img src=""  id="showImage">
            </div>
        </div>
    <script src="./utils.js"></script>
    <script>
        let bgImage = document.getElementById('bgImage')
        let selected = document.getElementById('selected')
        let showImage = document.getElementById('showImage')
        let gray = document.getElementById('gray')
        let canvas = document.getElementById('myCanvas')
        let ctx = canvas.getContext('2d')
        let bgImageData = {},selectData = {}
        bgImage.addEventListener('change',waterMarkChange,false)
        
        function waterMarkChange(){
            const file = bgImage.files[0]
            let type = file.type
            if(type.indexOf('image') == -1){
                alert('仅支持图片,请重新上传')
            }
            getImageData(file)
        }
    
    function getImageData(file){
        let image = new Image()
            image.src = window.URL.createObjectURL(file)
            image.onload = function(){
            bgImageData.data = image
            bgImageData.width = image.width
            bgImageData.height = image.height
            let x = canvas.width / 2 - bgImageData.width / 2
            let y = canvas.height / 2 - bgImageData.height / 2
            bgImageData.x = x , bgImageData.y = y
            putImageData()
        }
    }
    
    function putImageData(){
      ctx.clearRect(0,0,canvas.width,canvas.height)
      ctx.drawImage(bgImageData.data,bgImageData.x,bgImageData.y,bgImageData.width,bgImageData.height)
    }
    
    selected.addEventListener('click',function(){
        // 获取canvas中的数据
        if(selectData.data){
            let bas64 = returnImageUrl(selectData.data)
            let blobData = C.dataURLToBlob(bas64)
            C.download(blobData)
        }
    })
    
    gray.addEventListener('click',function(){
        if(selectData.data){
            selectData.data = C.grey_processing(selectData.data)
            showImage.src = returnImageUrl(selectData.data)
        }
    })
    canvas.addEventListener('mousedown',mousedown,false)
    canvas.addEventListener('mousemove',mousemove,false)
    canvas.addEventListener('mouseup',mouseup,false)
    let mouse = C.getMousePosition(canvas)
    let isMoving = false
    let initX = 0,initY = 0
    function mousedown(){
        isMoving = true
        initY = mouse.y
        initX = mouse.x
    }
    
    function mousemove(){
       if(isMoving){
        putImageData()
        ctx.save()
        ctx.strokeStyle = '#fff'
        selectData.width = Math.abs(mouse.x - initX)
        selectData.height = Math.abs(mouse.y - initY)
        if(selectData.width && selectData.height){
            selectData.data = ctx.getImageData(initX,initY,selectData.width,selectData.height)
            showImage.width = selectData.width,showImage.height = selectData.height
            showImage.src = returnImageUrl(selectData.data)
        }
        ctx.strokeRect(initX,initY,selectData.width,selectData.height)
        ctx.restore()
      }
    
    }
    
    function mouseup(){
        isMoving = false
        initY = initX = 0
    }
    
    // 重新生成一个canvas用来下载图片
    function returnImageUrl(data){
        let canvasElm = document.createElement('canvas')
        let ctxElm = canvasElm.getContext('2d')
        canvasElm.width = showImage.width , canvasElm.height = showImage.height
        ctxElm.putImageData(data,0,0)
        return canvasElm.toDataURL('image/png',1)
    
    }
    
    </script>
    </body>
    
    </html>
    

    utils.js

    // 转换坐标
    C.getMousePosition = (el) =>{
            let mouse = {x:0,y:0}
            el.addEventListener('mousemove',(e)=>{
            let {x,y} = C.eventWrapper(e)
            mouse.x = x
            mouse.y = y
        })
        return mouse
    }
    C.eventWrapper = function(e){
        let {pageX, pageY, target} = e
        let {left,top} = target.getBoundingClientRect() // 获取元素相对于视口位置距离
        return {x : pageX - left ,y: pageY - top}
    }
    //下载blob对象数据
    C.download = (blob) =>{
        // 创建一个blob链接
        let url = URL.createObjectURL(blob)
        let a = document.createElement('a')
        a.setAttribute('download', url)
        a.href=url ;
        a.style.display = 'none'
        a.click()
        // 每次调用URL.createObjectURL,都会创建一个新的URL对象,浏览器内存中会保持对该对象的引用
        // 只有在document销毁时,才会释放此部分内存
        // 在考虑性能的情况下,在url使用结束后,最好释放此部分内存
        URL.revokeObjectURL(url)
    }
    
    // 将base64转换成blob对象
    C.dataURLToBlob = (code)=> {
        let parts = code.split(';base64,')
        let contentType = parts[0].split(':')[1]
        let raw = window.atob(parts[1])
        let rawLength = raw.length
        let uInt8Array = new Uint8Array(rawLength)
        for(let i = 0; i < rawLength; ++i) {
            uInt8Array[i] = raw.charCodeAt(i)
        }
        return new Blob([uInt8Array], {
            type: contentType
        })
    }
    
    // 对图片数据进行灰度处理
    C.grey_processing = (imageData) =>{
        let data = imageData.data
        for(let i = 0; i < data.length ; i+=4){
        let avg = 0
        avg = (data[i]+data[i+1]+data[i+2]) / 3
            data[i] = data[i+1] = data[i+2] = avg
        }
        return imageData
    }
    

    步骤

    • 图片上传现在到canvas上,显示图片
      • drawImage来将获取到的图片会知道canvas上
    • 在利用鼠标和canvas进行交互区域选择,获取到图片数据
      • 主要是利用mouseup|mousemove|mousedown事件来进行事件交互
      • 利用putImageData|getImageData来实现获取区域性的图像数据

    起源地下载网 » 【实例】canvas之图片区域性选择并下载

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元