2

I am developing the linebot to receive picture with QR-code. As you can see on below code I have already success to save file in to local folder as 'logo.png' in stream.on('end' , ...)

Then I want to use that recently save file to detect QR-code by this npm library. (https://www.npmjs.com/package/jsqr)

Then I have create function readPic() to pass imgPath and use that picture to detect QR-code.

My problem is that const image = new Image(); have an error called 'Image is not defined'

How can I fix this? or if there is an alternative ways to get imageData from picture to be used in jsQR() without using canvas.

My code:

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
    })
}

Error: Error

faijiuy
  • 55
  • 1
  • 9
  • https://stackoverflow.com/questions/62180774/how-to-display-an-image-saved-as-blob-in-react – fardown Jul 10 '21 at 03:55
  • is this running on a browser? or on nodejs? a browser wont have access to things like `fs` – alilland Jul 10 '21 at 05:12
  • The [`Image` Web API](https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/Image) is only available on the browser, it won't work in Node.js environments (in Next.js API routes, or when your page gets pre-rendered on the server). You could look into something like [this solution](https://stackoverflow.com/a/9548360/1870780) suggests to create an image. – juliomalves Jul 11 '21 at 10:57

3 Answers3

2
import Image from 'next/image'

add this import for images in next js

Salil Rajkarnikar
  • 588
  • 1
  • 7
  • 26
1

The Image constructor is equivalent to document.createElement('img'). Since you're running your code in Node, the document is undefined. Simply provide an env check, something like this :

 if (
    typeof window === 'undefined' ||
    typeof document === 'undefined' 
  ) return
0
  1. Import Image from next. That is

import Image from 'next/image';

  1. Follow the syntax for adding image

Ex -

<Image class = "logo" src={ekl_logo}  alt="Ekl Logo" width="350px" height="300px"/>

Reference Link : https://medium.com/nextjs/how-to-add-an-image-in-next-js-5c1065450e3a

My code below :

import Image from 'next/image';
import ekl_logo from "../public/logo.png";

export default function Home() {
  return (
    <div>

      <header>
      <Image class = "logo" src={ekl_logo}  alt="Ekl Logo" width="350px" height="300px"/>
      <nav>
          <ul class = "nav__links ">
              <li> <a href="#">Services</a> </li>
              <li> <a href="#">Projects</a> </li>
              <li> <a href="#">About</a> </li>
          </ul>
      </nav>
      </header>

    </div>
  )
}
Mounesh
  • 561
  • 5
  • 18