1. 最开始本人是用的taro-code这个包生成的二维码,代码如下

import appState from "@@/store"
import { Collapse, Empty, FixedView, Loading } from "@taroify/core"
import { View, Image } from "@tarojs/components"
import Taro, { getSetting, authorize, } from "@tarojs/taro"
import styles from './index.module.scss'
import { ArrowDown, ArrowUp, ArrowLeft } from "@taroify/icons"
import { useRequest } from "taro-hooks"
import { generateInviteCode } from "@/api/inviteCode"
import { QRCode } from 'taro-code'
import { copy2Clipboard } from "@/utils/clipboard"
import dayjs from 'dayjs'
import './index.scss'

import {
  saveImageToPhotosAlbum,
  getFileSystemManager,
  base64ToArrayBuffer,
  env,
} from "@tarojs/taro";
import { listSubSummary } from "@/api/record"

export default () => {
  const { globalData } = Taro.getApp();

  const images = appState.images;

  const ref = useRef<any>();
  const [value, setValue] = useState('');
  const { data: code, loading } = useRequest(generateInviteCode, {
    onSuccess: (res) => {
      if (!res) {
        Taro.showModal({
          title: '提示',
          content: '当前暂无权限,请联系管理员',
          showCancel: false,
        })
      }
    },
  });

  const handleWriteFile = useCallback(() => {
    console.log('ref.current', ref.current)
    const { src } = ref.current.childNodes[0].props;
    // 移除"data:image/png;base64,"前缀
    const base64WithoutPrefix = src.replace(/^data:image\/\w+;base64,/, '');
    // 解码base64字符串到二进制数据
    const buffer = base64ToArrayBuffer(base64WithoutPrefix);
    const filePath = `${env.USER_DATA_PATH}/${Date.now()}.jpg`; // base64是gif格式data:image/gif;base64,R0lGOD,
    const { writeFile } = getFileSystemManager();
    // 写入 获得文件路径
    writeFile({
      data: buffer,
      filePath,
      encoding: "binary",
      success: () => {
        //存入相册
        saveImageToPhotosAlbum({
          filePath,
          success: (res) => {
            console.log('writeFile res: ', res);
            console.log("👏");
            Taro.showToast({
              title: '保存成功',
              icon: 'none'
            })
          },
        });
      },
      fail: (err) => {
        console.error(err);
      },
    });
  }, []);


  const handleSaveCode = useCallback(() => {
    getSetting({
      success: function ({ authSetting }) {
        //没有权限则申请
        if (!authSetting["scope.writePhotosAlbum"]) {
          authorize({
            scope: "scope.writePhotosAlbum",
            success: () => {
              //存储二维码
              handleWriteFile();
            },
          });
        } else handleWriteFile();
      },
    });
  }, []);

  
  return (
    <View className={styles['qrcode-box']} ref={ref}>
        <QRCode
          text={`https://×××.cn/code?distributionCode=${code}`}
          size={190}
          scale={4}
          errorCorrectLevel='M'
          typeNumber={2}
        />
      </View>
      <View className={styles['qrcode-but']}>
        <View className={styles['qrcode-but__item']} onClick={() => {
          copy2Clipboard(code || '')
        }}>
          <Image src={images['distribution-copy-icon']} />
          <View>复制邀请码</View>
        </View>
        <View className={styles['qrcode-but__item']} onClick={handleSaveCode}>
          <Image src={images['distribution-save-icon']} />
          <View>保存二维码</View>
        </View>
      </View>
  )
}

但是打包后小程序体验版后小程序可以下载二维码图片,但是线上图片是gif格式,并且很多机型都不支持转发给朋友,截图如下:

然后调试发现,该图片本质是base64的图片,并且前缀是data:image/gif;base64,...开头的字符串生成的,哪怕我在上面代码中使用base64ToArrayBuffer转换成二进制在保存为jpg或者png格式文件,最后在小程序打包后运行后将二维码保存在手机,显示格式还是gif(虽然电脑端可以保存为png格式图片)。

2.没有办法,只能借鉴另外一个项目中的代码,代码如下:

