uni-app uni.canvasPutImageData 无效

uni-app uni.canvasPutImageData 无效

产品分类:

uniapp/H5

PC开发环境操作系统:

Windows

PC开发环境操作系统版本号:

1

HBuilderX类型:

正式

HBuilderX版本号:

4.57

浏览器平台:

Chrome

浏览器版本:

1

项目创建方式:

HBuilderX

示例代码:

<div class="wrap">  
    <div class="wrap-content">  
        <canvas :style="{'width': canvasWidth + 'px', 'height': canvasHeight + 'px'}" canvas-id="filterCanvas"></canvas>  
    </div>  

    <div class="wrap-bottom">  
        <scroll-view class="wrap-bottom__scroll" scroll-x style="height: 80rpx; padding: 0px; border-top: 2rpx solid #2B3A33; border-bottom: 2rpx solid #2B3A33">  
            <view style="display: inline-block; width: 40rpx"></view>  
            <view @click="filterFn" class="tab-item" :class="{'tab-active': currentIndex === index}" v-for="(item, index) of 20" :key="index">  
                文本  
            </view>  
        </scroll-view>  
        <scroll-view class="wrap-bottom__scroll" scroll-x>  
            <view style="width: 40rpx; display: inline-block"></view>  
            <view class="wrap-bottom__scroll-item" v-for="(item, index) of 20" :key="index">  
                <image src="/static/ico_sound.png" class="wrap-bottom__scroll-icon"></image>  
                <view class="wrap-bottom__scroll-text">紫色</view>  
            </view>  
        </scroll-view>  

        <div class="wrap-bottom__btm">  
            <image src="/static/ico_sound.png" class="wrap-bottom__btm-icon" @click="closeRoteFn"></image>  
            <image src="/static/ico_sound.png" class="wrap-bottom__btm-icon" @click="sureRoteFn"></image>  
        </div>  
    </div>  
</div>  
<script>  
import { nextTick } from 'vue';  

export default {  
  data() {  
    return {  
      ctx: null,  
      canvasWidth: 0,  
      canvasHeight: 0,  
      filterFile: '',  
      imageType: 1, // 1 是横向图片 2 是竖图  
      systemInfo: {},  
      currentIndex: 0  
    };  
  },  
  created() {  
    this.filterFile =uni.getStorageSync('filterFile');  
    uni.showLoading({  
      title: '加载中'  
    });  
    this.initInfo();  
  },  
  mounted() {  
    this.ctx = uni.createCanvasContext('filterCanvas');  
    if (!this.ctx) {  
      console.error('Canvas 上下文初始化失败');  
    } else {  
      this.canvasImageFn();  
    }  
  },  
  methods: {  
    filterFn() {  
      setTimeout(() => {  
        uni.canvasGetImageData({  
          canvasId: 'filterCanvas',  
          x: 0,  
          y: 0,  
          width: this.canvasWidth,  
          height: this.canvasHeight,  
          success: (res) => {  
            console.log(res, "===");  
            // let data = new Uint8ClampedArray(res.data);  
            let data = res.data;  
            for (let i = 0; i < data.length; i += 4) {  
              data[i] = 255 - data[i];     // R  
              data[i + 1] = 255 - data[i + 1]; // G  
              data[i + 2] = 255 - data[i + 2]; // B  
            }  
            uni.canvasPutImageData({  
              canvasId: 'filterCanvas',  
              x: 0,  
              y: 0,  
              width: 1,  
              data: data,  
              success: (res) => {  
                this.ctx.draw();  

                console.log(res, "----");  
                uni.hideLoading();  
              },  
              fail: (e) => {  
                uni.hideLoading();  
                console.log(e, "===");  
              }  
            }, this);  
          }  
        }, this);  
      }, 200)  
    },  
    initInfo() {  
      this.systemInfo = uni.getWindowInfo();  
      console.log(this.filterFile, "this.filterFile");  

      let whVal = uni.getStorageSync('filterWH') || [0, 0]  

      if (whVal[0] >= whVal[1]) {  
        this.imageType = 1;  
        this.canvasWidth = this.systemInfo.screenWidth;  
        this.canvasHeight = whVal[1] * this.systemInfo.screenWidth / whVal[0];  
      } else {  
        this.imageType = 2;  
        this.canvasHeight = whVal[1] / (whVal[1] / (this.systemInfo.screenHeight - 200));  
        this.canvasWidth = whVal[0] / (whVal[1] / (this.systemInfo.screenHeight - 200));  
      }  

      // uni.getImageInfo({  
      //   src: this.filterFile,  
      //   success: (res) => {  
      //     if (res.width >= res.height) {  
      //       this.imageType = 1;  
      //       this.canvasWidth = this.systemInfo.screenWidth;  
      //       this.canvasHeight = res.height * this.systemInfo.screenWidth / res.width;  
      //     } else {  
      //       this.imageType = 2;  
      //       this.canvasHeight = res.height / (res.height / (this.systemInfo.screenHeight - 200));  
      //       this.canvasWidth = res.width / (res.height / (this.systemInfo.screenHeight - 200));  
      //     }  
      //   },  
      //   fail: (e) => {  
      //     console.log(e, "===");  
      //   }  
      // });  
    },  
    canvasImageFn() {  

      setTimeout(() => {  
        this.ctx.drawImage(  
            this.filterFile,  
            0, // 源图像的 x 坐标  
            0, // 源图像的 y 坐标  
            this.canvasWidth, // 源图像的宽度  
            this.canvasHeight // 源图像的高度  
        );  

        this.ctx.draw();  
        uni.hideLoading();  
      }, 500);  
    },  
    closeRoteFn() {  
      uni.navigateBack({});  
    },  
    sureRoteFn() {  
      // 确定按钮逻辑  
    }  
  }  
};  
</script>  

