0

I really need some help, I'm new to coding and I'm trying to make a script

The script is supposed to achieve the following:

  1. Takes a picture
  2. Finds text within the image using tesseract
  3. Search for a specific string within the text founded
  4. Preforms an action based on if the specific string has been found or not

The problem I am having is that every time I run the script, it uses the previous version of the image saved, giving me the wrong result at the time.

I could really use some help.

const robot = require('robotjs')
const Jimp = require('jimp')
const Tesseract = require('tesseract.js');
const { Console, log } = require("console");
const fs = require('fs');
const {readFileSync, promises: fsPromises} = require('fs');
const { resolve } = require('path');


const myLogger = new Console({
  stdout: fs.createWriteStream("normalStdout.txt")
});

const myLogger2 = new Console({
    stdout: fs.createWriteStream("normalStdout2.txt")
});

//////////////////////////////////////////////////////////////////////////////////////////

function main(){
  sleep(2000);
  performRead();   
}

//Edited function to sync instead of async - The problem is still persisting
//Edited function to include tesseractimage() in callback of writeimage()

function writeImage(){
                  
                    var width = 498;
                    var height = 135;
                    var img4 = robot.screen.capture(0, 862, width, height).image;
                    new Jimp({data: img4, width, height}, (err, image) => {
                      image.write("image.png", function() {
                        tesseractimage();
                        
                    });
                    
                    });
                    
                    console.log("Image 1 created");
                    
                    
                }

              
         function tesseractimage(){
            
                    Tesseract.recognize("image.png", 'eng')
                    .then(out => myLogger.log(out));
                    //Saves image to normalstdOut.txt

                    console.log("Tesseracted image")
                }
                   
                

          function readTest(normalStdout, Viverz) {
                  var path = require('path');
                  const contents = readFileSync(path.resolve("normalStdout.txt"), 'utf-8');
                  const result = contents.includes("Viverz");
                  
                  console.log(result);
                  
                }

//Edited performRead removing the call for tesseractimage();, it is now in writeimage();
function performRead(){
 
    writeImage();
    readTest();
    
  }



function sleep(ms){
        Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
        return null;
    }

main();

I have tried changing functions to async functions, I've tried numerous methods, pauses, reiterations of functions multiple times, nothing saves the file until the script ends and then after it finds the correct string from the previously saved screenshot, not the new one.

Current output: Image 1 created a false Tesseracted image

Even when forcing tesseractimage() to call before the result is published it still has the same problem of not reading the file until the script is over

Ahmad Othman
  • 853
  • 5
  • 18
  • Call `tesseractimage()` within the callback function of `image.writeAsync` or change it to write synchronously instead. At the moment, the image is written asynchronously, so the tesseractimage function gets called before the writing process has finished. – Geshode Dec 22 '22 at 08:28
  • Thank you for the fast response sir! I will try this now and respond with an edit in this comment :) – Kelvin gaston Dec 22 '22 at 08:35
  • I'm afraid i haven't been able to work out how to call tesseractimage() within the callback of image.writeAsync, i tried many alternatives just then to test but i wasn't successful – Kelvin gaston Dec 22 '22 at 08:50

2 Answers2

0

One way to call tesseractimage() from writeImage() when using image.write():

new Jimp({data: img4, width, height}, (err, image) => {
    image.write("image.png", function() {
        tesseractimage();
    });
});

One way to call tesseractimage() from writeImage() when using image.writeAsync():

new Jimp({data: img4, width, height}, (err, image) => {
    image.writeAsync("image.png")
        .then((result) => {
            tesseractimage();
        }).catch((error) => {
            // Handle error
        })
});

Also remove the function call from within performRead().

For reference look under "Writing to files and buffers".

Geshode
  • 3,600
  • 6
  • 18
  • 32
  • Thank you again for your replies mate, much appreciated I updated the code in the OP with edits made again, the problem is still persisting however the code is working without errors, but the order is a little messed up "Image 1 created-> false-> Tesseracted image" But i did manage to fix the output order. The problem of it only reading the file saved previously is still persisting. I also tried using the Async version you posted, for similar results to above ^ – Kelvin gaston Dec 22 '22 at 09:51
  • I feel like my code is reading backwards the more i play with it, try coding they said, it'll be fun they said *Edit I do love coding – Kelvin gaston Dec 22 '22 at 11:16
0

Solved** I removed the readTest() altogether, and restructured the tesseractimage to a new function

async function tesseracttest() {
  const finalText = await Tesseract.recognize(
    "image.png",
    'eng',
    { logger: m => console.log(m) }
  ).then(({ data: { text } }) => {
    let extractedText = text.toString();
    let finalText = extractedText.includes("Prayer potion");
    console.log(extractedText)
    console.log(finalText);
    return finalText;
  });
}   
Tyler2P
  • 2,324
  • 26
  • 22
  • 31