How to draw Images canvas at faster rate from websocket onmessageevent - html5-canvas

I have written a websocket implementation for image transfer from server to javascript client.
In the client side on the event this.webSocket.onmessage we are receiving a png image as base64 and we write as below to display.
if (bIsPngFormat) {
// Draw the image onto canvas using image.onload event
var myImage = new Image();
myImage.onload = () => {
this.ctx.drawImage(myImage, 0, 0);
}
myImage.src = "data:image/png;base64," + renderableImage
}
But the display is not refreshing even through the event is fired at the rate of 90 frames/sec
Just want to know why canvas is not getting refreshed with new incoming image when it comes very fast.
Will it work better when used canvas with openGL context or directly send the RGBA buffer (instead of base64 png) and rendered using below code
Code:
// Apply the uint8array buffer received from websocket onmessage
var iData = new ImageData(new Uint8ClampedArray(renderableImage), width, height);
this.ctx.putImageData(iData, 0, 0);"
Thanks in advance.

Related

In Flutter, how to associate device pixel ratio with a canvas created from scratch?

I'm using the following code snippet to record and get an image from a canvas. The image shows fuzzy on some devices.
setLayerBuffer(int layerID) async {
recorder = new ui.PictureRecorder();
canvas2 = new Canvas(recorder, canvasRect); //canvasRect is the drawing area
for (var myLayer in layers)
if (myLayer.id == layerID) {
if (myLayer.buffer != null) {
canvas2.drawImage(myLayer.buffer, new Offset(0.0, 0.0), Paint());
}
doPaint(canvas2, 1); //this will draw on canvas2
break;
}
var picture = recorder.endRecording();
buffer = await picture.toImage(
canvasRect!.width.round(), canvasRect!.height.round());
setBuffer(layerID, buffer!); // store image as buffer in layer
paintController.myNotifyListeners(); //paint the main canvas wiht buffers of layers
}
According to this https://github.com/flutter/flutter/issues/17782, the canvas created from scratch is not being set with device pixel ratio unlike the canvas created by CustomPaint.
I did try to set canvas scale with device pixel ratio as suggested by the above link. However, the image disappears after setting the scale. How do I set the canvas to use the device pixel ratio ?

How to display an image offline using Famo.us

How can you display an image that can be used offline using Famo.us?
A Famo.us Image surface sets it's content based on an image URL. However, when offline, this URL will not work. I have tried using an HTTP request and converting the buffer to a Blob and then creating a URI for the Blob:
// bytes = request.buffer of HTTP request
// Make a Blob from the bytes
var blob = new Blob([bytes], {type: 'image/jpg'});
// Use createObjectURL to make a URL for the blob
imageURL = URL.createObjectURL(blob);
//Use Famo.us image surface API to display the image (http://famo.us/docs/api/latest/surfaces/ImageSurface)
imageSurface.setContent(imageURL);
This does not throw any warning or errors but displays a broken image. Any suggestions? I want to display an image even when I am offline, but when I reconnect I will request for the newest image uploaded.
ImageSurface in Famo.us can take a url to the image or the base-64 encoded data.
Using Blob:
Use the file reader to readAsDataURL
var reader = new FileReader();
reader.onloadend = function () {
imageURL = reader.result;
}
reader.readAsDataURL(blob);
Using Canvas:
There are plenty of ways to get the encoded base-64 data. Canvas has another way to get this string for you.
Example jsBin Here
Using the example snippet below, you can see how you can use Canvas.toDataURL.
var image = new Image();
image.crossOrigin = 'anonymous'; // only needed for CORS, not needed for same domain.
// create an empty canvas element
var canvas = document.createElement("canvas");
var canvasContext = canvas.getContext("2d");
image.onload = function () {
//Set canvas size is same as the picture
canvas.width = image.width;
canvas.height = image.height;
// draw image into canvas element
canvasContext.drawImage(image, 0, 0, image.width, image.height);
// get canvas contents as a data URL (returns png format by default)
imageURL = canvas.toDataURL();
};
image.src = 'http://code.famo.us/assets/famous_logo.png';