<style lang="scss" scoped>  
.wrap {  
  width: 750rpx;  
  height: 100vh;  
  display: flex;  
  flex-direction: column;  
  overflow: hidden;  
  background-color: #252525;  

  &-bottom {  
    background-color: #060908;  
    width: 750rpx;  

    .tab-item {  
      display: inline-block;  
      margin-right: 20rpx;  
      height: 76rpx;  
      line-height: 76rpx;  
      color: #fff;  
      font-size: 28rpx;  
      position: relative;  
    }  

    .tab-active {  
      &::after {  
        content: '';  
        display: inline-block;  
        width: 75%;  
        height: 2rpx;  
        background-color: #949594;  
        position: absolute;  
        bottom: 12rpx;  
        left: 50%;  
        transform: translateX(-50%);  
      }  
    }  

    &__scroll {  
      width: 750rpx;  
      overflow-x: scroll;  
      box-sizing: border-box;  
      padding: 30rpx 0rpx;  
      white-space: nowrap;  

      &-item {  
        display: inline-block;  
        margin-right: 24rpx;  
      }  

      &-icon {  
        width: 80rpx;  
        height: 80rpx;  
        margin: 0rpx auto 4rpx;  
      }  

      &-text {  
        font-size: 28rpx;  
        color: #fff;  
        text-align: center;  
      }  
    }  

    &__btm {  
      width: 750rpx;  
      height: 90rpx;  
      box-sizing: border-box;  
      padding: 0rpx 40rpx;  
      display: flex;  
      align-items: center;  
      justify-content: space-between;  
      border-top: 1rpx solid #2B3A33;  

      &-icon {  
        width: 40rpx;  
        height: 40rpx;  
        display: block;  
      }  
    }  
  }  

  &-content {  
    flex: 1;  
    display: flex;  
    align-items: center;  
    justify-content: center;  
  }  
}  

.background-image {  
  //position: absolute;  
  //top: 50%;  
  //left: 50%;  
  //transform: translate(-50%, -50%);  
  width: 750rpx;  
  transform-origin: center;  
}  

.background-imageTwo {  
  height: 650rpx;  
  transform-origin: center;  
}
</style>

操作步骤:

  • 点击文字

预期结果:

  • 图片正常滤镜 到画布上

实际结果:

  • 画布为空的

bug描述:

canvasPutImageData 走到success 但是 画布原来的图片直接没了 并没有加滤镜并且绘制到画布


更多关于uni-app uni.canvasPutImageData 无效的实战教程也可以访问 https://www.itying.com/category-93-b0.html

1 回复

更多关于uni-app uni.canvasPutImageData 无效的实战教程也可以访问 https://www.itying.com/category-93-b0.html


根据代码分析,uni.canvasPutImageData无效可能有以下几个原因:

  1. 参数问题:在canvasPutImageData调用中,width参数设置为1,这明显不正确,应该设置为canvasWidth。

  2. 时序问题:canvasPutImageData操作后需要调用ctx.draw()才能生效,虽然代码中有调用,但可能在canvas上下文未准备好时执行。

  3. 数据格式:修改后的ImageData可能需要转换为Uint8ClampedArray。

建议修改filterFn方法如下:

filterFn() {
  setTimeout(() => {
    uni.canvasGetImageData({
      canvasId: 'filterCanvas',
      x: 0,
      y: 0,
      width: this.canvasWidth,
      height: this.canvasHeight,
      success: (res) => {
        let data = new Uint8ClampedArray(res.data);
        for (let i = 0; i < data.length; i += 4) {
          data[i] = 255 - data[i];
          data[i + 1] = 255 - data[i + 1];
          data[i + 2] = 255 - data[i + 2];
        }
        uni.canvasPutImageData({
          canvasId: 'filterCanvas',
          x: 0,
          y: 0,
          width: this.canvasWidth,  // 修改这里
          height: this.canvasHeight,
          data: data,
          success: () => {
            this.ctx.draw();
            uni.hideLoading();
          }
        }, this);
      }
    }, this);
  }, 200)
}
回到顶部