When I run tesseract.js on a URL it works fine. But when I run it on a local file I get these errors. How can I solve this?
I am running tesseract.js v2.1.0 and here is my code:
const { createWorker } = require('tesseract.js');
const worker = createWorker({
logger: m => console.log(m), // Add logger here
});
(async () => {
await worker.load();
await worker.loadLanguage('eng');
await worker.initialize('eng');
const { data: { text } } = await worker.recognize('download.png');
console.log(text);
await worker.terminate();
})();
If you want to load local images in tesseract you have to load them via input tag, Here is the working example.
HTML
<input type="file" id="input_image" accept="image/*">
JavaScript
const input_image = document.getElementById("input_image");
const offscreen_canvas = new OffscreenCanvas(0, 0);
const offscreen_canvas_context = offscreen_canvas.getContext("2d");
input_image.addEventListener("change", () => {
var file = input_image.files[0];
if (file == undefined) return;
var reader = new FileReader();
reader.onload = function (event) {
const reader_image = event.target.result;
const image = new Image();
image.onload = function () {
offscreen_canvas.width = image.width;
offscreen_canvas.height = image.height;
offscreen_canvas_context.drawImage(image, 0, 0);
offscreen_canvas.convertToBlob().then((blob) => {
Tesseract.recognize(blob, "eng", {
logger: (m) => console.log(m)
}).then(({ data: { text } }) => {
console.log(text);
});
});
};
image.src = reader_image;
};
reader.readAsDataURL(file);
});
Related
The problem is when i do no not see the form data in the console. I do not know what is wrong. here is the code:
So I got firstly the nodes and tried to create a function thta reads the file and a function that returns a src that would be stored in the readForm data function
//nodes
const mainContainer = document.getElementById("main");
const postTitleNode = document.getElementById("postTitle");
const postDateNode = document.getElementById("postDate");
const postFileNode = document.getElementById("postFile");
const postContentNode = document.getElementById("postContent");
//image file reader
function readImageFile(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.addEventListener("load", () => {
resolve(reader.result);
});
reader.addEventListener("error", () => {
reject(reader.error);
});
reader.readAsDataURL(file);
});
}
//reading the src of the image uploaded
function readFileSrc(elementNode) {
return new Promise((resolve, reject) => {
elementNode.addEventListener("change", async () => {
const file = elementNode.files[0];
if (file.type.startsWith("image/")) {
const dataUrl = await readImageFile(file);
postFileNode.value = dataUrl;
resolve(dataUrl);
} else {
console.error("Selected file is not an image.");
reject("Selected file is not an image.");
}
});
});
}
//clear form data
function clearInputValue() {
postTitleNode.value = "";
postDateNode.value = "";
postFileNode.value = "";
postContentNode.value = "";
}
//get form Data
async function readFormData() {
//values: store the values in an object
const postFile = await readFileSrc(postFileNode);
const formData = {
title: postTitleNode.value,
postDate: postDateNode.value,
postFile: postFile,
postContent: postContentNode.value,
};
console.log(formData);
return formData;
}
//onClick function
async function onClickEvent() {
//read data
await readFormData();
//clear data after clicking
clearInputValue();
}
//buttons
const createPostButton = document.getElementById("modalCreatePostButton");
createPostButton.addEventListener("click", onClickEvent);
what can I do to solve the problem or where is my mistake? why am i not getting any data in the console
i am trying to make a component that take a pdf from input or an already uploaded one and then extract pages from it and uploaded again
when choosing a file from input (choosing file from my computer)
i am using this
const handleFileChange = async (event) => {
const file = event.target.files[0];
setFiles(event.target.files[0])
const fileName = event.target.files[0].name
setFileName(fileName);
const fileReader = new FileReader();
fileReader.onload = async () => {
const pdfBytes = new Uint8Array(fileReader.result);
const pdfDoc = await PDFDocument.load(pdfBytes);
setPdfDoc(pdfDoc);
setPdfBlob(pdfBytes)
};
fileReader.readAsArrayBuffer(file);
setShowPdf(true)
};
we get a pdfDoc and a Unit8Array
then i use the pdfDoc to get pages and extract a new pdf file....
this works fine
now when selecting a file that we already uploaded
i use this to ping the api to get the file
const handleGetFile = async (url) => {
const headers = {
Authorization: "Bearer " + (localStorage.getItem("token")),
Accept: 'application/pdf'
}
await axios.put(`${process.env.NEXT_PUBLIC_API_URL}getPdfFileBlob`, {
pdfUrl: `https://handle-pdf-photos-project-through-compleated-task.s3.amazonaws.com/${url}`
}, { responseType: 'arraybuffer', headers }).then((res) => {
const handlePdf = async () => {
const uint8Array = new Uint8Array(res.data);
const pdfBlob = new Blob([uint8Array], { type: 'application/pdf' });
setPdfBlob(uint8Array)
// setPdfDoc(pdfBlob) .....? how do i create a pdf doc from the unit8array
}
handlePdf()
}).catch((err) => {
console.log(err)
})
}
this the the end point i am pinging
app.put('/getPdfFileBlob',async function(req,res){
try {
console.log(req.body.pdfUrl)
const url =req.body.pdfUrl;
const fileName = 'file.pdf';
const file = fs.createWriteStream(fileName);
https.get(url, (response) => {
response.pipe(file);
file.on('finish', () => {
file.close();
// Serve the file as a response
const pdf = fs.readFileSync(fileName);
res.setHeader('Content-Type', 'application/pdf');
res.setHeader( 'Content-Transfer-Encoding', 'Binary'
);
res.setHeader('Content-Disposition', 'inline; filename="' + fileName + '"');
res.send(pdf);
});
});
} catch (error) {
res.status(500).json({success:false,msg:"server side err"})
}
})
after getting this file here is what am trying to do
const handlePageSelection = (index) => {
setSelectedPages(prevSelectedPages => {
const newSelectedPages = [...prevSelectedPages];
const pageIndex = newSelectedPages.indexOf(index);
if (pageIndex === -1) {
newSelectedPages.push(index);
} else {
newSelectedPages.splice(pageIndex, 1);
}
return newSelectedPages;
});
};
const handleExtractPages = async () => {
for (let i = pdfDoc.getPageCount() - 1; i >= 0; i -= 1) {
if (!selectedPages.includes(i + 1)) {
pdfDoc.removePage(i);
}
}
await pdfDoc.save();
};
well in the first case where i upload the pdf file from local storage i get a pdfDoc
console of pdf Doc and pdfBlob
and when i select already existing file i can't find a way to transfer unit8array buffer to pdf doc
log of pdfBlob and no pdf doc
what i want is transform the pdfblob to pdfDcoument or get the pdf document from the array buffer so i can use getpages on it
I need to store one image and text in clipboard. I'd like to use Clipboard API. Is it possible?
I'm using following sample to store Image or Text but is it possible to combine?
copyImgBtn.addEventListener('click', async () => {
const response = await fetch(img.src)
const blob = await response.blob()
const blob1 = new Blob([textarea.value], { type: 'text/plain' })
var data = [new ClipboardItem({[blob.type] : blob})]
navigator.clipboard.write(data).then(function() {
console.log("Copied to clipboard successfully!");
}, function() {
console.error("Unable to write to clipboard. :-(");
})
}
)
Thank you
As you cannot write multiple ClipBoardItems at once, I used a single text/html blob.
(Note that the below snippet will not run here, because of browser permissions policy)
I found the blobToBase64 function here: https://stackoverflow.com/a/18650249/91017
Hope this helps,
Koen
async function copyToClipboard() {
const imageUrl = 'https://i.picsum.photos/id/739/200/300.jpg?hmac=xApsFbHx511SUVG612QiltrATotVTYu3Q4wfvGyYC1g';
try {
const imageData = await fetch(imageUrl);
const imageBlob = await imageData.blob();
const imageBase64Data = await blobToBase64(imageBlob);
const html =
`<p>Some text</p>
<p><img src="${imageBase64Data}" alt="Some image"></p>`;
const textBlob = new Blob([html], {
type: 'text/html'
});
await navigator.clipboard.write([
new ClipboardItem({
[textBlob.type]: textBlob
})
]);
console.log('Copied.');
} catch (err) {
console.error(err.name, err.message);
}
}
function blobToBase64(blob) {
return new Promise((resolve, _) => {
const reader = new FileReader();
reader.onloadend = () => resolve(reader.result);
reader.readAsDataURL(blob);
});
}
<button onclick="copyToClipboard()">Copy text and image to clipboard</button>
implementing tensorflow with posenet into my expo project so once a user hits a certain pose it would result in the camera to take a picture and then user can press a button to upload it firebase. As soon as I open the camera I'm getting an error saying [Unhandled promise rejection: Error: FileReader.readAsArrayBuffer is not implemented]. Odd thing is that nowhere in my code am I calling FileReader. I am using blob but that is to upload firebase but that is not triggered until a user pushes a button.
I am not even able to get the canvas to draw on the user or for posenet to console.log info such as users nose, ears, and so on. What am doing incorrectly?
Code that I have so far:
import * as tf from '#tensorflow/tfjs';
import * as posenet from "#tensorflow-models/posenet";
import { drawKeypoints, drawSkeleton } from "../utils/TfDrawingUtli";
import Canvas from 'react-native-canvas';
const cameraRef = useRef();
const canvasRef = useRef();
const [TfReady, setTfReady] = useState(true);
// tensor flow pose net
const runPosenet = async () => {
const net = await posenet.load({
architecture: 'MobileNetV1',
outputStride: 16,
inputResolution: { width: 640, height: 480 },
multiplier: 0.75
});
setInterval(() => {
detect(net);
}, 100);
};
const detect = async (net) => {
if (cameraRef.current) {
// Get Video Properties
const video = cameraRef.current;
const videoWidth = cameraRef.current.videoWidth;
const videoHeight = cameraRef.current.videoHeight;
// Set video width
cameraRef.current.width = videoWidth;
cameraRef.current.height = videoHeight;
// Make Detections
const pose = await net.estimateSinglePose(video);
console.log(pose);
drawCanvas(pose, video, videoWidth, videoHeight, canvasRef);
}
};
// drawing a canvas
const drawCanvas = (pose, video, videoWidth, videoHeight, canvas) => {
const ctx = canvas.current.getContext("2d");
canvas.current.width = videoWidth;
canvas.current.height = videoHeight;
drawKeypoints(pose["keypoints"], 0.5, ctx);
drawSkeleton(pose["keypoints"], 0.5, ctx);
};
runPosenet();
useEffect(() => {
(async () => {
// tensorflow
await tf.ready();
setTfReady(true);
console.log(` ======= TF is ready ==== ${TfReady} =======`)
}
)();
}, []);
upload to firebase code
const uploadImageAsync = async (uploadToFirebase) => {
var user = firebase.auth().currentUser.uid;
const blob = await new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.onload = function () {
resolve(xhr.response);
};
xhr.onerror = function (e) {
console.log(e);
reject(new TypeError('Network request failed'));
};
xhr.responseType = 'blob';
xhr.open('GET', uploadToFirebase, true);
xhr.send(null);
});
const ref = firebase
.storage()
.ref(user)
.child('test image')
const snapshot = await ref.put(blob);
blob.close();
return await snapshot.ref.getDownloadURL();
};
code inside return()
<Camera ref={cameraRef} />
<Canvas ref={canvasRef} />
Initially, I have made loading here so like this
export function сonvertFilesToByteArray(e) {
const MAX_FILE_SIZE = 1024 * 1024 * 50; // 50MB
const files = Object.keys(e.target.files);
const asyncReadFile = eachFile =>
new Promise((resolve, reject) => {
if (e.target.files[eachFile].size > MAX_FILE_SIZE) {
return reject([{ message: `File ${e.target.files[eachFile].name} too large` }]);
}
const reader = new FileReader();
const targetFileInfo = {
contentType: e.target.files[eachFile].type,
filename: e.target.files[eachFile].name,
};
reader.readAsArrayBuffer(e.target.files[eachFile]);
reader.onload = () => {
resolve({ ...targetFileInfo, body: Array.from(new Uint8Array(reader.result)) });
};
reader.onerror = error => reject(error);
});
return Promise.all(files.map(asyncReadFile));
}
Here in the constant files, I define how many at my files and I apply a function to each of them.
And then I get my file(s) in the component
handleFileUpload = (e) => {
сonvertFilesToByteArray(e)
.then((result) => {
runInAction(() => {
this.files = [
...this.files,
...result,
];
});
})
.catch(err => runInAction(() => {
this.errors = [...this.errors, err[0].message];
}));
}
And put in this.files and finally my this.files looks like [{contentType: 'plain/text', filename: 'blabla', body: [123, 456, 23, ...] }]
Where [123, 456, 23...] there is my ArrayBuffer
But at such approach in spite of the fact that I use Promise.all, when loading files/files which have weight more ~ 2MB, the page is frozen, it is impossible to interact with her in any way (but I can scroll). Except as realization when each file are divided into chunks nothing has come to mind to correct a situation.
Ok, I try to rewrite the code: With chunks
export function сonvertFilesToByteArray(e) {
const MAX_FILE_SIZE = 1024 * 1024 * 50; // 50MB
const files = Object.keys(e.target.files);
const asyncReadFile = eachFile =>
new Promise((resolve, reject) => {
if (e.target.files[eachFile].size > MAX_FILE_SIZE) {
return reject([{ message: `File ${e.target.files[eachFile].name} too large` }]);
}
const file = e.target.files[eachFile];
let offset = 0;
console.log(offset, 'offset', file.size, 'size');
const defaultChunkSize = 64 * 1024; // bytes
const fileReader = new FileReader();
const blob = file.slice(offset, offset + defaultChunkSize);
const isEndOfFile = () => offset >= file.size;
const testEndOfFile = () => {
if (isEndOfFile()) {
console.log('Done reading file');
}
};
fileReader.readAsArrayBuffer(blob);
fileReader.onloadend = (event) => {
const target = (event.target);
if (target.error == null) {
const result = target.result;
offset += result.length;
testEndOfFile();
console.log(result, 'result');
resolve(result);
} else {
reject(target.error);
}
};
});
return Promise.all(files.map(asyncReadFile));
}
Here I receive the file and I divide it. But the problem is that if the file is more than a chunk, then I should bring together him from them again and again. But how to make it in my case? I can't understand it in any way...
Please help me :) What it is necessary to make to read the file in chunks and to receive it as ArrayBuffer?