putImageData / Canvas - How do I dump the pixel array in here? - javascript

How do I redraw the pixel array after I after I have previously used getImageData? The way that I thought made sense gives me the error: An invalid or illegal string was specified" code: "12
function makeImage(canvasId, background, object) {
var canvas = document.getElementById(canvasId);
var ctx = canvas.getContext('2d');
var backgroundData = null;
var objectData = null;
//Get image Data
function getDataFromImage(img) {
canvas.width = img.width;
canvas.height = img.height;
ctx.clearRect(0, 0, img.width, img.height);
ctx.drawImage(img, 0 ,0);
return ctx.getImageData(0, 0, img.width, img.height);
}
//Load image
function loadImage(src, callback) {
var img = document.createElement('img');
img.onload = callback;
img.src = src;
return img;
}
//Get Background Image Data
var backgroundImg = loadImage(background, function() {
backgroundData = getDataFromImage(backgroundImg);
ctx.clearRect(0, 0, canvas.width, canvas.height);
});
//Get Object Image Data
var objectImg = loadImage(object, function() {
objectData = getDataFromImage(objectImg);
ctx.clearRect(0, 0, canvas.width, canvas.height);
});
main();
function main() {
ctx.putImageData(backgroundData, 0, 0); //Try to redraw the background??
}
};

I think you might need to put the
main()
call inside the loadImage call that is populating backgroundData. It could be that main is called before the image has loaded.
var backgroundImg = loadImage(background, function() {
backgroundData = getDataFromImage(backgroundImg);
ctx.clearRect(0, 0, canvas.width, canvas.height);
main();
});

Related

getImageData() array is returning all 0s in angular 5

I am trying to get the rgb value of an image after I render the image inside canvas. However I am getting all 0s in return. I am trying to use getImageData() after I render the image not sure why I am getting 0s in return.
My Code :
fileSelected: File;
preview: any;
context: CanvasRenderingContext2D;
hue: any;
myImageData:any
onFileSelect(e: any) {
let canvas = this.mycanvas.nativeElement;
let context = canvas.getContext('2d');
context.clearRect(0, 0, canvas.width, canvas.height)
let imgData;
this.fileSelected = e.target.files[0];
let reader = new FileReader()
reader.onload = (e: any) => {
var image = new Image();
image.onload = function () {
image.width = canvas.width;
image.height = canvas.height;
context.drawImage(image, 0, 0, canvas.width, canvas.height)
};
image.src = e.target.result
}
reader.readAsDataURL(this.fileSelected);
this.myImageData = context.getImageData(0, 0, 100, 100);
this.hue = this.calculateHue(this.fileSelected, this.myImageData);
}
calculateHue(file, myImageData) {
console.log("rgb====", myImageData.data)
return null
}
I have gone through these links getImageData() returning all zeros, getImageData() returning all 0's, getImageData always returning 0
But none of the answers solved it. What am I doing wrong?
You're writing to the canvas as soon as the image is loaded, however you're trying to read from the canvas as soon as a file is selected, move:
this.myImageData = context.getImageData(0, 0, 100, 100);
this.hue = this.calculateHue(this.fileSelected, this.myImageData);
into the image.onload and after the context.drawImage(image, 0, 0, canvas.width, canvas.height) call so you're sure there is image data that you can read.
It should look something like this:
onFileSelect(e: any) {
let canvas = this.mycanvas.nativeElement;
let context = canvas.getContext('2d');
context.clearRect(0, 0, canvas.width, canvas.height)
let imgData;
this.fileSelected = e.target.files[0];
let reader = new FileReader();
let self = this;
reader.onload = (e: any) => {
var image = new Image();
image.onload = () => {
image.width = canvas.width;
image.height = canvas.height;
context.drawImage(image, 0, 0, canvas.width, canvas.height)
// Move it here
self.myImageData = context.getImageData(0, 0, 100, 100);
self.hue = this.calculateHue(self.fileSelected, self.myImageData);
};
image.src = e.target.result
}
reader.readAsDataURL(this.fileSelected);
}

