美文网首页
canvas image模糊失真

canvas image模糊失真

作者: Shiki_思清 | 来源:发表于2021-09-02 16:43 被阅读0次

    知识点:

    1. pixelRatio拿到当前机型设备的像素比(dpr)

    2. canvas.width 和 canvas.height 是画布本体宽高

    3. https://developer.mozilla.org/zh-CN/docs/Web/API/Canvas_API/Tutorial/Transformations
      scale(x, y)来增减图形(ctx)在 canvas 中的像素数目,对形状,位图进行缩小或者放大。默认情况下,canvas 的 1 个单位为 1 个像素

    4. style或CSS设置的 width 和height ,是画布进行拉伸挤压后展示出来的宽高

    关系

    1. 像素比(dpr)越大,说明该设备高清,如果图片不扩大像素比,那就一定会失真
    2. 先将canvas.width=imgWidth*dpr 画布本体宽高放大 像素比(dpr) 倍数,为图片提供足够的空间
    3. 再将ctx.scale(dpr, dpr) 将画布上的 每一个单位 通过该方法将 像素数目 放大dpr倍
    4. 展示出来的宽高还是需要按照设备宽高来比例设置<canvas style={{ width: imgWidth, height: imgHeight }} />
    5. 最后在画布上绘制图片,宽高也同样以设备的宽高来比例设置
    
    // 1. 首次加载先拿到图片的尺寸
    useEffect(() => {
          // 2. 先拿到图片大小, 来初始化canvas大小
          Taro.getImageInfo({ src: initUrl }).then((res) => {
            const { width, height } = res  // 3. 图片大小
            const devide = width / height   // 4. 真实图片宽高比
            const ww = Taro.getSystemInfoSync().screenWidth   // 5. 屏幕宽
            const hh = Math.round(ww / devide)  // 6. 等比高
    
            console.log('width', width, ww);
            
            dispatch({ type: 'setPaperRect', payload: [ww, hh] })
    
            // 首次
            resetCanvasAndDrawImage(ww, hh, initUrl).then(() => {
              pushDrawStack('common')
            })
          })
        }, [])
    
    // 7. 调用方法,渲染canvas
    const resetCanvasAndDrawImage = (ww: number, hh: number, url: string) => {
          // canvas需要等到宽高确定之后才能开始画图, 此时dom已经渲染完成
          return new Promise<void>((resolve) => {
            const query = Taro.createSelectorQuery()
            query.select('#paper_canvas')
              .fields({ node: true, size: true })
              .exec((res) => {
                // 8. 初始化canvas 2d
                const canvas = res[0].node
                const ctx = canvas.getContext('2d')
                // 9. 重要,拿到像素比
                const dpr = Taro.getSystemInfoSync().pixelRatio
                // 10. 根据像素比放大canvas本体,为后面绘图提供更大空间
                canvas.width = ww * dpr
                canvas.height = hh * dpr
                // 11. 放大每个单位像素比
                ctx.scale(dpr, dpr)
                // 12. canvas展示出来的宽高,还是按照上面获得的比例宽高设置
                setCanvasW(ww)
                setCanvasH(hh)
    
                // 保存 canvas 指针 
                stateSync.current.ctx = ctx
                stateSync.current.canvas = canvas
    
                // 渲染图片
                const image = canvas.createImage()
                image.onload = () => {
                  // 13. 开始绘图图片,图片的展示宽高,与canvas的展示宽高一致就好
                  ctx.drawImage(image, 0, 0, ww, hh)
                  resolve()
                }
                image.src = url
              })
          })
        }
    
    
    <Canvas
              type='2d'
              id='paper_canvas'
              style={{ width: canvasW, height: canvasH }}
            />
    

    相关文章

      网友评论

          本文标题:canvas image模糊失真

          本文链接:https://www.haomeiwen.com/subject/fwqcwltx.html