uniapp 生成海报二维码 (微信小程序)

发布于:2025-05-12 ⋅ 阅读:(16) ⋅ 点赞:(0)

先下载qrcodenpm install qrcode

调用
community_poster.vue

	<template>
    <view class="poster-page">
        <uv-navbar title="物业推广码" placeholder autoBack></uv-navbar>

        <view class="community-info">
            <text class="community-name">{{ communityName }}</text>
            <text class="community-desc">扫描下方二维码,绑定物业</text>
        </view>

       <property-poster ref="propertyPosterRef" :communityName="communityName" :bgImages="bgImages" :width="750" :height="668" :size="300" :qrCodeContent="qrCodeContent"
                    @posterGenerated="handlePosterGenerated"></property-poster>
    </view>
</template>

<script lang="ts" setup>
import { ref, onMounted } from 'vue'
import { onLoad } from '@dcloudio/uni-app'
import PropertyPoster from '@/components/propertyPoster/index.vue'
import { localImg } from '@/utils/util'


// 页面参数
const communityId = ref('')
const communityName = ref('小区')
const qrCodeContent = ref('')
const bgImages = ref('')

// 页面加载
onLoad((options: any) => {
    if (options.id) {
        communityId.value = options.id
        // 可以根据ID获取小区信息
        getCommunityInfo(options.id)
    }

    if (options.name) {
        communityName.value = options.name
    }

    // 生成二维码内容
    generateQrCodeContent()
})
function handlePosterGenerated(url: string) {
    console.log('接收到的海报图片路径:', url)
    posterUrl.value = url
}
// 获取小区信息
const getCommunityInfo = async (id: string) => {
    try {
        // 这里可以调用API获取小区详情
        // const res = await getCommunityDetail(id)
        // communityName.value = res.communityName
    } catch (error) {
        console.error('获取小区信息失败:', error)
        uni.showToast({
            title: '获取小区信息失败',
            icon: 'none'
        })
    }
}

// 生成二维码内容
const generateQrCodeContent = () => {
    // 生成二维码内容和背景图,可以是小程序页面路径+参数   自己填写
    qrCodeContent.value = import.meta.env.VITE_APP_BASE_URL + '/admin/Properties/getProperCode/1920001749794516994'
    bgImages.value = localImg('/images/content/community.png')

}
</script>

<style lang="scss" scoped>
.poster-page {
    min-height: 100vh;
    background-color: #F8F8F8;
    padding-bottom: 40rpx;
}

.community-info {
    padding: 30rpx;
    text-align: center;
}

.community-name {
    font-size: 36rpx;
    font-weight: bold;
    color: #333;
    display: block;
    margin-bottom: 10rpx;
}

.community-desc {
    font-size: 28rpx;
    color: #666;
}
</style>

组件
components/propertyPoster/index.vue

<template>
    <view class="poster-container">
        <!-- 海报预览区域 -->
        <view class="poster-preview" v-if="posterUrl">
            <image :src="posterUrl" mode="widthFix" class="poster-image" @error="handleImageError"
                :style="{ width: canvasWidth + 'rpx', height: canvasHeight + 'rpx' }" />
        </view>

        <!-- 隐藏的Canvas -->
        <view class="canvas-container">
            <canvas canvas-id="posterCanvas" id="posterCanvas" class="poster-canvas"
                :style="{ width: canvasWidth + 'px', height: canvasHeight + 'px' }" />
            <canvas canvas-id="qrcodeCanvas" id="qrcodeCanvas" class="qrcode-canvas"
                :style="{ width: size + 'px', height: size + 'px' }" />
        </view>
    </view>
</template>

<script lang="ts" setup>
import { ref, onUnmounted, getCurrentInstance, nextTick } from 'vue'
import { storeToRefs } from 'pinia'
import { onReady } from '@dcloudio/uni-app'
import uQRCode from '@/utils/uqrcode.js'
import { useUserStore } from '@/stores/user'

type ErrorType = 'download' | 'canvas' | 'qrcode' | 'save' | 'unknown'

// 定义组件属性
const props = defineProps({
    communityName: {
        type: String,
        default: '幸福家园小区'
    },
    qrCodeContent: {
        type: String,
        required: true
    },
    bgImages: {
        type: String,
        required: true
    },
    bgColor: {
        type: String,
        default: '#ffffff'
    },
    width: {
        type: Number,
        default: 750
    },
    height: {
        type: Number,
        default: 1200
    },
    size: {
        type: Number,
        default: 400
    }
})

const emits = defineEmits(['posterGenerated'])

// 获取用户信息和应用信息
const userStore = useUserStore()
const { userInfo } = storeToRefs(userStore)
const instance = getCurrentInstance()

// 海报相关参数
const canvasWidth = ref(props.width)
const canvasHeight = ref(props.height)
const posterUrl = ref('')
const generating = ref(false)

// 图片加载失败处理
const handleImageError = () => {
    showToast('图片加载失败')
}

/**
 * 下载图片资源
 */
const downloadImage = async (url: string): Promise<string> => {
    try {
        const res = await uni.downloadFile({ url })
        if (res.statusCode === 200) {
            return res.tempFilePath
        }
        throw new Error(`下载失败(${res.statusCode})`)
    } catch (error) {
        throw new Error(`图片下载失败: ${error.message || error}`)
    }
}

/**
 * 生成二维码并返回临时路径
 */
const generateQRCode = async (): Promise<string> => {
    return new Promise((resolve, reject) => {
        uQRCode.make({
            canvasId: 'qrcodeCanvas',
            componentInstance: instance?.proxy,
            text: props.qrCodeContent,
            size: props.size,
            margin: 10,
            success: resolve,
            fail: (err) => reject(new Error(`二维码生成失败: ${err}`))
        })
    })
}

/**
 * 将Canvas转换为临时文件路径
 */
const canvasToTempFile = (canvasId: string): Promise<string> => {
    return new Promise((resolve, reject) => {
        uni.canvasToTempFilePath({
            canvasId,
            destWidth: canvasWidth.value * 2, // 提高清晰度
            destHeight: canvasHeight.value * 2,
            success: (res) => resolve(res.tempFilePath),
            fail: (err) => reject(new Error(`Canvas转换失败: ${err.errMsg || err}`))
        }, instance?.proxy)
    })
}

/**
 * 绘制海报内容
 */
