Can we add putImageData to fabric canvas instead of fromURL - javascript

fabric.Image.fromURL(hc.toDataURL(), function(img) {
// add image onto canvas
Canvas.add(img);
img.hasControls = false;
img.hasBorders = false;
img.hasControls = false;
img.hasRotatingPoint = false;
img.selectable = false;
});
Above code helps in rendering a image to canvas but I want to use something like putImageData/drawImage because I have to draw the image from another canvas . And as per real time operation using toDataURL for more than 5 MB images is very bad when performance comes to picture.
I also want to render the image on the middle of the canvas .
Fabricjs just takes the image toDataURL and renders it as it is.
Any help will be appreciated.

fabric.Image() just like the row ctx.drawImage accepts a canvasElement as imageSource.
So you can just call it like
canvas.add(new fabric.Image(yourCanvasToDraw));
And if you want it centered in the canvas :
canvas.add(new fabric.Image(c, {left: canvas.width/2-c.width/2, top: canvas.height/2-c.height/2}));
Note that ctx.getImageData+ctx.putImageData is at least as slow as ctx.toDataURLwhich both are incredibly slower than ctx.drawImage

Related

HTML5 Canvas bitmaps

I am building a retro styled game, that uses pixelated images. I have not yet created these images, because I wanted to know the best way of doing things.
These images will probably be a 16 or 32 PX square, but I would like to be able to scale the images as big as I like, just without any blur/distortion.
What format should I use? And how should I import them to my canvas. as well?
EDIT#1: Fixed typo & put Q back on topic. (Thank you Spence for pointing it out)
Try "Inkscape", its free
https://inkscape.org/en/
it uses SVG format (scalar vector graphics) so you will be able to scale the images as big as you like, just without any blur/distortion.
The only way to enlarge without any blur or distortion is turn each 1 pixel into a set of 2x2, 3x3, ... pixels.
For example, a single blue pixel in the top-left of the image would become a set of 4 blue pixels at [0,0], [1,0], [0,1] & [1,1]. And the same for every other pixel on the original image. The resulting image would be twice the width & height of the original image.
Since your graphics style is pixelated images, this adjustment would preserve your pixilation while also enlarging the original image.
You can code a function that uses an in-memory html5 canvas to "resize-by-multiplying" your original images as needed. This will use canvas's ability to set the RGBA values every pixel using context.getImageData and context.putImageData.
CanvasContext2d does have an option to disable the image smoothing : imageSmoothingEnabled which is set to true by default.
According to the specs, if set to false,
The image [drawn by drawImage() method] must be rendered using
nearest-neighbor interpolation.
This algorithm is the same as the one proposed by #markE in his answer.
Unfortunately, browsers still use vendor-prefix for this attribute and it wasn't implemented in both IE9 and IE10...
var img = document.querySelector('img'),
canvas = document.querySelector('canvas'),
ctx = canvas.getContext('2d');
// draw the image
img.onload = function(){
canvas.width = img.width*50;
canvas.height = img.height*50;
// disable smoothing after we change canvas' width/height
ctx.mozImageSmoothingEnabled = false;
ctx.webkitImageSmoothingEnabled = false;
ctx.msImageSmoothingEnabled = false;
ctx.imageSmoothingEnabled = false;
ctx.drawImage(img, 0,0, canvas.width, canvas.height);
}
//32x32px image taken from https://stackoverflow.com/q/31910043/3702797
img.src="http://i.stack.imgur.com/3Sp5x.png"
canvas{border:.5px solid}
<img/>
<canvas></canvas>
Scroll to see the resized image in canvas
Create large icon images to which you apply a 16x16 or 32x32 tile effect. Then when you write them to the canvas (after loading the images of course) scale them down to the size you want using
context.drawImage(img,x,y,width,height);
File sizes are unlikely to jump greatly since each tile should compress fairly easily.

Visualizing html5 canvas

This may be off topic but I'm not sure where else to go with this question. I'm just getting started with HTML5 canvas element and all of the incredibly powerful things it can do. I was hoping someone could offer some advise. When working with custom paths and bezier curves, what is the easiest/best way to visualize where the points belong on the canvas to achieve a desired effect. Right now it feels like I'm just guessing plotting points in any place hoping to end up with the right angle/shape that I want.
To be more specific I want to create a shape that will act as an image mask, and will later need to animate this shape. Much like this fiddle http://jsfiddle.net/jimrhoskins/dDUC3/1/ (someone else's work) but since I can't see where the picture is on the canvas or where any of the points are, I'm really just guessing at the approximate shape I need to make. I'm just wondering if there's a better way, or some function in javascript that can map the location of an image and give me at least a better place to start.
Here is what I know/have tried already
// Grab the Canvas and Drawing Context
var canvas = document.getElementById('c');
var context = canvas.getContext('2d');
// Create an image element
var img = document.createElement('IMG');
// When the image is loaded, draw it
img.onload = function () {
// Save the state, so we can undo the clipping
context.save();
// Create a shape, of some sort
context.beginPath();
context.moveTo(somex, somey);
context.bezierCurveTo(somexstart, someystart, somexcontrol, someycontro, somexend, someyend);
context.arcTo(somecoordinates);
context.closePath();
// Clip to the current path
context.clip();
context.drawImage(img, 0, 0);
// Undo the clipping
context.restore();
}
// Specify the src to load the image
img.src = "url";
How about opening the image in an SVG editor. Drawing a path on a layer above the image. Then open the SVG and copy the coordinates?
Try an SVG Editor. You can get the points there. You can add images too. SVG animation is used nowadays as well. If you have Adobe Illustrator, it will be easier to draw there and just save it as SVG.

