分享uniapp canvas动态生成海报 二维码

 

<template>
  <view class="p-20">
    <view class="flex flex-wrap">
      <view v-for="(item,index) in 50" :key="index" class="w-1/2 relative p-10">
        <view class="rounded-20 overflow-hidden">
          <uv-image height="550rpx" src="https://cdn.uviewui.com/uview/album/1.jpg"
                    width="100%"></uv-image>
        </view>
        <view class="flex absolute bottom-40 left-1/2 items-center pt-20" style="transform: translateX(-50%)">
          <view class="w-120">
            <xxz-button size="mini" text="分享" @ok="handleShare"></xxz-button>
          </view>
        </view>
      </view>
    </view>
    <uv-popup ref="popup" bgColor="none" mode="center" @change="change">
      <view class="rounded-20 overflow-hidden" style="height: 80vh;width: 80vw">
        <view class="w-full" style="height: 80%">
          <uv-image height="100%" src="https://cdn.uviewui.com/uview/album/1.jpg"
                    width="100%"></uv-image>
        </view>
        <view class="bg-white p-30">
          <view class="flex justify-between">
            <view class="relative">
              <view>王德发</view>
              <view>151******888</view>
              <view class="w-100 absolute bottom-20">
                <xxz-button size="mini" text="保存相册" @ok="saveImg"/>
              </view>
            </view>
            <view>
              <uv-image height="180rpx" src="https://cdn.uviewui.com/uview/album/1.jpg"
                        width="180rpx"></uv-image>
            </view>
          </view>
        </view>
      </view>
    </uv-popup>
    <view class="relative" style="width: 100vw;overflow: hidden">
      <!-- 画布 -->
      <canvas canvas-id="myCanvas"
              style="width: 750rpx;height: 1300rpx;position: absolute;opacity: 0;left:100%"></canvas>
    </view>
  </view>
</template>

<script lang="ts" setup>
import {onMounted, ref} from "vue";

/**
 * 画布
 */
const ctx: any = ref('')
const img1Path = ref('https://cdn.uviewui.com/uview/album/1.jpg') // 图片背景路径
const img2Path = ref('https://cdn.uviewui.com/uview/album/1.jpg') // 图片二维码路径
const powerW: any = ref('')

// 点击-保存海报
const saveImg = async () => {
  // 调用合并图片的方法。
  mergeImages();
}

// 合并图片的方法
const mergeImages = async () => {
  // 加载第一张图片到canvas上
  const image1 = await loadImage(img1Path.value);
  // 背景色
  ctx.value.setFillStyle('#ffffff')
  ctx.value.fillRect(0, 0, 999, 999)
  // 在(0,0)位置绘制图片1,图一宽高分别为345px和334px
  ctx.value.drawImage(image1, 0, 0, 375 * powerW.value, 500 * powerW.value);

  // 加载第二张图片到canvas上,并设置位置和大小(根据需要调整)
  const image2 = await loadImage(img2Path.value);

  // 在(10,209)位置绘制图片2,图片二宽高75px,可以根据需要调整位置和大小
  ctx.value.drawImage(image2, 270 * powerW.value, 520 * powerW.value, 90 * powerW.value, 90 * powerW.value);

  // 设置字体样式
  // this.ctx.font = '8px Arial';
  ctx.value.font = `bold ${(18 * powerW.value).toFixed(0)}px Arial`;
  ctx.value.fillStyle = '#000000'; // 设置填充颜色

  // 在 Canvas 上绘制文字
  // 第二个和第三个参数是文字的 x 和 y 坐标
  ctx.value.fillText('王德发', 20 * powerW.value, 540 * powerW.value);

  ctx.value.font = `${(16 * powerW.value).toFixed(0)}px Arial`;
  ctx.value.fillStyle = '#000000'; // 设置填充颜色
  ctx.value.fillText('15245822325', 20 * powerW.value, 565 * powerW.value);

  ctx.value.font = `${(14 * powerW.value).toFixed(0)}px Arial`;
  ctx.value.fillStyle = '#000000'; // 设置填充颜色
  ctx.value.fillText('【扫一扫识别二维码】', 15 * powerW.value, 600 * powerW.value);

  // 完成绘制并导出为图片(可选)
  ctx.value.draw(true, () => {
    // 这里可以处理合并后的图片,比如保存到相册或上传到服务器等操作。
    // 如果需要导出为文件或上传等操作,可以使用uni.canvasToTempFilePath等方法。
    uni.canvasToTempFilePath({// res.tempFilePath临时路径
      canvasId: 'myCanvas',
      success: (res) => {
        console.log(res, '临时路径');
        uni.saveImageToPhotosAlbum({ // 保存本地
          filePath: res.tempFilePath,
          success: (response) => {
            uni.showToast({
              title: '保存成功',
              icon: 'success'
            })
            console.log(response, 'success');
          },
          fail: (response) => {
            console.log(response, 'error');
            uni.openSetting({ //打开权限
              success: (response) => {
                if (!response.authSetting['scope.writePhotosAlbum']) {
                  uni.showToast({
                    title: '获取权限成功, 再次点击即可保存',
                    icon: 'none'
                  })
                } else {
                  uni.showToast({
                    title: '获取权限失败, 无法保存',
                    icon: 'none'
                  })
                }
              }
            })
          }
        })
      }
    })
  });
}
// 注:canvas绘图在开发者工具上支持base64图片,在真机上是不可以的,
// 需让后台返回图片网络链接通过getimageinfo方法获取临时路径再进行操作
const loadImage = (src) => {
  return new Promise((resolve, reject) => {
    uni.getImageInfo({
      src: src, // 图片的URL或临时文件路径
      success: (res) => {
        console.log(res, 1.5);
        // 获取图片的本地路径或临时文件路径,用于在canvas上绘制。
        resolve(res.path);
      },
      fail: reject, // 处理加载失败的情况。
    });
  });
}


const popup = ref()
const handleShare = () => {
  popup.value.open();
}
const change = (e) => {
  console.log('弹窗状态改变:', e);
}


onMounted(() => {
  powerW.value = uni.getSystemInfoSync().windowWidth / 375;
  // console.log(this.powerW, '宽度比率');
  // 创建画布 初始化canvas上下文
  ctx.value = uni.createCanvasContext('myCanvas');
})
</script>


<style lang="scss" scoped>

</style>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值