How to get base64 image data without call canvas toDataURL?

I'm on a project which requires to support ie9 or ie10.
I'm using d3.js for data visualization.
Now I need to provide a function to export the chart as pdf.
I have been investigate into possible solutions. It seems that canvas + jsPdf is the way to go, below is some code I write.
But the problem is that when toDataURL gets called, it will cause security errors on IE9 and IE10. So I'm wondering if there's some work around to get base64 image data without using canvas since jsPdf only needs base64 image data???
createObjectURL to the root svg element
svgElement = $('svg').get(0);
serializer = new XMLSerializer();
str = serializer.serializeToString(svgElement);
DOMURL = window.URL || window.webkitURL || window;
url = DOMURL.createObjectURL(new Blob([str], {type: 'image/svg+xml;charset=utf-8'}));
draw an image using canvas
img = new Image();
img.onload = function(){
ctx.drawImage(img, 0, 0);
imgData = $canvas.get(0).toDataURL("image/jpeg");
DOMURL.revokeObjectURL(url);
pdf = new jsPDF('landscape', 'pt', 1000, 800);
pdf.addImage(imgData, 'JPEG', 0, 0);
pdf.save('download.pdf');
};
img.src = url;
I finally find the solution which is to use an open source project: canvg

HTML5 canvas - Only draw image differences?

I'm receiving images via a websocket in base64 format and then drawing the images on a canvas using:
var img=new Image();
img.onload = function() {
cxt.drawImage(img, 0, 0, canvas.width, canvas.height);
};
img.src = "data:image/jpeg;base64,"+imgData;
Is it possible to change this code and somehow only draw the pixels that have changed? And if it is possible, would this even increase the performance? Thanks for the help. :)
What would be more efficient first would be to only send/receive images deltas ( what has changed) between images, then draw that on your canvas.

html5: copy a canvas to image and back

I implemented a zoom in and out function on a canvas element.
it works by scaling the canvas, translating it, and then redraw the whole scene again.
the problem is that it takes a lot of time to redraw everything because i got a lot of things on my canvas.
I need a way to copy the canvas to an image object and than copy the image back to the canvas without loosing quality. what are the specific methods to copy canvas to a javascript variable, and to to copy this variable back to the canvas later?
I'll be glad if you write down the code because I couldn't find any good explanation over the internet.
thanks,
The drawImage() method can draw to a canvas using another canvas instead of an image.
You could create a 'backup' canvas, of the same size as your original, draw the first one to there and then draw that one back to the original when you need it.
e.g.
// Assume we have a main canvas
// canvas = <main canvas>
ctx = canvas.getContext('2d');
..
// create backing canvas
var backCanvas = document.createElement('canvas');
backCanvas.width = canvas.width;
backCanvas.height = canvas.height;
var backCtx = backCanvas.getContext('2d');
// save main canvas contents
backCtx.drawImage(canvas, 0,0);
..
// restore main canvas
ctx.drawImage(backCanvas, 0,0);
There are a few ways to do it theres the getImageData and putImageData methods Reference, However putImageData and getImageData are pretty slow. Another way is to save the data to an image in memory and recall it from that which is much faster, then the third way is the one above mentioned by andrewmu which involves copying to another canvas element. I have included examples for the first and second type.
Image in memory method
var canvas = document.getElementById("canvas"),
ctx = canvas.getContext("2d"),
savedData = new Image();
function save(){
// get the data
savedData.src = canvas.toDataURL("image/png");
}
function restore(){
// restore the old canvas
ctx.drawImage(savedData,0,0)
}
getImageData putImageData method
// Setup our vars, make a new image to store the canvas data
var canvas = document.getElementById("canvas"),
ctx = canvas.getContext("2d"),
canvasData = '';
function save(){
// get the data
canvasData = ctx.getImageData(0, 0, 100, 100);
}
function restore(){
// restore the old canvas
ctx.putImageData(canvasData, 0, 0);
}
added image into canvas
var image = new Image();
image.src = "1.jpg";
image.onload = function () {
context.drawImage(image, 0, 0);
};

Resources