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 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> heic图片转换 -> 正文阅读

[移动开发]heic图片转换

问题:

heic图片在微信小程序端不能回显也不能上传成功。

1.了解heic图

Heic格式是苹果专门为iOS11开发的照片格式。Heic是苹果iOS和macOS的一种文件格式,用于处理图像和视频。Heic是H.264和JEP格式,取代了IOS 11系统中的原始视频和照片。Heic格式不仅可以节省内存,还可以保留原始图像质量。Heic格式是苹果iOS和iOS的特殊格式。

heic的特点:与JPG相比,heic格式占用空间更少,图像质量更无损。HEIC格式照片支持iOS11和macOS High Sierra(10.13)及更高版本。但是这种格式不能用图片查看软件直接在Windows中打开(Windows10 RS4开始支持这种格式)。

2.微信小程序下的回显

heic的图片在微信小程序下,经过压缩,可以转换为jpeg,展示

         wx.compressImage({
            src: path, // 图片路径
            quality: 50, // 压缩质量
            success: (res) => {
              console.log(res, 'ressss')
            },
            fail: (err) => {
              console.log(err)
            }
          })

注意:压缩图片在微信小程序可以回显页面,但是继续上传后端,依旧会失败

3.解决微信小程序上传失败

终极解决方案是后端进行转换。暂时没有找到前端能直接转换的方案,如果有,欢迎讨论

(下面是为了上传heic图片成功,所以用本地node端测试了一下转换图片,在回传给前端,在重新上传给真正的后端转换的图片上传成功的案例)

(1)微信小程序端

   //选择图片
   wx.chooseMedia({
      count: 1,
      mediaType: 'image',
      success: (r) => {
       //上传给node服务器进行转换
       wx.uploadFile({
            url: 'http://localhost:7001/uploadImg/api/heictoany', 
            filePath:r.tempFiles[0].tempFilePath,
            name: 'file',
            success: (res) => {
              let src = 'http://localhost:7001/MKIntouch/' ++JSON.parse(res.data).src
              //拿到地址重新下载图片
              wx.downloadFile({
                url: src, 
                success (tempR) {
                  if (tempR.statusCode === 200) {
                   //重新生成本地临时路径(用这个路径在去上传给后端可上传heic成功,也可以回显)
                    console.log(tempR.tempFilePath)
                  }
                }
              })
            }
          })

      }

(2)node端转换heic

主要使用插件

GitHub - catdad-experiments/heic-convert: 🤳 convert heic/heif images to jpeg and png

node端用了egg.js框架

1.进行配置

文件上传 | Egg

egg.js内置了

配置插件 - config.default.js

    const whitelist = [
        // images
        '.jpg', '.jpeg', // image/jpeg
        '.png', // image/png, image/x-png
        '.gif', // image/gif
        '.bmp', // image/bmp
        '.wbmp', // image/vnd.wap.wbmp
        '.webp',
        '.tif',
        '.psd',
        // text
        '.svg',
        '.js', '.jsx',
        '.json',
        '.css', '.less',
        '.html', '.htm',
        '.heic',
        '.HEIC',
        '.xml',
        // tar
        '.zip',
        '.gz', '.tgz', '.gzip',
        // video
        '.mp3',
        '.mp4',
        '.avi',
    ];

    exports.multipart = {
        whitelist,
        fileSize: '50mb',
    };

如果不配置config,接收文件流会报错

2.在router页面进行创建

创建文件夹 - uploadImg->app,js

'use strict';
module.exports = app => {
    const { router, controller } = app;
    const subRouter = router.namespace('/uploadImg');

    subRouter.post('/api/heictoany', controller.uploadImg.api.heictoany);

};

3.controller层进行业务书写

要使用的插件需要利用npm下载哦

controller新建文件夹uploadImg->app.js

'use strict';
const egg = require('egg');
const convert = require('heic-convert');
const fs = require('fs');
const { promisify } = require('util');

const path = require('path');
const awaitWriteStream = require('await-stream-ready').write;
const senToWormhole = require('stream-wormhole');
// 时间格式化
const dayjs = require('dayjs');
const await = require('await-stream-ready/lib/await');


module.exports = class Pages extends egg.Controller {
    async heictoany() {
        const { ctx } = this;

        // 获取文件流
        const stream = await ctx.getFileStream();
        // 创建基础的目录
        const uploadBasePath = 'public/img';
        // 创建生成的基础名
        const filename = `${Date.now()}${Number.parseInt(Math.random() * 1000)}${path.extname(stream.filename).toLocaleLowerCase()}`;
        // const resultname = filename.replace(/heic/g, 'png')
        const resultname = filename.replace(/heic/g, 'jpg')
        // 生成文件夹
        const dirname = dayjs(Date.now()).format('YYYY/MM/DD');
        // 创建目录
        function mkdirsSync(dirname) {
            if (fs.existsSync(dirname)) { // fs.existsSync检测目录是否存在,存在返回true,反之亦然
                return true;
            }
            if (mkdirsSync(path.dirname(dirname))) { // 返回 path 的目录名,尾部的文件名会被忽略path.dirname('/目录1/目录2/目录3');返回'/目录1/目录2'
                fs.mkdirSync(dirname);// fs.mkdirSync同步地创建目录
                return true;
            }

        }

        mkdirsSync(path.join(uploadBasePath, dirname));// path.join,以特定的分隔符将路径连接起来
        // 生成写入路径
        const target = path.join(uploadBasePath, dirname, filename);

        console.log(path.join(uploadBasePath, dirname), '文件文件');
        // 写入流
        const writeStream = fs.createWriteStream(target);
        try {
            // 异步把文件流 写入
            await awaitWriteStream(stream.pipe(writeStream));
        } catch (err) {
            // 如果出现错误,关闭管道
            await sendToWormhole(stream);
            return Promise.reject('上传错误');
        }

        const inputBuffer = await promisify(fs.readFile)(target);
        console.log(inputBuffer, 'inputBuffer');
        const outputBuffer = await convert({
            buffer: inputBuffer, // the HEIC file buffer
            format: 'JPEG', // output format
            // format: 'PNG', // output format
        });
        console.log(outputBuffer, 'outbuffer')
        console.log(path.join(uploadBasePath, dirname, resultname), 'xxxx')
        const resultUrl = path.join(uploadBasePath, dirname, resultname);
        console.log(resultUrl, 'resultURLLLLL')
        await promisify(fs.writeFile)(resultUrl, outputBuffer);

        ctx.status = 200;
        ctx.body = {
            src: resultUrl
        };


    }
};

经过测试发现,只有转成jpg才可以进行重新上传到服务器。转成png,依旧无法上传到服务器

如果是想转换给前端base64,可以继续进行转化

 let res = fs.readFileSync(resultUrl,'binary')
       
 const buffer = new Buffer(res, 'binary');
 const src = 'data: image/png;base64,' + buffer.toString('base64');

暂时没有什么其他方法了,微信官方都推荐后端进行转换

转换插件,会发现,如果heic图片转换时间有点慢(1.8M的heic转换启动本地的node会大概11s左右)

欢迎交流该问题

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-10-31 12:09:06  更:2022-10-31 12:13:31 
 
开发: 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年5日历 -2024/5/19 18:44:29-

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