【问题标题】:Nuxt convert image to webp before sending to AWS S3Nuxt 在发送到 AWS S3 之前将图像转换为 webp
【发布时间】:2021-09-21 18:26:26
【问题描述】:

如何在我的 NUXT 应用程序中将图像转换为 WEBP 格式,然后再将它们发送到 AWS S3?

我在我的网站上上传了一张照片,我想在上传到亚马逊网络服务之前将图像从文件输入转换为WEBP 格式。与我可以导入sharp并使用它将图像转换为WEBP格式的NodeJS不同,这里不是这种情况,因为我收到如下错误

Failed to compile with 4 errors                                                                                               friendly-errors 01:16:19  

These dependencies were not found:                                                                                                    friendly-errors 01:16:19  
                                                                                                                                      friendly-errors 01:16:19  
* child_process in ./node_modules/detect-libc/lib/detect-libc.js, ./node_modules/sharp/lib/libvips.js                                 friendly-errors 01:16:19
* fs in ./node_modules/detect-libc/lib/detect-libc.js, ./node_modules/sharp/lib/libvips.js                                            friendly-errors 01:16:19  
                                                                                                                                      friendly-errors 01:16:19  
To install them, you can run: npm install --save child_process fs  

我想像下面的代码一样转换图像

        drop(e) {
            e.preventDefault();
            e.stopPropagation();
            e.target.classList.remove('solid');
            const files = e.dataTransfer.files;
            this.handleFiles(files);
        },
        onFilePicked(e) {
            e.preventDefault();
            e.stopPropagation();
            const files = e.target.files;
            this.handleFiles(files);
        },
        saveToBackend(file, result) {
            // compress image
            // save to aws
        },
        readFiles(file) {
            const reader = new FileReader();
            reader.readAsDataURL(file)
            reader.onload = () => {
                const uploading = this.uploading
                const result = reader.result
                uploading.push(result)
                this.uploading = uploading
                

                // upload to aws
                this.saveToBackend(file, result)
            }
        },
        handleFiles(files) {
            const Files = Array.from(files);
            Files.forEach(file => {
                // check if image is a valid image
                if (file.type.includes('image')) {
                    // display the image
                    return this.readFiles(file)
                }
                return
            });
            console.log(Files, "loaded files");
        },

对于锋利的插件

import vue from "vue"
import sharp from "sharp"
vue.use(sharp)

请问如何压缩图片?

【问题讨论】:

  • @kissu 您的回答只能解释为什么我正在做的事情行不通,但它没有提供任何解决方案。但我最终找到了一个解决方案,在将图像发送到 AWS S3 之前,无需使用任何包即可将任何图像转换为 WEBP 格式。我必须将图像转换为画布,然后将图像转换为 WEBP 格式。我将在下面发布我的解决方案。
  • 到目前为止,我无法解释如何在 StackOverflow 答案中的 2 个应用程序之间设置服务器。很高兴您找到了将图像转换为.webp 的方法,希望在此过程中不会有太多质量损失。渴望看到你的答案。

标签: node.js amazon-web-services vue.js nuxt.js


【解决方案1】:

您可以使用包imageminimagemin-webp 在这里回答:Convert Images to webp with Node

【讨论】:

  • 兄弟在 NUXT 或 VUE 中使用它是一个问题。
  • @OpeyemiOdedeyi 请不要兄弟 Thomas,到目前为止,他正在给你一个很好的建议。
【解决方案2】:

正如我在您的 previous question 中向您解释的那样,您不能在客户端应用程序中使用 Node.js 插件,尤其是当这个插件已经在运行时,特别是如果您在某些服务器上将其托管为 target: static Vercel 或类似平台。

除此之外,图像处理在所需处理方面非常繁重。因此,最好有一个外部服务器作为中间件来执行此操作。您将能够制作负载均衡器、分配自动缩放、防止客户端超时并允许以更简单的方式进行调试(实际上可能还有更多好处)。
如果您不会对较慢的冷启动感到困扰,您甚至可以在无服务器功能上执行此操作。

TLDR:

  • 简单高效的解决方案,在 Nuxt 和 S3 存储桶之间放置一个 Node.js 服务器
  • 更实惠但更复杂,为此调用无服务器函数(甚至不确定这是否会高效)
  • 等待带有 Nitro 的 Nuxt3,并在边缘渲染中使用本地 serviceWorker 和 Cloudflare workers 制造一些恶作剧(甚至不确定这也是处理您的问题的最合适的方式)
  • 也许可以尝试寻找不那么昂贵的在线服务来为您处理中间件

最后,图像或视频处理起来繁重且昂贵。而且做这些事情也需要相当多的知识!

【讨论】:

    【解决方案3】:

    最终,我能够在不使用任何包的情况下解决我的问题,我所做的只是将图像转换为画布,然后将图像转换为 WEBP 格式。以下是我的解决方案。

        convertImage(file) {
            return new Promise((resolve) => {
                // convert image
                let src = URL.createObjectURL(file)
                let canvas = document.createElement('canvas');
                let ctx = canvas.getContext('2d')
    
                let userImage = new Image();
                userImage.src = src
    
                userImage.onload = function() {
                    canvas.width = userImage.width;
                    canvas.height = userImage.height;
                    ctx.drawImage(userImage, 0, 0);
    
                    let webpImage = canvas.toDataURL("image/webp");
                    return resolve(webpImage);
                }
            });    
        },
    

    所以,上面的函数首先接收一个文件,该文件是您要从文件输入转换的图像,然后将图像转换为画布,然后将画布转换回图像,但是这次您指定了格式你想把它转换成的图像。

    因为在我的例子中,我想要一个webp 图像,所以我设置了canvas.toDataURL("image/webp"),默认情况下,WEBP 图像的质量将与接收到的图像质量相同。如果您想将质量降低到较低质量,canvas.toDataURL("image/webp", 1) 采用另一个参数,该参数是0-11 之间的数字,表示最高质量,0 最低质量。你也可以将0.5 设置为中等质量,或者任何你想要的。您还可以通过第一个参数设置您想要的其他文件格式,例如 canvas.toDataURL('image/jpeg', 1.0)-- 用于 jpeg 格式或 canvas.toDataURL('image/png', 1.0)-- 用于 png。

    来源

    我找到解决方案的小渠道 - Where I found my solution

    developer.mozilla.org 解释 - more on the CanvasElement.toDataURL()

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-04-24
      • 2018-05-10
      • 2022-07-07
      • 2012-10-24
      • 2017-12-12
      • 1970-01-01
      • 2019-11-18
      相关资源
      最近更新 更多