import appState from "@@/store"
import { Collapse, Empty, FixedView, Loading } from "@taroify/core"
import { View, Image , Canvas } from "@tarojs/components"
import Taro, { getSetting, authorize, } from "@tarojs/taro"
import styles from './index.module.scss'
import { ArrowDown, ArrowUp, ArrowLeft } from "@taroify/icons"
import { useRequest } from "taro-hooks"
import { generateInviteCode } from "@/api/inviteCode"
import { copy2Clipboard } from "@/utils/clipboard"
import dayjs from 'dayjs'
import './index.scss'
import drawQrcode from 'weapp-qrcode';

import {
  saveImageToPhotosAlbum,
} from "@tarojs/taro";
import { listSubSummary } from "@/api/record"

export default () => {
  const { globalData } = Taro.getApp();

  const images = appState.images;

  const ref = useRef<any>();
  const [value, setValue] = useState('');
  const [tempFilePath, setTempFilePath] = useState('');
  const { data: code, loading } = useRequest(generateInviteCode, {
    onSuccess: (res) => {
      console.log('generateInviteCode res: ', res);
      const distributionCode = res
      console.log('distributionCode: ', distributionCode);
      if (!res) {
        Taro.showModal({
          title: '提示',
          content: '当前暂无权限,请联系管理员',
          showCancel: false,
        })
      }
      Taro.getSystemInfo().then((res) => {
        console.log('getSystemInfo res: ', res);
        const scale = res.screenWidth / 375;
        drawQrcode({
          width: 200 * scale,
          height: 200 * scale,
          canvasId: 'myQrcode',
          _this: ref,
          text: `https://×××.cn/code?distributionCode=${distributionCode}`,
        });
        setTimeout(() => {
          Taro.canvasToTempFilePath({
            canvasId: 'myQrcode',
            success(res: any) {
              console.log('Taro.canvasToTempFilePath res: ', res);
              setTempFilePath(res.tempFilePath)
            }
          })
        }, 1000);
      });
    },
  });

  const handleWriteFile = () => {
    console.log('tempFilePath', tempFilePath)
     //存入相册
     // 踩坑!!!微信开发工具会报错,无法保存,但是打包后能正常保存图片,就不会报错,不要一直在开发工具上调试,要打包看
     // {"errMsg":"saveImageToPhotosAlbum:fail no such file or directory http://tmp/XTC0JqAPxaDyc85d680aafd9bba175e0504de55a3f7c.png"}
     saveImageToPhotosAlbum({
      filePath: tempFilePath,
      success: (res) => {
        console.log('writeFile res: ', res);
        console.log("👏");
        Taro.showToast({
          title: '保存成功',
          icon: 'none'
        })
      },
    });
  }


  const handleSaveCode = () => {
    getSetting({
      success: function ({ authSetting }) {
        //没有权限则申请
        if (!authSetting["scope.writePhotosAlbum"]) {
          authorize({
            scope: "scope.writePhotosAlbum",
            success: () => {
              //存储二维码
              handleWriteFile();
            },
          });
        } else handleWriteFile();
      },
    });
  }


  return (
    <View className={styles['qrcode-box']}>
        <Canvas ref={ref} className={styles['canvas']} canvasId='myQrcode' id='myQrcode' />
      </View>
      <View className={styles['qrcode-but']}>
        <View className={styles['qrcode-but__item']} onClick={() => {
          copy2Clipboard(code || '')
        }}>
          <Image src={images['distribution-copy-icon']} />
          <View>复制邀请码</View>
        </View>
        <View className={styles['qrcode-but__item']} onClick={handleSaveCode}>
          <Image src={images['distribution-save-icon']} />
          <View>保存二维码</View>
        </View>
      </View>
  )
}

代码中用的是weapp-qrcode,底层原来是用canvas绘制二维码,然后调用canvasToTempFilePath将二维码保存为图片文件,默认格式是png格式,需要了解详情可以看下微信这接口的文档。但是本人在微信开发工具调试的时候一直无法保存图片,报错如下:

没有办法,只能在问AI,AI的回答就是让我不断的补漏洞。把各种可能的原因都考虑到了,网上不断搜索也没解决。耽误了我一天,把我心态都搞崩了。最后到了下班时间,想着打个包看下微信体验版会不会就不报错了,抱着最后一丝希望,打包后居然不报错能正确保存为png格式的图片,并且能转发给朋友。我崩溃的心,终于被解救了。这次给我的教训很大,就是不要太相信微信开发工具,之前凡是微信开发工具运行不了的功能,打包后也运行不了。于是犯了经验主义错误。以后如果再遇到开发工具一直运行不了的情况,先打个包或者启用真机调试。

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