const drawPosterContent = async (ctx: UniApp.CanvasContext) => {
    // 绘制背景
    ctx.setFillStyle(props.bgColor)
    ctx.fillRect(0, 0, canvasWidth.value, canvasHeight.value)

    // 绘制背景图片
    const bgImagePath = await downloadImage(props.bgImages)
    ctx.drawImage(bgImagePath, 0, 0, canvasWidth.value, canvasHeight.value)

    // 绘制小区名称
    if (props.communityName) {
        ctx.setFillStyle('#FFFFFF')
        ctx.setFontSize(30)
        const textWidth = ctx.measureText(props.communityName).width
        const x = (canvasWidth.value - textWidth) / 2
        ctx.fillText(props.communityName, x, 120)
    }

    // 生成并绘制二维码
    const qrSize = props.size
    const qrX = (canvasWidth.value - qrSize) / 2
    const qrY = (canvasHeight.value - qrSize) / 2

    const qrCodePath = await generateQRCode()
    ctx.drawImage(qrCodePath, qrX, qrY, qrSize, qrSize)
}

/**
 * 执行Canvas绘制
 */
const executeCanvasDraw = (ctx: UniApp.CanvasContext): Promise<void> => {
    return new Promise((resolve) => {
        ctx.draw(false, () => {
            setTimeout(resolve, 300) // 确保绘制完成
        })
    })
}

/**
 * 显示提示信息
 */
const showToast = (message: string, icon: UniApp.ShowToastOptions['icon'] = 'none') => {
    uni.showToast({ title: message, icon })
}

/**
 * 生成海报主函数
 */
const generatePoster = async () => {
    if (generating.value) return
    generating.value = true
    uni.showLoading({ title: '生成中...', mask: true })

    try {
        // 创建Canvas上下文
        const ctx = uni.createCanvasContext('posterCanvas', instance?.proxy)
        if (!ctx) {
            throw new Error('获取Canvas上下文失败')
        }

        // 绘制海报内容
        await drawPosterContent(ctx)

        // 执行绘制
        await executeCanvasDraw(ctx)

        // 转换为临时文件
        posterUrl.value = await canvasToTempFile('posterCanvas')
        emits('posterGenerated', posterUrl.value)

        showToast('生成成功')
    } catch (error) {
        console.error('生成海报失败:', error)
        showToast('生成海报失败')
    } finally {
        generating.value = false
        uni.hideLoading()
    }
}

/**
 * 保存海报到相册
 */
const savePoster = async () => {
    if (!posterUrl.value) {
        showToast('请先生成海报')
        return
    }

    try {
        await uni.saveImageToPhotosAlbum({
            filePath: posterUrl.value
        })
        showToast('保存成功', 'success')
    } catch (error) {
        if (error.errMsg.includes('auth deny') || error.errMsg.includes('authorize no response')) {
            uni.showModal({
                title: '提示',
                content: '需要您授权保存图片到相册',
                success: (res) => res.confirm && uni.openSetting()
            })
        } else {
            showToast(`保存失败: ${error.errMsg || error}`)
        }
    }
}

// 暴露方法给父组件
defineExpose({
    savePoster,
    generatePoster
})

// 组件挂载后自动生成海报
onReady(() => {
    nextTick(() => {
        generatePoster()
    })
})

// 页面卸载时清理资源
onUnmounted(() => {
    if (posterUrl.value) {
        // #ifdef MP-WEIXIN
        uni.removeSavedFile({
            filePath: posterUrl.value,
            complete: () => console.log('临时文件已清理')
        })
        // #endif
    }
})
</script>

<style lang="scss" scoped>
.poster-container {
    padding: 20rpx;
    display: flex;
    flex-direction: column;
    align-items: center;
}

.poster-preview {
    margin: 30rpx auto;
    width: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
}

.poster-image {
    width: 100%;
    box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.1);
    border-radius: 20rpx;
}

.canvas-container {
    position: fixed;
    left: -9999px;
    top: -9999px;
    z-index: -1;
    opacity: 0;
}

.poster-canvas,
.qrcode-canvas {
    position: absolute;
}
</style>

uqrcode.js

//---------------------------------------------------------------------
// github https://github.com/Sansnn/uQRCode
//---------------------------------------------------------------------

