【问题标题】:Next.js - Image is not 'defined"Next.js - 图像未“定义”
【发布时间】:2021-07-16 13:20:15
【问题描述】:

我正在开发 linebot 以接收带有 QR 码的图片。正如您在下面的代码中看到的那样,我已经成功地将文件保存到本地文件夹中为stream.on('end' , ...)中的“logo.png”@

然后我想用这个最近保存的文件来检测这个 npm 库的二维码。 (https://www.npmjs.com/package/jsqr)

然后我创建了函数 readPic() 来传递 imgPath 并使用该图片来检测 QR 码。

我的问题是const image = new Image(); 有一个名为“图像未定义”的错误

我该如何解决这个问题?或者如果有另一种方法可以在不使用画布的情况下从图片中获取要在jsQR() 中使用的 imageData。

我的代码:

import { useState } from 'react';
import fs from 'fs'

import axios from 'axios';
import jsQR from 'jsqr'

const request = require('request')
require('dotenv').config()

// const redis = require('redis')
// const client = redis.createClient();

// client.on("error", function(error) {s
//   console.error(error);
// });


// client.set("key", "value", redis.print);
// client.get("key", redis.print);
let count = 0

const cal_state = []

let calState = false
// 

const line = require('@line/bot-sdk');

export default function test(req, res) {


    // handle LINE BOT webhook verification
    // The verification message does not contain any event, so length is zero.
    if (req.body.events.length === 0) {
        res.status(200).json({})
        // console.log("hello")
        reply("Hello")   // can reply anything
        return
    }

    let event = req.body.events[0];

    let reply_token = event.replyToken

    let arr = []
    let path = './public/img/logo.png'


    let id = event.source.userId


    if (event.message.type !== 'text') {

        const client = new line.Client({
            channelAccessToken: process.env.CHANNEL_ACCESS_TOKEN
        });

        client.getMessageContent(event.message.id)
            .then((stream) => {
                stream.on('data', (chunk) => {
                    console.log(chunk)
                    arr.push(chunk)
                });

                stream.on('error', (err) => {
                    console.log("Error", err)
                });

                stream.on('end', function () {

                    //fs.writeFile('logo.png', imagedata, 'binary', function(err){

                    var buffer = Buffer.concat(arr)
                    fs.writeFile(path, buffer, function (err) {
                        if (err) throw err
                        console.log('File saved.')
                    })
                })
               
                stream.on('end', function() {
                    readPic()
                })

            });

        reply(reply_token, event.message.type)
        

    } else {
        postToDialogflow(req)
    }

}

function readPic() {
    const image = new Image();
    image.src = './public/img/QR-Code.png'
    if (image.width > image.height) {
      setWidth(600)
      setHeight(400)
    } else if (image.width < image.height) {
      setWidth(450)
      setHeight(600)
    }

    // const canvas = document.getElementById("canvas"); //Able to show picture on webpage
    const canvas = document.createElement('canvas'); //Do not show picture on page
    canvas.width = width
    canvas.height = height 
    const ctx = canvas.getContext('2d');

    let imageDataT = new Uint8ClampedArray()

    image.onload = () => {
      ctx.drawImage(image, 0, 0, canvas.width, canvas.height);
      // console.log('width:', image.width)
      // console.log('height:', image.height)
      imageDataT = ctx.getImageData(0, 0, image.width, image.height);
      console.log(imageDataT);
      const code = jsQR(imageDataT.data, image.width, image.height, 'dontInvert')
      if (code) {
        setQRdata(code.data)
        console.log("Found QR code", code);
        console.log("Result", code.data);
      } else {
        console.log("Do not detect QR-code.")
      }
    }
}

function reply(reply_token, msg) {


    let headers = {
        'Content-Type': 'application/json',
        'Authorization': 'Bearer {' + process.env.CHANNEL_ACCESS_TOKEN + '}'
    }

    // console.log('msg:', msg)
    let body = JSON.stringify({
        replyToken: reply_token,
        messages: [{
            type: 'text',
            text: msg
        }]
    })
    console.log("reply =============> ", body)

    request.post({
        url: 'https://api.line.me/v2/bot/message/reply',
        headers: headers,
        body: body
    }, (err, res, body) => {
        // console.log('status = ' + res.statusCode);

        // console.log("body ====> ", res.body)
    });
}

const postToDialogflow = req => {
    req.headers.host = "dialogflow.cloud.google.com"
    axios({
        url: "https://dialogflow.cloud.google.com/v1/integrations/line/webhook/e8cc963c-2816-4340-892f-f424247eb2f5",
        headers: req.headers,
        method: "post",
        data: req.body
    })
}

错误:

【问题讨论】:

  • 这是在浏览器上运行的吗?还是在nodejs上?浏览器将无法访问 fs 之类的内容
  • Image Web API 仅在浏览器上可用,它在 Node.js 环境中不起作用(在 Next.js API 路由中,或者当您的页面在服务器上预渲染时)。您可以查看this solution 建议创建图像之类的内容。

标签: node.js reactjs image-processing next.js getimagedata


【解决方案1】:
import Image from 'next/image'

为下一个 js 中的图像添加此导入

【讨论】:

    猜你喜欢
    • 2021-03-18
    • 1970-01-01
    • 2022-01-06
    • 2021-10-06
    • 2021-10-17
    • 2020-03-20
    • 2022-01-21
    相关资源
    最近更新 更多