How to download canvas with background image?

I have a canvas element that I'm setting the background on dynamically via code. Then I'm using the Sketch library (http://intridea.github.io/sketch.js/) to draw on the canvas. - This all works.
However, whenever I try to convert the canvas using canvas.toDataURL("image/png") it's able to save the canvas drawing, however isn't saving the background. - I understand this is working as designed.
Is there a way to merge the two? I was toying around with the idea that I could set the image src to the background src after I'm done drawing and try to export that, however I'm not certain. Does anyone have any experience with this?
As you've discovered, the canvas and its background are maintained separately and toDataURL will not also capture the background.
You can combine the background with the sketch using canvas compositing.
The 'destination-over' compositing mode will let you drawImage your background behind the sketches
context.globalCompositeOperation="destination-over";
context.drawImage(backgroundImage,0,0);
Now the background pixels have been drawn behind you sketch and both will be captured with toDataURL.
Yes, You are correct. I fetch the background image along with canvas image and download.
ctx.width = 2503;
ctx.height = 250;
ctx.globalCompositeOperation="destination-over";
var background = new Image();
background.src = "http://localhost/xxxxx/xxxxx/xxxxx/xxxxx/ecg_back.png";
ctx.drawImage(background, 0, 0);
// create pattern
var ptrn = ctx.createPattern(background, 'repeat'); // Create a pattern with this image, and set it to "repeat".
ctx.fillStyle = ptrn;
ctx.fillRect(0, 0, ctx.width, ctx.height);
How are you adding the background to the canvas? Are you setting it in css as a background image? Or are you adding the image directly to the canvas? I think you'll need to do the latter, as per the example here.

erase part moving image

Is there a way to clear the canvas (html5)of only 1 element only ? I have a moving image on a canvas and when I erase the image the background color goes as well. Is there a way to just remove the image and not the whole background. My background is just a simple color but in the future it will be more complicated.
This is also tricky because there is no way to get image x,y pos from a property.
ClassLoadImages.prototype.m_move = function(){
this.x=++img1_x;
this.y=++img1_y;
//img1_x++;
//img1_y++;
// alert(img.x);
ctx.drawImage(img.imgElement, this.x, this.y);
// ctx.fillText("finished loading " ,10,40);
};
function doGameLoop() {
ctx.clearRect(0,0,600,400);
img.m_move();
if (img.x>30)
{
clearInterval(gameLoop);
}
}
var img= new ClassLoadImages('images/image4.jpg');
gameLoop = setInterval(doGameLoop, 100);
</script>
Simple answer is no. A canvas is a flat bitmap, not a layered collection of objects. Once you draw to it you lose the background behind the thing you draw.
You could try to implement the functionality yourself by recording the steps you used to create the canvas in the first place, and re-creating it with or without the relevant image.

how to draw both image and sketch on canvas together

I want to draw an image to canvas and then allow user to draw some sketch on it by sketch.js. Now the situation is:
1.the image has been drawn on the canvas successfully
2. but when my mouse over the canvas, then image disappeared, and the canvas shows empty
3. when I dragged the mouse, some sketch shows on the empty canvas(the sketch looks correct)
so, I've made both functions right, but I'm confused about the part in between. I hope to draw the sketch on the canvas with the image on it. Here is my code:
index.html:
<canvas id="mysketch" width="578" height="400" style="margin: 0px; "></canvas>
canvas.js:
var mysketch = jQuery("#mysketch");
// draw the captured image to canvas
var displayImage = function() {
var context = mysketch.get(0).getContext("2d");
var image = new Image();
image.onload = function() {
context.drawImage(image, 0, 0);
}
// prepend the required image info again
image.src = dataURL;
// call sketch.js to draw sketch on the canvas
mysketch.sketch({defaultColor: "#ff0"});
}
I think that, on your call to sketch method
sketch.js is clearing the canvas first then allows you to draw something on it.
As you can see in the link here, in the 3rd example (i.e. Tools Example) the image is not drawn by drawImage method.
It is actually the background of the canvas which will always be there as background, whatever you draw on it.
So what you can do is:
either do same thing as in the example i.e. set your image as background,
or make a new canvas just behind your canvas with same width, height and on same location and draw your image on it. and do your sketch thing on the second one.

Categories