let uQRCode = {}

    ; (function () {
        //---------------------------------------------------------------------
        // QRCode for JavaScript
        //
        // Copyright (c) 2009 Kazuhiko Arase
        //
        // URL: http://www.d-project.com/
        //
        // Licensed under the MIT license:
        //   http://www.opensource.org/licenses/mit-license.php
        //
        // The word "QR Code" is registered trademark of
        // DENSO WAVE INCORPORATED
        //   http://www.denso-wave.com/qrcode/faqpatent-e.html
        //
        //---------------------------------------------------------------------

        //---------------------------------------------------------------------
        // QR8bitByte
        //---------------------------------------------------------------------

        function QR8bitByte(data) {
            this.mode = QRMode.MODE_8BIT_BYTE
            this.data = data
        }

        QR8bitByte.prototype = {
            getLength: function (buffer) {
                return this.data.length
            },

            write: function (buffer) {
                for (var i = 0; i < this.data.length; i++) {
                    // not JIS ...
                    buffer.put(this.data.charCodeAt(i), 8)
                }
            },
        }

        //---------------------------------------------------------------------
        // QRCode
        //---------------------------------------------------------------------

        function QRCode(typeNumber, errorCorrectLevel) {
            this.typeNumber = typeNumber
            this.errorCorrectLevel = errorCorrectLevel
            this.modules = null
            this.moduleCount = 0
            this.dataCache = null
            this.dataList = []
        }

        QRCode.prototype = {
            addData: function (data) {
                var newData = new QR8bitByte(data)
                this.dataList.push(newData)
                this.dataCache = null
            },

            isDark: function (row, col) {
                if (row < 0 || this.moduleCount <= row || col < 0 || this.moduleCount <= col) {
                    throw new Error(row + ',' + col)
                }
                return this.modules[row][col]
            },

            getModuleCount: function () {
                return this.moduleCount
            },

            make: function () {
                // Calculate automatically typeNumber if provided is < 1
                if (this.typeNumber < 1) {
                    var typeNumber = 1
                    for (typeNumber = 1; typeNumber < 40; typeNumber++) {
                        var rsBlocks = QRRSBlock.getRSBlocks(typeNumber, this.errorCorrectLevel)

                        var buffer = new QRBitBuffer()
                        var totalDataCount = 0
                        for (var i = 0; i < rsBlocks.length; i++) {
                            totalDataCount += rsBlocks[i].dataCount
                        }

                        for (var i = 0; i < this.dataList.length; i++) {
                            var data = this.dataList[i]
                            buffer.put(data.mode, 4)
                            buffer.put(data.getLength(), QRUtil.getLengthInBits(data.mode, typeNumber))
                            data.write(buffer)
                        }
                        if (buffer.getLengthInBits() <= totalDataCount * 8) break
                    }
                    this.typeNumber = typeNumber
                }
                this.makeImpl(false, this.getBestMaskPattern())
            },

            makeImpl: function (test, maskPattern) {
                this.moduleCount = this.typeNumber * 4 + 17
                this.modules = new Array(this.moduleCount)

                for (var row = 0; row < this.moduleCount; row++) {
                    this.modules[row] = new Array(this.moduleCount)

                    for (var col = 0; col < this.moduleCount; col++) {
                        this.modules[row][col] = null //(col + row) % 3;
                    }
                }

                this.setupPositionProbePattern(0, 0)
                this.setupPositionProbePattern(this.moduleCount - 7, 0)
                this.setupPositionProbePattern(0, this.moduleCount - 7)
                this.setupPositionAdjustPattern()
                this.setupTimingPattern()
                this.setupTypeInfo(test, maskPattern)

                if (this.typeNumber >= 7) {
                    this.setupTypeNumber(test)
                }

                if (this.dataCache == null) {
                    this.dataCache = QRCode.createData(this.typeNumber, this.errorCorrectLevel, this.dataList)
                }

                this.mapData(this.dataCache, maskPattern)
            },

            setupPositionProbePattern: function (row, col) {
                for (var r = -1; r <= 7; r++) {
                    if (row + r <= -1 || this.moduleCount <= row + r) continue

                    for (var c = -1; c <= 7; c++) {
                        if (col + c <= -1 || this.moduleCount <= col + c) continue

                        if (
                            (0 <= r && r <= 6 && (c == 0 || c == 6)) ||
                            (0 <= c && c <= 6 && (r == 0 || r == 6)) ||
                            (2 <= r && r <= 4 && 2 <= c && c <= 4)
                        ) {
                            this.modules[row + r][col + c] = true
                        } else {
                            this.modules[row + r][col + c] = false
                        }
                    }
                }
            },

            getBestMaskPattern: function () {
                var minLostPoint = 0
                var pattern = 0

                for (var i = 0; i < 8; i++) {
                    this.makeImpl(true, i)

                    var lostPoint = QRUtil.getLostPoint(this)

                    if (i == 0 || minLostPoint > lostPoint) {
                        minLostPoint = lostPoint
                        pattern = i
                    }
                }

                return pattern
            },

            createMovieClip: function (target_mc, instance_name, depth) {
                var qr_mc = target_mc.createEmptyMovieClip(instance_name, depth)
                var cs = 1

                this.make()

                for (var row = 0; row < this.modules.length; row++) {
                    var y = row * cs

                    for (var col = 0; col < this.modules[row].length; col++) {
                        var x = col * cs
                        var dark = this.modules[row][col]

                        if (dark) {
                            qr_mc.beginFill(0, 100)
                            qr_mc.moveTo(x, y)
                            qr_mc.lineTo(x + cs, y)
                            qr_mc.lineTo(x + cs, y + cs)
                            qr_mc.lineTo(x, y + cs)
                            qr_mc.endFill()
                        }
                    }
                }

                return qr_mc
            },

            setupTimingPattern: function () {
                for (var r = 8; r < this.moduleCount - 8; r++) {
                    if (this.modules[r][6] != null) {
                        continue
                    }
                    this.modules[r][6] = r % 2 == 0
                }

                for (var c = 8; c < this.moduleCount - 8; c++) {
                    if (this.modules[6][c] != null) {
                        continue
                    }
                    this.modules[6][c] = c % 2 == 0
                }
            },

            setupPositionAdjustPattern: function () {
                var pos = QRUtil.getPatternPosition(this.typeNumber)

                for (var i = 0; i < pos.length; i++) {
                    for (var j = 0; j < pos.length; j++) {
                        var row = pos[i]
                        var col = pos[j]

                        if (this.modules[row][col] != null) {
                            continue
                        }

                        for (var r = -2; r <= 2; r++) {
                            for (var c = -2; c <= 2; c++) {
                                if (r == -2 || r == 2 || c == -2 || c == 2 || (r == 0 && c == 0)) {
                                    this.modules[row + r][col + c] = true
                                } else {
                                    this.modules[row + r][col + c] = false
                                }
                            }
                        }
                    }
                }
            },

            setupTypeNumber: function (test) {
                var bits = QRUtil.getBCHTypeNumber(this.typeNumber)

                for (var i = 0; i < 18; i++) {
                    var mod = !test && ((bits >> i) & 1) == 1
                    this.modules[Math.floor(i / 3)][(i % 3) + this.moduleCount - 8 - 3] = mod
                }

                for (var i = 0; i < 18; i++) {
                    var mod = !test && ((bits >> i) & 1) == 1
                    this.modules[(i % 3) + this.moduleCount - 8 - 3][Math.floor(i / 3)] = mod
                }
            },

            setupTypeInfo: function (test, maskPattern) {
                var data = (this.errorCorrectLevel << 3) | maskPattern
                var bits = QRUtil.getBCHTypeInfo(data)

                // vertical
                for (var i = 0; i < 15; i++) {
                    var mod = !test && ((bits >> i) & 1) == 1

                    if (i < 6) {
                        this.modules[i][8] = mod
                    } else if (i < 8) {
                        this.modules[i + 1][8] = mod
                    } else {
                        this.modules[this.moduleCount - 15 + i][8] = mod
                    }
                }

                // horizontal
                for (var i = 0; i < 15; i++) {
                    var mod = !test && ((bits >> i) & 1) == 1

                    if (i < 8) {
                        this.modules[8][this.moduleCount - i - 1] = mod
                    } else if (i < 9) {
                        this.modules[8][15 - i - 1 + 1] = mod
                    } else {
                        this.modules[8][15 - i - 1] = mod
                    }
                }

                // fixed module
                this.modules[this.moduleCount - 8][8] = !test
            },

            mapData: function (data, maskPattern) {
                var inc = -1
                var row = this.moduleCount - 1
                var bitIndex = 7
                var byteIndex = 0

                for (var col = this.moduleCount - 1; col > 0; col -= 2) {
                    if (col == 6) col--

                    while (true) {
                        for (var c = 0; c < 2; c++) {
                            if (this.modules[row][col - c] == null) {
                                var dark = false

                                if (byteIndex < data.length) {
                                    dark = ((data[byteIndex] >>> bitIndex) & 1) == 1
                                }

                                var mask = QRUtil.getMask(maskPattern, row, col - c)

                                if (mask) {
                                    dark = !dark
                                }

                                this.modules[row][col - c] = dark
                                bitIndex--

                                if (bitIndex == -1) {
                                    byteIndex++
                                    bitIndex = 7
                                }
                            }
                        }

                        row += inc

                        if (row < 0 || this.moduleCount <= row) {
                            row -= inc
                            inc = -inc
                            break
                        }
                    }
                }
            },
        }

        QRCode.PAD0 = 0xec
        QRCode.PAD1 = 0x11

        QRCode.createData = function (typeNumber, errorCorrectLevel, dataList) {
            var rsBlocks = QRRSBlock.getRSBlocks(typeNumber, errorCorrectLevel)

            var buffer = new QRBitBuffer()

            for (var i = 0; i < dataList.length; i++) {
                var data = dataList[i]
                buffer.put(data.mode, 4)
                buffer.put(data.getLength(), QRUtil.getLengthInBits(data.mode, typeNumber))
                data.write(buffer)
            }

            // calc num max data.
            var totalDataCount = 0
            for (var i = 0; i < rsBlocks.length; i++) {
                totalDataCount += rsBlocks[i].dataCount
            }

            if (buffer.getLengthInBits() > totalDataCount * 8) {
                throw new Error('code length overflow. (' + buffer.getLengthInBits() + '>' + totalDataCount * 8 + ')')
            }

            // end code
            if (buffer.getLengthInBits() + 4 <= totalDataCount * 8) {
                buffer.put(0, 4)
            }

            // padding
            while (buffer.getLengthInBits() % 8 != 0) {
                buffer.putBit(false)
            }

            // padding
            while (true) {
                if (buffer.getLengthInBits() >= totalDataCount * 8) {
                    break
                }
                buffer.put(QRCode.PAD0, 8)

                if (buffer.getLengthInBits() >= totalDataCount * 8) {
                    break
                }
                buffer.put(QRCode.PAD1, 8)
            }

            return QRCode.createBytes(buffer, rsBlocks)
        }

        QRCode.createBytes = function (buffer, rsBlocks) {
            var offset = 0

            var maxDcCount = 0
            var maxEcCount = 0

            var dcdata = new Array(rsBlocks.length)
            var ecdata = new Array(rsBlocks.length)

            for (var r = 0; r < rsBlocks.length; r++) {
                var dcCount = rsBlocks[r].dataCount
                var ecCount = rsBlocks[r].totalCount - dcCount

                maxDcCount = Math.max(maxDcCount, dcCount)
                maxEcCount = Math.max(maxEcCount, ecCount)

                dcdata[r] = new Array(dcCount)

                for (var i = 0; i < dcdata[r].length; i++) {
                    dcdata[r][i] = 0xff & buffer.buffer[i + offset]
                }
                offset += dcCount

                var rsPoly = QRUtil.getErrorCorrectPolynomial(ecCount)
                var rawPoly = new QRPolynomial(dcdata[r], rsPoly.getLength() - 1)

                var modPoly = rawPoly.mod(rsPoly)
                ecdata[r] = new Array(rsPoly.getLength() - 1)
                for (var i = 0; i < ecdata[r].length; i++) {
                    var modIndex = i + modPoly.getLength() - ecdata[r].length
                    ecdata[r][i] = modIndex >= 0 ? modPoly.get(modIndex) : 0
                }
            }

            var totalCodeCount = 0
            for (var i = 0; i < rsBlocks.length; i++) {
                totalCodeCount += rsBlocks[i].totalCount
            }

            var data = new Array(totalCodeCount)
            var index = 0

            for (var i = 0; i < maxDcCount; i++) {
                for (var r = 0; r < rsBlocks.length; r++) {
                    if (i < dcdata[r].length) {
                        data[index++] = dcdata[r][i]
                    }
                }
            }

            for (var i = 0; i < maxEcCount; i++) {
                for (var r = 0; r < rsBlocks.length; r++) {
                    if (i < ecdata[r].length) {
                        data[index++] = ecdata[r][i]
                    }
                }
            }

            return data
        }

        //---------------------------------------------------------------------
        // QRMode
        //---------------------------------------------------------------------

        var QRMode = {
            MODE_NUMBER: 1 << 0,
            MODE_ALPHA_NUM: 1 << 1,
            MODE_8BIT_BYTE: 1 << 2,
            MODE_KANJI: 1 << 3,
        }

        //---------------------------------------------------------------------
        // QRErrorCorrectLevel
        //---------------------------------------------------------------------

        var QRErrorCorrectLevel = {
            L: 1,
            M: 0,
            Q: 3,
            H: 2,
        }

        //---------------------------------------------------------------------
        // QRMaskPattern
        //---------------------------------------------------------------------

        var QRMaskPattern = {
            PATTERN000: 0,
            PATTERN001: 1,
            PATTERN010: 2,
            PATTERN011: 3,
            PATTERN100: 4,
            PATTERN101: 5,
            PATTERN110: 6,
            PATTERN111: 7,
        }

        //---------------------------------------------------------------------
        // QRUtil
        //---------------------------------------------------------------------

        var QRUtil = {
            PATTERN_POSITION_TABLE: [
                [],
                [6, 18],
                [6, 22],
                [6, 26],
                [6, 30],
                [6, 34],
                [6, 22, 38],
                [6, 24, 42],
                [6, 26, 46],
                [6, 28, 50],
                [6, 30, 54],
                [6, 32, 58],
                [6, 34, 62],
                [6, 26, 46, 66],
                [6, 26, 48, 70],
                [6, 26, 50, 74],
                [6, 30, 54, 78],
                [6, 30, 56, 82],
                [6, 30, 58, 86],
                [6, 34, 62, 90],
                [6, 28, 50, 72, 94],
                [6, 26, 50, 74, 98],
                [6, 30, 54, 78, 102],
                [6, 28, 54, 80, 106],
                [6, 32, 58, 84, 110],
                [6, 30, 58, 86, 114],
                [6, 34, 62, 90, 118],
                [6, 26, 50, 74, 98, 122],
                [6, 30, 54, 78, 102, 126],
                [6, 26, 52, 78, 104, 130],
                [6, 30, 56, 82, 108, 134],
                [6, 34, 60, 86, 112, 138],
                [6, 30, 58, 86, 114, 142],
                [6, 34, 62, 90, 118, 146],
                [6, 30, 54, 78, 102, 126, 150],
                [6, 24, 50, 76, 102, 128, 154],
                [6, 28, 54, 80, 106, 132, 158],
                [6, 32, 58, 84, 110, 136, 162],
                [6, 26, 54, 82, 110, 138, 166],
                [6, 30, 58, 86, 114, 142, 170],
            ],

            G15: (1 << 10) | (1 << 8) | (1 << 5) | (1 << 4) | (1 << 2) | (1 << 1) | (1 << 0),
            G18: (1 << 12) | (1 << 11) | (1 << 10) | (1 << 9) | (1 << 8) | (1 << 5) | (1 << 2) | (1 << 0),
            G15_MASK: (1 << 14) | (1 << 12) | (1 << 10) | (1 << 4) | (1 << 1),

            getBCHTypeInfo: function (data) {
                var d = data << 10
                while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15) >= 0) {
                    d ^= QRUtil.G15 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15))
                }
                return ((data << 10) | d) ^ QRUtil.G15_MASK
            },

            getBCHTypeNumber: function (data) {
                var d = data << 12
                while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18) >= 0) {
                    d ^= QRUtil.G18 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18))
                }
                return (data << 12) | d
            },

            getBCHDigit: function (data) {
                var digit = 0

                while (data != 0) {
                    digit++
                    data >>>= 1
                }

                return digit
            },

            getPatternPosition: function (typeNumber) {
                return QRUtil.PATTERN_POSITION_TABLE[typeNumber - 1]
            },

            getMask: function (maskPattern, i, j) {
                switch (maskPattern) {
                    case QRMaskPattern.PATTERN000:
                        return (i + j) % 2 == 0
                    case QRMaskPattern.PATTERN001:
                        return i % 2 == 0
                    case QRMaskPattern.PATTERN010:
                        return j % 3 == 0
                    case QRMaskPattern.PATTERN011:
                        return (i + j) % 3 == 0
                    case QRMaskPattern.PATTERN100:
                        return (Math.floor(i / 2) + Math.floor(j / 3)) % 2 == 0
                    case QRMaskPattern.PATTERN101:
                        return ((i * j) % 2) + ((i * j) % 3) == 0
                    case QRMaskPattern.PATTERN110:
                        return (((i * j) % 2) + ((i * j) % 3)) % 2 == 0
                    case QRMaskPattern.PATTERN111:
                        return (((i * j) % 3) + ((i + j) % 2)) % 2 == 0

                    default:
                        throw new Error('bad maskPattern:' + maskPattern)
                }
            },

            getErrorCorrectPolynomial: function (errorCorrectLength) {
                var a = new QRPolynomial([1], 0)

                for (var i = 0; i < errorCorrectLength; i++) {
                    a = a.multiply(new QRPolynomial([1, QRMath.gexp(i)], 0))
                }

                return a
            },

            getLengthInBits: function (mode, type) {
                if (1 <= type && type < 10) {
                    // 1 - 9

                    switch (mode) {
                        case QRMode.MODE_NUMBER:
                            return 10
                        case QRMode.MODE_ALPHA_NUM:
                            return 9
                        case QRMode.MODE_8BIT_BYTE:
                            return 8
                        case QRMode.MODE_KANJI:
                            return 8
                        default:
                            throw new Error('mode:' + mode)
                    }
                } else if (type < 27) {
                    // 10 - 26

                    switch (mode) {
                        case QRMode.MODE_NUMBER:
                            return 12
                        case QRMode.MODE_ALPHA_NUM:
                            return 11
                        case QRMode.MODE_8BIT_BYTE:
                            return 16
                        case QRMode.MODE_KANJI:
                            return 10
                        default:
                            throw new Error('mode:' + mode)
                    }
                } else if (type < 41) {
                    // 27 - 40

                    switch (mode) {
                        case QRMode.MODE_NUMBER:
                            return 14
                        case QRMode.MODE_ALPHA_NUM:
                            return 13
                        case QRMode.MODE_8BIT_BYTE:
                            return 16
                        case QRMode.MODE_KANJI:
                            return 12
                        default:
                            throw new Error('mode:' + mode)
                    }
                } else {
                    throw new Error('type:' + type)
                }
            },

            getLostPoint: function (qrCode) {
                var moduleCount = qrCode.getModuleCount()

                var lostPoint = 0

                // LEVEL1

                for (var row = 0; row < moduleCount; row++) {
                    for (var col = 0; col < moduleCount; col++) {
                        var sameCount = 0
                        var dark = qrCode.isDark(row, col)

                        for (var r = -1; r <= 1; r++) {
                            if (row + r < 0 || moduleCount <= row + r) {
                                continue
                            }

                            for (var c = -1; c <= 1; c++) {
                                if (col + c < 0 || moduleCount <= col + c) {
                                    continue
                                }

                                if (r == 0 && c == 0) {
                                    continue
                                }

                                if (dark == qrCode.isDark(row + r, col + c)) {
                                    sameCount++
                                }
                            }
                        }

                        if (sameCount > 5) {
                            lostPoint += 3 + sameCount - 5
                        }
                    }
                }

                // LEVEL2

                for (var row = 0; row < moduleCount - 1; row++) {
                    for (var col = 0; col < moduleCount - 1; col++) {
                        var count = 0
                        if (qrCode.isDark(row, col)) count++
                        if (qrCode.isDark(row + 1, col)) count++
                        if (qrCode.isDark(row, col + 1)) count++
                        if (qrCode.isDark(row + 1, col + 1)) count++
                        if (count == 0 || count == 4) {
                            lostPoint += 3
                        }
                    }
                }

                // LEVEL3

                for (var row = 0; row < moduleCount; row++) {
                    for (var col = 0; col < moduleCount - 6; col++) {
                        if (
                            qrCode.isDark(row, col) &&
                            !qrCode.isDark(row, col + 1) &&
                            qrCode.isDark(row, col + 2) &&
                            qrCode.isDark(row, col + 3) &&
                            qrCode.isDark(row, col + 4) &&
                            !qrCode.isDark(row, col + 5) &&
                            qrCode.isDark(row, col + 6)
                        ) {
                            lostPoint += 40
                        }
                    }
                }

                for (var col = 0; col < moduleCount; col++) {
                    for (var row = 0; row < moduleCount - 6; row++) {
                        if (
                            qrCode.isDark(row, col) &&
                            !qrCode.isDark(row + 1, col) &&
                            qrCode.isDark(row + 2, col) &&
                            qrCode.isDark(row + 3, col) &&
                            qrCode.isDark(row + 4, col) &&
                            !qrCode.isDark(row + 5, col) &&
                            qrCode.isDark(row + 6, col)
                        ) {
                            lostPoint += 40
                        }
                    }
                }

                // LEVEL4

                var darkCount = 0

                for (var col = 0; col < moduleCount; col++) {
                    for (var row = 0; row < moduleCount; row++) {
                        if (qrCode.isDark(row, col)) {
                            darkCount++
                        }
                    }
                }

                var ratio = Math.abs((100 * darkCount) / moduleCount / moduleCount - 50) / 5
                lostPoint += ratio * 10

                return lostPoint
            },
        }

        //---------------------------------------------------------------------
        // QRMath
        //---------------------------------------------------------------------

        var QRMath = {
            glog: function (n) {
                if (n < 1) {
                    throw new Error('glog(' + n + ')')
                }

                return QRMath.LOG_TABLE[n]
            },

            gexp: function (n) {
                while (n < 0) {
                    n += 255
                }

                while (n >= 256) {
                    n -= 255
                }

                return QRMath.EXP_TABLE[n]
            },

            EXP_TABLE: new Array(256),

            LOG_TABLE: new Array(256),
        }

        for (var i = 0; i < 8; i++) {
            QRMath.EXP_TABLE[i] = 1 << i
        }
        for (var i = 8; i < 256; i++) {
            QRMath.EXP_TABLE[i] =
                QRMath.EXP_TABLE[i - 4] ^ QRMath.EXP_TABLE[i - 5] ^ QRMath.EXP_TABLE[i - 6] ^ QRMath.EXP_TABLE[i - 8]
        }
        for (var i = 0; i < 255; i++) {
            QRMath.LOG_TABLE[QRMath.EXP_TABLE[i]] = i
        }

        //---------------------------------------------------------------------
        // QRPolynomial
        //---------------------------------------------------------------------

        function QRPolynomial(num, shift) {
            if (num.length == undefined) {
                throw new Error(num.length + '/' + shift)
            }

            var offset = 0

            while (offset < num.length && num[offset] == 0) {
                offset++
            }

            this.num = new Array(num.length - offset + shift)
            for (var i = 0; i < num.length - offset; i++) {
                this.num[i] = num[i + offset]
            }
        }

        QRPolynomial.prototype = {
            get: function (index) {
                return this.num[index]
            },

            getLength: function () {
                return this.num.length
            },

            multiply: function (e) {
                var num = new Array(this.getLength() + e.getLength() - 1)

                for (var i = 0; i < this.getLength(); i++) {
                    for (var j = 0; j < e.getLength(); j++) {
                        num[i + j] ^= QRMath.gexp(QRMath.glog(this.get(i)) + QRMath.glog(e.get(j)))
                    }
                }

                return new QRPolynomial(num, 0)
            },

            mod: function (e) {
                if (this.getLength() - e.getLength() < 0) {
                    return this
                }

                var ratio = QRMath.glog(this.get(0)) - QRMath.glog(e.get(0))

                var num = new Array(this.getLength())

                for (var i = 0; i < this.getLength(); i++) {
                    num[i] = this.get(i)
                }

                for (var i = 0; i < e.getLength(); i++) {
                    num[i] ^= QRMath.gexp(QRMath.glog(e.get(i)) + ratio)
                }

                // recursive call
                return new QRPolynomial(num, 0).mod(e)
            },
        }

        //---------------------------------------------------------------------
        // QRRSBlock
        //---------------------------------------------------------------------

        function QRRSBlock(totalCount, dataCount) {
            this.totalCount = totalCount
            this.dataCount = dataCount
        }

        QRRSBlock.RS_BLOCK_TABLE = [
            // L
            // M
            // Q
            // H

            // 1
            [1, 26, 19],
            [1, 26, 16],
            [1, 26, 13],
            [1, 26, 9],

            // 2
            [1, 44, 34],
            [1, 44, 28],
            [1, 44, 22],
            [1, 44, 16],

            // 3
            [1, 70, 55],
            [1, 70, 44],
            [2, 35, 17],
            [2, 35, 13],

            // 4
            [1, 100, 80],
            [2, 50, 32],
            [2, 50, 24],
            [4, 25, 9],

            // 5
            [1, 134, 108],
            [2, 67, 43],
            [2, 33, 15, 2, 34, 16],
            [2, 33, 11, 2, 34, 12],

            // 6
            [2, 86, 68],
            [4, 43, 27],
            [4, 43, 19],
            [4, 43, 15],

            // 7
            [2, 98, 78],
            [4, 49, 31],
            [2, 32, 14, 4, 33, 15],
            [4, 39, 13, 1, 40, 14],

            // 8
            [2, 121, 97],
            [2, 60, 38, 2, 61, 39],
            [4, 40, 18, 2, 41, 19],
            [4, 40, 14, 2, 41, 15],

            // 9
            [2, 146, 116],
            [3, 58, 36, 2, 59, 37],
            [4, 36, 16, 4, 37, 17],
            [4, 36, 12, 4, 37, 13],

            // 10
            [2, 86, 68, 2, 87, 69],
            [4, 69, 43, 1, 70, 44],
            [6, 43, 19, 2, 44, 20],
            [6, 43, 15, 2, 44, 16],

            // 11
            [4, 101, 81],
            [1, 80, 50, 4, 81, 51],
            [4, 50, 22, 4, 51, 23],
            [3, 36, 12, 8, 37, 13],

            // 12
            [2, 116, 92, 2, 117, 93],
            [6, 58, 36, 2, 59, 37],
            [4, 46, 20, 6, 47, 21],
            [7, 42, 14, 4, 43, 15],

            // 13
            [4, 133, 107],
            [8, 59, 37, 1, 60, 38],
            [8, 44, 20, 4, 45, 21],
            [12, 33, 11, 4, 34, 12],

            // 14
            [3, 145, 115, 1, 146, 116],
            [4, 64, 40, 5, 65, 41],
            [11, 36, 16, 5, 37, 17],
            [11, 36, 12, 5, 37, 13],

            // 15
            [5, 109, 87, 1, 110, 88],
            [5, 65, 41, 5, 66, 42],
            [5, 54, 24, 7, 55, 25],
            [11, 36, 12],

            // 16
            [5, 122, 98, 1, 123, 99],
            [7, 73, 45, 3, 74, 46],
            [15, 43, 19, 2, 44, 20],
            [3, 45, 15, 13, 46, 16],

            // 17
            [1, 135, 107, 5, 136, 108],
            [10, 74, 46, 1, 75, 47],
            [1, 50, 22, 15, 51, 23],
            [2, 42, 14, 17, 43, 15],

            // 18
            [5, 150, 120, 1, 151, 121],
            [9, 69, 43, 4, 70, 44],
            [17, 50, 22, 1, 51, 23],
            [2, 42, 14, 19, 43, 15],

            // 19
            [3, 141, 113, 4, 142, 114],
            [3, 70, 44, 11, 71, 45],
            [17, 47, 21, 4, 48, 22],
            [9, 39, 13, 16, 40, 14],

            // 20
            [3, 135, 107, 5, 136, 108],
            [3, 67, 41, 13, 68, 42],
            [15, 54, 24, 5, 55, 25],
            [15, 43, 15, 10, 44, 16],

            // 21
            [4, 144, 116, 4, 145, 117],
            [17, 68, 42],
            [17, 50, 22, 6, 51, 23],
            [19, 46, 16, 6, 47, 17],

            // 22
            [2, 139, 111, 7, 140, 112],
            [17, 74, 46],
            [7, 54, 24, 16, 55, 25],
            [34, 37, 13],

            // 23
            [4, 151, 121, 5, 152, 122],
            [4, 75, 47, 14, 76, 48],
            [11, 54, 24, 14, 55, 25],
            [16, 45, 15, 14, 46, 16],

            // 24
            [6, 147, 117, 4, 148, 118],
            [6, 73, 45, 14, 74, 46],
            [11, 54, 24, 16, 55, 25],
            [30, 46, 16, 2, 47, 17],

            // 25
            [8, 132, 106, 4, 133, 107],
            [8, 75, 47, 13, 76, 48],
            [7, 54, 24, 22, 55, 25],
            [22, 45, 15, 13, 46, 16],

            // 26
            [10, 142, 114, 2, 143, 115],
            [19, 74, 46, 4, 75, 47],
            [28, 50, 22, 6, 51, 23],
            [33, 46, 16, 4, 47, 17],

            // 27
            [8, 152, 122, 4, 153, 123],
            [22, 73, 45, 3, 74, 46],
            [8, 53, 23, 26, 54, 24],
            [12, 45, 15, 28, 46, 16],

            // 28
            [3, 147, 117, 10, 148, 118],
            [3, 73, 45, 23, 74, 46],
            [4, 54, 24, 31, 55, 25],
            [11, 45, 15, 31, 46, 16],

            // 29
            [7, 146, 116, 7, 147, 117],
            [21, 73, 45, 7, 74, 46],
            [1, 53, 23, 37, 54, 24],
            [19, 45, 15, 26, 46, 16],

            // 30
            [5, 145, 115, 10, 146, 116],
            [19, 75, 47, 10, 76, 48],
            [15, 54, 24, 25, 55, 25],
            [23, 45, 15, 25, 46, 16],

            // 31
            [13, 145, 115, 3, 146, 116],
            [2, 74, 46, 29, 75, 47],
            [42, 54, 24, 1, 55, 25],
            [23, 45, 15, 28, 46, 16],

            // 32
            [17, 145, 115],
            [10, 74, 46, 23, 75, 47],
            [10, 54, 24, 35, 55, 25],
            [19, 45, 15, 35, 46, 16],

            // 33
            [17, 145, 115, 1, 146, 116],
            [14, 74, 46, 21, 75, 47],
            [29, 54, 24, 19, 55, 25],
            [11, 45, 15, 46, 46, 16],

            // 34
            [13, 145, 115, 6, 146, 116],
            [14, 74, 46, 23, 75, 47],
            [44, 54, 24, 7, 55, 25],
            [59, 46, 16, 1, 47, 17],

            // 35
            [12, 151, 121, 7, 152, 122],
            [12, 75, 47, 26, 76, 48],
            [39, 54, 24, 14, 55, 25],
            [22, 45, 15, 41, 46, 16],

            // 36
            [6, 151, 121, 14, 152, 122],
            [6, 75, 47, 34, 76, 48],
            [46, 54, 24, 10, 55, 25],
            [2, 45, 15, 64, 46, 16],

            // 37
            [17, 152, 122, 4, 153, 123],
            [29, 74, 46, 14, 75, 47],
            [49, 54, 24, 10, 55, 25],
            [24, 45, 15, 46, 46, 16],

            // 38
            [4, 152, 122, 18, 153, 123],
            [13, 74, 46, 32, 75, 47],
            [48, 54, 24, 14, 55, 25],
            [42, 45, 15, 32, 46, 16],

            // 39
            [20, 147, 117, 4, 148, 118],
            [40, 75, 47, 7, 76, 48],
            [43, 54, 24, 22, 55, 25],
            [10, 45, 15, 67, 46, 16],

            // 40
            [19, 148, 118, 6, 149, 119],
            [18, 75, 47, 31, 76, 48],
            [34, 54, 24, 34, 55, 25],
            [20, 45, 15, 61, 46, 16],
        ]

        QRRSBlock.getRSBlocks = function (typeNumber, errorCorrectLevel) {
            var rsBlock = QRRSBlock.getRsBlockTable(typeNumber, errorCorrectLevel)

            if (rsBlock == undefined) {
                throw new Error('bad rs block @ typeNumber:' + typeNumber + '/errorCorrectLevel:' + errorCorrectLevel)
            }

            var length = rsBlock.length / 3

            var list = []

            for (var i = 0; i < length; i++) {
                var count = rsBlock[i * 3 + 0]
                var totalCount = rsBlock[i * 3 + 1]
                var dataCount = rsBlock[i * 3 + 2]

                for (var j = 0; j < count; j++) {
                    list.push(new QRRSBlock(totalCount, dataCount))
                }
            }

            return list
        }

        QRRSBlock.getRsBlockTable = function (typeNumber, errorCorrectLevel) {
            switch (errorCorrectLevel) {
                case QRErrorCorrectLevel.L:
                    return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 0]
                case QRErrorCorrectLevel.M:
                    return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 1]
                case QRErrorCorrectLevel.Q:
                    return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 2]
                case QRErrorCorrectLevel.H:
                    return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 3]
                default:
                    return undefined
            }
        }

        //---------------------------------------------------------------------
        // QRBitBuffer
        //---------------------------------------------------------------------

        function QRBitBuffer() {
            this.buffer = []
            this.length = 0
        }

        QRBitBuffer.prototype = {
            get: function (index) {
                var bufIndex = Math.floor(index / 8)
                return ((this.buffer[bufIndex] >>> (7 - (index % 8))) & 1) == 1
            },

            put: function (num, length) {
                for (var i = 0; i < length; i++) {
                    this.putBit(((num >>> (length - i - 1)) & 1) == 1)
                }
            },

            getLengthInBits: function () {
                return this.length
            },

            putBit: function (bit) {
                var bufIndex = Math.floor(this.length / 8)
                if (this.buffer.length <= bufIndex) {
                    this.buffer.push(0)
                }

                if (bit) {
                    this.buffer[bufIndex] |= 0x80 >>> this.length % 8
                }

                this.length++
            },
        }

        //---------------------------------------------------------------------
        // Support Chinese
        //---------------------------------------------------------------------
        function utf16To8(text) {
            var result = ''
            var c
            for (var i = 0; i < text.length; i++) {
                c = text.charCodeAt(i)
                if (c >= 0x0001 && c <= 0x007f) {
                    result += text.charAt(i)
                } else if (c > 0x07ff) {
                    result += String.fromCharCode(0xe0 | ((c >> 12) & 0x0f))
                    result += String.fromCharCode(0x80 | ((c >> 6) & 0x3f))
                    result += String.fromCharCode(0x80 | ((c >> 0) & 0x3f))
                } else {
                    result += String.fromCharCode(0xc0 | ((c >> 6) & 0x1f))
                    result += String.fromCharCode(0x80 | ((c >> 0) & 0x3f))
                }
            }
            return result
        }

        uQRCode = {
            defaults: {
                size: 238,
                margin: 0,
                backgroundColor: '#ffffff',
                foregroundColor: '#000000',
                fileType: 'png', // 'jpg', 'png'
                correctLevel: 0,
                typeNumber: -1,
            },

            make: function (options) {
                var defaultOptions = {
                    canvasId: options.canvasId,
                    componentInstance: options.componentInstance,
                    text: options.text,
                    size: this.defaults.size,
                    margin: this.defaults.margin,
                    backgroundColor: this.defaults.backgroundColor,
                    foregroundColor: this.defaults.foregroundColor,
                    fileType: this.defaults.fileType,
                    correctLevel: this.defaults.correctLevel,
                    typeNumber: this.defaults.typeNumber,
                }
                if (options) {
                    for (var i in options) {
                        defaultOptions[i] = options[i]
                    }
                }
                options = defaultOptions

                if (!options.canvasId) {
                    console.error('uQRCode: Please set canvasId!')
                    return
                }

                function createCanvas() {
                    var qrcode = new QRCode(options.typeNumber, options.correctLevel)
                    qrcode.addData(utf16To8(options.text))
                    qrcode.make()

                    var ctx = uni.createCanvasContext(options.canvasId, options.componentInstance)
                    ctx.setFillStyle(options.backgroundColor)
                    ctx.fillRect(0, 0, options.size, options.size)

                    var tileW = (options.size - options.margin * 2) / qrcode.getModuleCount()
                    var tileH = tileW

                    for (var row = 0; row < qrcode.getModuleCount(); row++) {
                        for (var col = 0; col < qrcode.getModuleCount(); col++) {
                            var style = qrcode.isDark(row, col) ? options.foregroundColor : options.backgroundColor
                            ctx.setFillStyle(style)
                            var x = Math.round(col * tileW) + options.margin
                            var y = Math.round(row * tileH) + options.margin
                            var w = Math.ceil((col + 1) * tileW) - Math.floor(col * tileW)
                            var h = Math.ceil((row + 1) * tileW) - Math.floor(row * tileW)
                            ctx.fillRect(x, y, w, h)
                        }
                    }

                    // if (options.image) {
                    //   uni.getImageInfo({
                    //     src: options.image,
                    //     success: function (res) {
                    //       var ratioSize = options.size
                    //       var ratioImgSize = options.imageSize
                    //       var x = Number(((ratioSize - ratioImgSize) / 2).toFixed(2))
                    //       var y = Number(((ratioSize - ratioImgSize) / 2).toFixed(2))
                    //       console.log(
                    //         '[  options.image, x, y, ratioImgSize, ratioImgSize ] >',
                    //         res,
                    //         x,
                    //         y,
                    //         ratioImgSize,
                    //         ratioImgSize
                    //       )
                    //       ctx.drawImage(res.path, 0, 0, ratioImgSize, ratioImgSize)
                    //     },
                    //   })
                    // }
                    setTimeout(function () {
                        ctx.draw(true, function () {
                            setTimeout(function () {
                                let imgSize = options.size * 5
                                uni.canvasToTempFilePath(
                                    {
                                        canvasId: options.canvasId,
                                        fileType: options.fileType,
                                        width: imgSize,
                                        height: imgSize,
                                        destWidth: imgSize,
                                        destHeight: imgSize,
                                        success: function (res) {
                                            options.success && options.success(res.tempFilePath)
                                        },
                                        fail: function (error) {
                                            options.fail && options.fail(error)
                                        },
                                        complete: function (res) {
                                            options.complete && options.complete(res)
                                        },
                                    },
                                    options.componentInstance
                                )
                            }, options.text.length + 100)
                        })
                    }, 500)
                }

                createCanvas()
            },
        }
    })()

export default uQRCode

效果如下
!](https://i-blog.csdnimg.cn/direct/03eca73974084d76bb8cbcdfee6acfb7.png)
在这里插入图片描述


网站公告

今日签到

点亮在社区的每一天
去签到