Get Return Value From Variable in JavaScript [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 6 years ago.
I have JavaScript function which check the image is null or not and call the function to convert the image to base64 string, but after converting image also I can't able to return that variable value always shows undefiend.updateUserDetails its an onclick function, help me to solve it.
var userImgData;
function updateUserDetails() {
if (userImgData === "undefined") {
ImgData = (document.getElementById("userProfileImage"));
getUserBase64Image(ImgData.src)
}
updateDetails(userImgData)
}
function updateDetails(userImgData )
{
//i am calling ajax to update
}
function getUserBase64Image(img) {
var i = img;
var canvas = document.createElement('canvas'),
ctx = canvas.getContext('2d'),
img = new Image();
img.onload = function () {
canvas.width = img.width;
canvas.height = img.height;
if (canvas.width > canvas.height) {
canvas.style.width = "320px";
} else {
canvas.style.height = "300px";
}
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
var dataURl = (canvas.toDataURL('image/jpeg'));
userImgData = dataURl.replace("data:image/jpeg;base64,", " ")
return userImgData ;
}
img.src = img;
}
onload function is asynchronous, you can solve this problem using call back as follow :
function updateDetails(customerImgData,CB)
{
//i am calling ajax to update
}
function getUserBase64Image(img) {
var i = img;
var canvas = document.createElement('canvas'),
ctx = canvas.getContext('2d'),
img = new Image();
img.onload = function () {
canvas.width = img.width;
canvas.height = img.height;
if (canvas.width > canvas.height) {
canvas.style.width = "320px";
} else {
canvas.style.height = "300px";
}
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
var dataURl = (canvas.toDataURL('image/jpeg'));
userImgData = dataURl.replace("data:image/jpeg;base64,", " ");
CB(userImgData);
return userImgData ;
}
img.src = img;
}
function updateUserDetails(imageData){
//you will get image data here in variable "imageData",
//put your code here.
}
updateUserDetails(customerImgData,updateUserDetails);//function call.

Why are pixels retrieved from canvas all black?

As an exercise, I would like to fill the background of the browser window with pixels of random color: https://jsfiddle.net/j8fay7bs/3/
My question is how to retrieve the current filling of the background image and randomly change the pixels? Currently the image seems to be reverted to black.
// redraw canvas pixels on resize --------------------------
var render = function resize() {
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
context.canvas.width = window.innerWidth;
context.canvas.height = window.innerHeight;
var imageData = context.getImageData(0, 0, canvas.width, canvas.height);
var t0 = performance.now();
for (var i = 0; i < canvas.width*canvas.height; i++) {
if (Math.random() < 0.5) {
imageData.data[i*4] = Math.round(Math.random()*255);
imageData.data[i*4+1] = Math.round(Math.random()*255);
imageData.data[i*4+2] = Math.round(Math.random()*255);
imageData.data[i*4+3] = 255;
}
}
context.putImageData(imageData, 0, 0);
$('#fps').text(1000/(performance.now() - t0) + " fps");
}
window.onresize = render;
// rendering loop ---------------------------------------
(function loop() {
setInterval(render, 10);
})();
You may retrieve the last image data before u touch the canvas width and height,
once u touched them, the canvas will be reset:
var render = function resize() {
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
var oldImageData = context.getImageData(0, 0, canvas.width, canvas.height); // <----
context.canvas.width = window.innerWidth;
context.canvas.height = window.innerHeight;
var imageData = context.getImageData(0, 0, canvas.width, canvas.height);
updated fiddle

Converting data URI to image data

/**
* Converts data URI in 'image/png' format to an image data object
* #param dataURL Base64 encoded string
* #returns {ImageData/undefined}
*/
convertDataURLToImageData: function (dataURL) {
if (dataURL !== undefined && dataURL !== null) {
var canvas, context, image, imageData;
canvas = document.createElement('canvas');
canvas.width = 470;
canvas.height = 470;
context = canvas.getContext('2d');
image = new Image();
image.addEventListener('load', function(){
context.drawImage(image, 0, 0, canvas.width, canvas.height);
imageData = context.getImageData(0, 0, canvas.width, canvas.height);
//how do i return this?
}, false);
image.src = dataURL;
return imageData;
}
}
considering the snippet above, if I would like to get an array of image data from a data URL I wold draw it on a canvas , how do I return the image data?
The problem is that your function is asynchronous, because you are waiting for the load event.
Then, you could use promises:
function convertURIToImageData(URI) {
return new Promise(function(resolve, reject) {
if (URI == null) return reject();
var canvas = document.createElement('canvas'),
context = canvas.getContext('2d'),
image = new Image();
image.addEventListener('load', function() {
canvas.width = image.width;
canvas.height = image.height;
context.drawImage(image, 0, 0, canvas.width, canvas.height);
resolve(context.getImageData(0, 0, canvas.width, canvas.height));
}, false);
image.src = URI;
});
}
var URI = "data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAQAQAABMLAAATCwAAAAAAAAAAAABsiqb/bIqm/2yKpv9siqb/bIqm/2yKpv9siqb/iKC3/2yKpv9siqb/bIqm/2yKpv9siqb/bIqm/2yKpv9siqb/bIqm/2yKpv9siqb/bIqm/2yKpv9siqb/2uLp///////R2uP/dZGs/2yKpv9siqb/bIqm/2yKpv9siqb/bIqm/2yKpv9siqb/bIqm/2yKpv9siqb/bIqm/////////////////+3w9P+IoLf/bIqm/2yKpv9siqb/bIqm/2yKpv9siqb/bIqm/2yKpv9siqb/bIqm/2yKpv///////////+3w9P+tvc3/dZGs/2yKpv9siqb/bIqm/2yKpv9siqb/TZbB/02Wwf9NlsH/TZbB/02Wwf9NlsH////////////0+Pv/erDR/02Wwf9NlsH/TZbB/02Wwf9NlsH/TZbB/02Wwf9NlsH/TZbB/02Wwf9NlsH/TZbB//////////////////////96sNH/TZbB/02Wwf9NlsH/TZbB/02Wwf9NlsH/TZbB/02Wwf9NlsH/TZbB/02Wwf////////////////+Ft9T/TZbB/02Wwf9NlsH/TZbB/02Wwf9NlsH/E4zV/xOM1f8TjNX/E4zV/yKT2P/T6ff/////////////////4fH6/z+i3f8TjNX/E4zV/xOM1f8TjNX/E4zV/xOM1f8TjNX/E4zV/xOM1f+m1O/////////////////////////////w+Pz/IpPY/xOM1f8TjNX/E4zV/xOM1f8TjNX/E4zV/xOM1f8TjNX////////////T6ff/Tqng/6bU7////////////3u/5/8TjNX/E4zV/xOM1f8TjNX/AIv//wCL//8Ai///AIv/////////////gMX//wCL//8gmv////////////+Axf//AIv//wCL//8Ai///AIv//wCL//8Ai///AIv//wCL///v+P///////+/4//+Axf//z+n/////////////YLf//wCL//8Ai///AIv//wCL//8Ai///AIv//wCL//8Ai///gMX/////////////////////////////z+n//wCL//8Ai///AIv//wCL//8Ai///AHr//wB6//8Aev//AHr//wB6//+Avf//7/f/////////////v97//xCC//8Aev//AHr//wB6//8Aev//AHr//wB6//8Aev//AHr//wB6//8Aev//AHr//wB6//8Aev//AHr//wB6//8Aev//AHr//wB6//8Aev//AHr//wB6//8Aev//AHr//wB6//8Aev//AHr//wB6//8Aev//AHr//wB6//8Aev//AHr//wB6//8Aev//AHr//wB6//8Aev//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==";
convertURIToImageData(URI).then(function(imageData) {
// Here you can use imageData
console.log(imageData);
});
var img = new Image;
img.src = strDataURI;
try this hope u will understand ..

How to redraw canvas (every 250ms) without flickering between each redraw?

I wrote a function that draws out a slice of a pizza based on how big you specify it to be (in degrees)
function drawProgress(degs){
var canvas = document.getElementById('progress');
var context = canvas.getContext('2d');
context.globalAlpha=1;
var img = new Image();
img.onload = function(){
context.beginPath();
context.arc(canvas.width/2,canvas.height/2, canvas.height/2, 0, degs * (-Math.PI/180), true);
context.lineTo(canvas.width/2, canvas.height/2);
context.clip();
context.drawImage(img, 0, 0, canvas.width,canvas.width);
}
img.src = 'pizza.png';
}
When I try to call this function every 250ms, the progress is not updated after the first draw.
function runsEvery250ms(percent){
drawProgress(3.6 * percent);
}
What changes do I need to make to the code to get the canvas to redraw each time drawProgress(degs) is called? Is it possible to perform redraws without causing the pizza to flicker?
Use context.clearRect(0, 0, canvas.width, canvas.height); and cache your image, don't reload each time you refresh
UPDATE: No idea if this will work, untested and been a while since I used canvas but try it
var canvas = document.getElementById('progress');
var context = canvas.getContext('2d');
var img = new Image();
var imgLoaded = false;
img.src = 'pizza.png';
img.onload = function(){
imgLoaded = true;
}
function drawProgress(degs){
context.save();
context.clearRect(0, 0, canvas.width, canvas.height);
context.globalAlpha=1;
context.beginPath();
context.arc(canvas.width/2,canvas.height/2, canvas.height/2, 0, degs * (-Math.PI/180), true);
context.lineTo(canvas.width/2, canvas.height/2);
context.clip();
if (imgLoaded) context.drawImage(img, 0, 0, canvas.width,canvas.width);
context.restore();
}

Categories

Resources