I have the following javascript code, which takes a photo from a webcam and compares it with another photo stored on the server. What I am trying to do is to take the photo from the webcam automatically, without waiting for the user to click on the take photo button. I am just using
document.getElementById('take_snap').click()
but this code is doing nothing. When I click on the button manually my code works perfectly, but the above code doesn't work.
This is my code:
const imageUploads = document.getElementById('take_snap')
const image_url = document.getElementById('results')
var pid=$('#student_id').val();
Promise.all([
faceapi.nets.faceRecognitionNet.loadFromUri('models'),
faceapi.nets.faceLandmark68Net.loadFromUri('models'),
faceapi.nets.ssdMobilenetv1.loadFromUri('models')
]).then(start)
async function start() {
const container = document.createElement('div')
container.style.position = 'relative'
document.body.append(container)
const labeledFaceDescriptors = await loadLabeledImages()
const faceMatcher = new faceapi.FaceMatcher(labeledFaceDescriptors, 0.6)
let image
let canvas
document.body.append('You can start')
imageUploads.click();
imageUploads.addEventListener('click', async () => {
if (image) image.remove()
if (canvas) canvas.remove()
Webcam.snap( function(data_uri) {
// display results in page
document.getElementById('results').innerHTML =
'<img src="'+data_uri+'" id="img_tag"/>';
var filename= upload_img(data_uri)
document.getElementById('results').innerHTML =
'<img src="upload/'+filename+'" id="img_tags"/>';
} );
console.log( document.getElementById('img_tags').getAttribute('src'));
image = await faceapi.fetchImage(document.getElementById('img_tags').getAttribute('src'))
container.append(image)
canvas = faceapi.createCanvasFromMedia(image)
container.append(canvas)
const displaySize = { width: image.width, height: image.height }
faceapi.matchDimensions(canvas, displaySize)
const detections = await faceapi.detectAllFaces(image).withFaceLandmarks().withFaceDescriptors()
const resizedDetections = faceapi.resizeResults(detections, displaySize)
const results = resizedDetections.map(d => faceMatcher.findBestMatch(d.descriptor))
//console.log( 'descriptor'+d.descriptor)
console.log(detections)
results.forEach((result, i) => {console.log('iiiiiiiiiiiii'+i)
const box = resizedDetections[i].detection.box
const drawBox = new faceapi.draw.DrawBox(box, { label: result.toString() })
console.log('resultttt'+ result.toString())
if(result.toString()!=null || result.toString()!='unknown')
{
$('#tamam').show();
}
if(result.toString().indexOf('unknown'))
{
$('#tamam').hide();
}
drawBox.draw(canvas)
})
})
}
as I mentioned above the code works fine when I click on the button manually but it seems that this code not working when using autoclick.
imageUploads.click();
Related
I'm using the current code:
const generatePDF = () => {
const input = document.getElementById("content");
const pdf = new jspdf("p", "pt", "a4");
var canvas = pdf.canvas;
canvas.width = document.body.clientWidth;
pdf.html(input, {
callback: function (pdf) {
pdf.save("mypdf.pdf");
},
});
};
that's what's happening to my pdf
I would like my text to be rightly placed on the pdf
I'm using pdf.js library to render my pdf file on canvas.
First I was searching a solution for rendering pdf with the size of canvas parent element.
I've found it and it works fine.
Then I solve the problem of rendering ALL pages at once.
Finally, my code now looks this way:
pdfjsLib.GlobalWorkerOptions.workerSrc = `//cdnjs.cloudflare.com/ajax/libs/pdf.js/${pdfjsLib.version}/pdf.worker.min.js`;
class PdfLoader {
currPage = 1;
numPages = -1;
doc = null;
constructor($container) {
this.$container = $container;
}
load(path) {
// reset when using more than once
this.currPage = 1;
this.promise = new Promise(resolve => this.promiseResolve = resolve);
this.$container.innerHTML = "";
pdfjsLib.getDocument(path).promise.then(pdf => {
this.doc = pdf;
this.numPages = pdf.numPages;
pdf.getPage(1).then(this._handlePage.bind(this));
});
return this;
}
_handlePage(page) {
let viewport = page.getViewport({scale: 1});
const scale = this.$container.clientWidth/viewport.width;
// const outputScale = window.devicePixelRatio || 1;
const outputScale = 1;
viewport = page.getViewport({scale});
const cnv = document.createElement("canvas");
const ctx = cnv.getContext("2d");
const width = Math.floor(viewport.width);
const height = Math.floor(viewport.height);
cnv.width = Math.floor(width * outputScale);
cnv.height = Math.floor(height * outputScale);
cnv.style.width = `${width}px`;
cnv.style.height = `${height}px`;
const transform = (outputScale !== 1) ? [outputScale, 0, 0, outputScale, 0, 0] : null;
page.render({
canvasContext: ctx,
transform: transform,
viewport: viewport,
});
this.$container.appendChild(cnv);
this.currPage++;
if (this.doc !== null && this.currPage <= this.numPages) {
this.doc.getPage(this.currPage).then(this._handlePage.bind(this));
} else {
this.promiseResolve();
}
}
}
const $pages = document.getElementById("pages");
const pdfLoader = new PdfLoader($pages);
pdfLoader.load("extendedReport.pdf").promise
.then(initReport);
let arrow = null;
function initReport() {
// my other stuff
}
And now my problem is that when viewing rendered pdf it looks like its quality is very low and text is blurred so the document is unreadable on mobile devices. I tried to change passed scale like they say on the internet, but that's not it. Could you help me, plz? What am I missing?
I'm trying to use images off the internet to try and train my network. I'm using an Image() object to create the images and pass them to tensorflow. According to my knowledge, Image() returns a HTMLImageElement, however, I'm still getting the following error:
Error: pixels passed to tf.browser.fromPixels() must be either an HTMLVideoElement, HTMLImageElement, HTMLCanvasElement, ImageData in browser, or OffscreenCanvas, ImageData in webworker or {data: Uint32Array, width: number, height: number}, but was Image
Below is the code I'm running:
const tf = require("#tensorflow/tfjs");
require("#tensorflow/tfjs-node")
const mobilenetModule = require("#tensorflow-models/mobilenet");
const knnClassifier = require("#tensorflow-models/knn-classifier");
const { Image } = require("canvas");
const classifier = knnClassifier.create();
const urls = ["https://upload.wikimedia.org/wikipedia/commons/thumb/7/70/Solid_white.svg/2048px-Solid_white.svg.png", "https://stone.co.nz/wp-content/uploads/2020/06/Iconic-Black.jpg", "https://media.tarkett-image.com/large/TH_25094225_25187225_001.jpg"];
async function start() {
const mobilenet = await mobilenetModule.load();
const pic0 = new Image();
pic0.src = urls[0];
pic0.onload = () => {
const img0 = tf.browser.fromPixels(pic0);
const logits0 = mobilenet.infer(img0, true);
classifier.addExample(logits0, 0);
}
const pic1 = new Image();
pic1.src = urls[1];
pic1.onload = () => {
const img1 = tf.browser.fromPixels(pic1);
const logits1 = mobilenet.infer(img1, true);
classifier.addExample(logits1, 1);
}
const checkPic = new Image();
checkPic.src = urls[2];
checkPic.onload = () => {
const x = tf.browser.fromPixels(checkPic);
const xlogits = mobilenet.infer(x, true);
const p = classifier.predictClass(xlogits);
console.log(p);
}
}
start();
Please note that I am a js/nodejs newbie 😊
Seems like an oversight by TFJS team so Image type is not recognized.
do this instead:
const pic0 = document.createElement('image')
This creates HTMLImageElement which is "almost" the same as Image element, but has a different signature that TF expects
And best to report on TFJS Git as an issue, it should be easy to resolve
I have two functions,
One function converts images from whatever format to canvas, then to WEBP image format.
The other function receives the image and console.log the image.
The problem is that when I log the result of the image in the saveToBackend function, I get a result of undefined, but when I console.log the converted image in the convertImage function, I get the image. Please how can i solve the issue?
Below are the functions in my NUXT app
convertImage(file) {
// 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");
console.log(webpImage); // with this i get the image in the console
return webpImage
}
},
async saveToBackend(file, result) {
// convert images to webp
let webpFile = await this.convertImage(file)
console.log(webpFile); // with this i get undefined in the console
}
You can't return webpImage from inside the onload callback. It simply will not wait for onload to execute. You can instead create a Promise that resolves the value of webpImage when onload completes:
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");
console.log(webpImage); // with this i get the image in the console
// resolve promise so that saveToBackend can await it
return resolve(webpImage);
};
});
}
Hopefully that helps!
i want to draw image next to another in this same div.
Generaly drawing works fine, but i have problem with placing one picture next to another.
Every time i draw image it is placend in this same div.
My HTML is:
<div id="thumbnailImages">
<canvas
id="thumbnailImage"
/>
</div>
And code:
function thumbnail(video) {
const canvasThumbnail = document.getElementById('thumbnailImage')
const cth = canvasThumbnail.getContext('2d')
const data = video.slice(8)
imgToHTML(data, e => {
const drawingThumbnail = new Image()
drawingThumbnail.src = e.target.result
drawingThumbnail.onload = function () {
canvasThumbnail.width = 128
canvasThumbnail.height = 128
cth.drawImage(drawingThumbnail, 0, 0)
document.getElementById('thumbnails').appendChild(canvasThumbnail)
}
})
}
I would like to have many 'canvas' in 'thumbnailImages' id.
Can you help me?
The issue is that you are reusing the same canvas over and over again. You need to create a new canvas to put next to it:
function thumbnail(video) {
const canvasThumbnail = document.createElement('canvas');
const cth = canvasThumbnail.getContext('2d')
const data = video.slice(8)
imgToHTML(data, e => {
const drawingThumbnail = new Image()
drawingThumbnail.src = e.target.result
drawingThumbnail.onload = function () {
canvasThumbnail.width = 128
canvasThumbnail.height = 128
cth.drawImage(drawingThumbnail, 0, 0)
document.getElementById('thumbnailImages').appendChild(canvasThumbnail)
}
})
}