IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> 小程序canvas输出gif格式的图片作为表情 -> 正文阅读

[移动开发]小程序canvas输出gif格式的图片作为表情

canvas的基础直接略过,可以自己去学习,我们主要看小程序输出gif格式的方式

1.可以使用前端传参的方式,通过后端去处理图片完成(此处不讲解)

2.使用微信的FileSystemManager输出gif格式图片

在看微信小程序的官方文档当中我们可以知道canvas使用wx.canvasToTempFilePath的API输出两种图片的格式是png和jpg,那么我们需要如何实现gif格式的输出

我们需要使用gif.js;官网地址:gif.js,因为小程序不直接操作DOM的属性和只能有一个worker的方式,我们需要改写gif.js的文件

GIF.prototype.finishRendering = function() {
                    var data, frame, i, image, j, k, l, len, len1, len2, len3, offset, page, ref, ref1, ref2;
                    len = 0;
                    ref = this.imageParts;
                    for (j = 0,
                    len1 = ref.length; j < len1; j++) {
                        frame = ref[j];
                        len += (frame.data.length - 1) * frame.pageSize + frame.cursor
                    }
                    len += frame.pageSize - frame.cursor;
                    this.log("rendering finished - filesize " + Math.round(len / 1e3) + "kb");
                    data = new Uint8Array(len);
                    offset = 0;
                    ref1 = this.imageParts;
                    for (k = 0,
                    len2 = ref1.length; k < len2; k++) {
                        frame = ref1[k];
                        ref2 = frame.data;
                        for (i = l = 0,
                        len3 = ref2.length; l < len3; i = ++l) {
                            page = ref2[i];
                            // data.set(page, offset);
                            for (var _i = 0; _i < frame.pageSize; _i++) {
                                data[offset + _i] = page[_i]
                            }
                            if (i === frame.data.length - 1) {
                                offset += frame.cursor
                            } else {
                                offset += frame.pageSize
                            }
                        }
                    }
                    let worker = this.freeWorkers.shift();
                    // console.log('worker', worker)
                    worker.terminate(); // 销毁多线程
                    // image = new Blob([data],{
                    //     type: "image/gif"
                    // });
                    return this.emit("finished", data)
                    // return this.emit("finished", image, data)
                }
GIF.prototype.addFrame = function(image, options) {
                    var frame = {}, key;
                    if (options == null) {
                        options = {}
                    }
                    frame.index = options.index || 0;
                    frame.transparent = this.options.transparent;
                    for (key in frameDefaults) {
                        frame[key] = options[key] || frameDefaults[key]
                    }
                    if (this.options.width == null) {
                        this.setOption("width", image.width)
                    }
                    if (this.options.height == null) {
                        this.setOption("height", image.height)
                    }
                    if (image && image.width && image.height && image.data) {
                        frame.data = image.data
                    // } else if (typeof ImageData !== "undefined" && ImageData !== null && image instanceof ImageData) {
                    //     frame.data = image.data
                    // } else if (typeof CanvasRenderingContext2D !== "undefined" && CanvasRenderingContext2D !== null && image instanceof CanvasRenderingContext2D || typeof WebGLRenderingContext !== "undefined" && WebGLRenderingContext !== null && image instanceof WebGLRenderingContext) {
                    //     if (options.copy) {
                    //         frame.data = this.getContextData(image)
                    //     } else {
                    //         frame.context = image
                    //     }
                    // } else if (image.childNodes != null) {
                    //     if (options.copy) {
                    //         frame.data = this.getImageData(image)
                    //     } else {
                    //         frame.image = image
                    //     }
                    } else {
                        throw new Error("Invalid image")
                    }
                    return this.frames.push(frame)
                }

第二步:

    async createGif()  
        const self = this
        if (this.isShown) {
            return
        } 
        this.isShown = true
        let systemObj = wx.getSystemInfoSync()
        let pixelRatio = systemObj.pixelRatio
        this.setData({
            pixelRatio: pixelRatio
        })
        let windowWidth = systemObj.windowWidth // 总的px宽度
        let _1rpx = windowWidth / 750.0
    
        let width = this.data.imgW, 
            height = this.data.imgH
        let ctx = wx.createCanvasContext('ca')
        let gif = new GIF({
            workers: 1,
            width: width/pixelRatio, // 输出图片的宽高
            height: height/pixelRatio,
            debug: true
        })

        let startTime
        gif.on('start', function() {
            startTime = Date.now()
            return true
        });
        gif.on('progress', function(p) {
            self.setData({
                progress: p * 100
            })
            return true
        });
        gif.on('finished', function(data) {
            const fm = wx.getFileSystemManager()
            let ab = new ArrayBuffer(data.length) // js方法
            let dv = new DataView(ab) // js方法
            for (var i = 0; i < data.length; i++) {
                dv.setInt8(i, data[i])
            }
            fm.writeFile({
                filePath: `${wx.env.USER_DATA_PATH}/test.gif`,
                encoding: 'binary',
                data: ab,
                success (r) {
                    console.log('保存图片', `${wx.env.USER_DATA_PATH}/test.gif`)
                    self.setData({
                        gifFile: `${wx.env.USER_DATA_PATH}/test.gif`
                    })
                },
                fail (r) {
                    console.log(r)
                }
            })
            return true
        });
        ctx.clearRect(0, 0, width/pixelRatio, height/pixelRatio)
        ctx.setFillStyle('#f00');
        ctx.fillRect(0, 0, width/pixelRatio, height/pixelRatio)
        ctx.save()
        ctx.drawImage(this.data.diyFile,0,0, width/pixelRatio, height/pixelRatio)
        let drawRes = await new Promise(r => ctx.draw(true, r))
        try {
            let imgdata = await new Promise((resolve, reject) => wx.canvasGetImageData({
                canvasId: 'ca',
                height: height/pixelRatio,
                width: width/pixelRatio,
                x: 0,
                y: 0,
                success (r) {
                    resolve(r)
                },
                fail (e) {
                    reject(e)
                }
            }))
            console.log(imgdata)
            setTimeout(()=>{
                gif.addFrame(imgdata, {delay: 2000})
                console.log(gif.render())
            }, 2000)
        } catch(e) {

        }
}

这样我们就改写好了适合小程序的gif图,后面根据gif的官方文档API添加图片即可,实际上我们只需要了解小程序跟PC端的DOM操作的区别然后对应修改gif.js的文件即可,有时间的可以扩展在小程序当中生成gif动画功能

demo可以扫描的二维码diy栏目查看效果

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-01-28 12:02:03  更:2022-01-28 12:03:49 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 12:27:48-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码