HTML5 Canvas Scaling using getImageData and putImageData - html

Is there any way to scale the canvas using getImageData and putImageData.Below is the snippet of code.
var c=document.getElementById("myCanvas");
var c2=document.getElementById("myCanvas2");
var ctx=c.getContext("2d");
var ctx2=c2.getContext("2d");
ctx.fillStyle="red";
ctx.fillRect(10,10,50,50);
function copy(){
var imgData=ctx.getImageData(10,10,50,50);
ctx2.translate(133.333,0);
ctx2.scale(0.75,1);
ctx2.putImageData(imgData,10,70);
}
I have tried this out http://jsbin.com/efixur/1/edit.
Thanks
Ajain

getImageData() and putImageData() are provided for raw pixel operations and thus scaling is not possible (unless you write a custom scaler in Javascript).
What you want is to use drawImage() and then use another <canvas> as source instead of <img>.
https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Canvas_tutorial/Using_images#Scaling

Related

Write svg latex into a canvas html

My goal is to record maths scripts running on the canvas and at the same time record sound from the mic (I am a math teacher). I would like very much to allow latex formulas. Of course latex formulas do not write directly to canvas. MathJax can produce SVG elements. I wonder if it is possible to go from SVG->image->canvas, using javascript. I don't care if the obtained image on canvas is a little blured.
I couldn't find good examples of this yet on the internet.
Thanks!
Indeed there is no Latex to canvas direct way.
You can however draw an SVG over a canvas. See this Q/A to see how to proceed from an SVG in the DOM (which MathJax should give you).
Indeed that's possible. The trick here is to grab the SVG output of MathJax and draw it to a temporary <img> element, which in-turn is drawn to an on-screen canvas afterwards.
The actual <svg> element is a children of the <mjx-container> element returned by a call to MathJax's tex2svg() method.
Here's an example:
let canvas = document.getElementById('canvas');
let ctx = canvas.getContext('2d');
let equation = "x = \\sin \\left( \\frac{\\pi}{2} \\right)";
let svg = MathJax.tex2svg(equation).firstElementChild;
let img = document.createElement('img');
img.onload = (e) => {
let tempWidth = e.target.naturalWidth;
let tempHeight = e.target.naturalHeight;
ctx.drawImage(e.target, canvas.width / 2 - tempWidth / 2, canvas.height / 2 - tempHeight / 2, tempWidth, tempHeight)
}
img.src = 'data:image/svg+xml;base64,' + btoa('<?xml version="1.0" encoding="UTF-8" standalone="no" ?>\n' + svg.outerHTML);
#canvas {
background-color: #eeeeee;
}
<script src="https://cdn.jsdelivr.net/npm/mathjax#3/es5/tex-svg.js" type="text/javascript"></script>
<canvas id="canvas"></canvas>

SVG stroke width is messy on a html 5 canvas

I am trying to bind an SVG to a canvas. The SVG has a stroke width setup and it seems to be thicker than what it needs to be when bound to the canvas. What could be causing this and how to fix this?
The library that I use to bind svg to the html5 canvas is canvg
The JS fiddle below shows both the SVG and the bound svg on a canvas.
JS Fiddle: http://jsfiddle.net/fYAAf/111/
var image = new Image();
var canvas = document.createElement('canvas');
canvas.width =1090;
canvas.height = 1875;
var context = canvas.getContext('2d');
context.drawSvg(xml, 0, 0);
image.src = canvas.toDataURL();
According to the link: http://jsfiddle.net/fYAAf/111/
In the javascript code you are embedding the characteristic of SVG in a type tag (image). The result is something like this:

<img src="data:image/png;basQAACAnWQXByGjnghZGYT8......characteristic_of_SVG">
So you should try to put all the XML properties within an SVG tag, as it is written in the HTML document in the top of the example of jsFiddle.
In JavaScript something fast would:
var xml = "<svg> (Write here xml properties) <g><text (Write here text properties)><tspan dy="35" x="0">Test</tspan></text></g></svg>";
document.getElementById('container').innerHTML = xml;
<div id="container"></div>
I don't know what the cause of this behavior in img tags.

Drawing on HTML5 Canvas

Is there a putpixel functionality in html5. I have a canvas and want to draw on the canvas using mouse. How should I wright the javascript function for that. How can can I take the coordinate value on mouseclick and change the pixel value as soon as the user clicks.
From http://net.tutsplus.com/tutorials/javascript-ajax/canvas-from-scratch-pixel-manipulation/ section "Putting this into practice" using jquery:
$(canvas).click(function(e) {
var canvasOffset = $(canvas).offset();
var canvasX = Math.floor(e.pageX-canvasOffset.left);
var canvasY = Math.floor(e.pageY-canvasOffset.top);
// do here whatever you want
});
Read the article for a detailed explanation.
If you have a intermediate knowledge of Javascript try reading a tutorial like this:
http://www.williammalone.com/articles/create-html5-canvas-javascript-drawing-app/

Should I use multiple images in one canvas?

What is best practice? Should I make a separate canvas tag for each image in html5, or is it just as functional to put multiple images in one canvas, and how would I do that.
My Code so far:
var canvas = document.getElementById("e");
var context = canvas.getContext("2d");
var cat = new Image();
cat.src = "images/cartoonPaul01.jpg";
cat.onload = function() {
context.drawImage(cat, 0, 0, 169, 207);
};
You can do this dynamically, if you're so inclined. muro from deviant art uses a few base canvases – temp, buffer, and background. Then you dynamically create and delete layers using a control on the side. It depends largely on what you want to do.
If you are just printing to the canvas, and you don't need to necessarily alter the images in a way that needs dynamism, you can draw them all to one canvas. If you need layering, use it.
Dynamic canvas and context creation:
// This is not best practice, just an example using globals.
var layers = [];
var lyrCtx = [];
createLayer = function() {
// Create the canvas.
layers.push(document.createElement('canvas'));
layers[layers.length - 1].setAttribute('id', 'layer'+layers.length-1);
// Create the context. Provided you do it in order, lyrCtx[i] should correlate to layers[i]
lyrCtx.push(layers[layers.length - 1].getContext("2d"));
// Handle context settings here.
}
You should get the balance. I usually use 4-6 canvas layers in my app, and draw logical part on them.

How do I generate a thumbnail client-side in a modern browser?

I'm looking for an elegant way to generate a thumbnail for use with the FileAPI. Currently I get a DataURL representing an image. Problem is, if the image is very large, than moving it around and rerendering it becomes CPU intensive. I can see 2 options to get around this.
Generate a thumbnail on the client
Generate a thumbnail on the server, send the thumbnail back to the client (AJAX).
With HTML5 we have a canvas element? Does anyone know how to use it to generate thumbnails from pictures? They don't have to be perfect -- sampling quality is acceptable. Is there a jQuery plugin that will do this for me? Are there any other way to speed up the clientside use of large images?
I'm using HTML5, and Firefox 3.6+: there is no need to support anything other than Firefox 3.6+, please don't provide suggestions for IE 6.0
Here’s what you can do:
function getThumbnail(original, scale) {
var canvas = document.createElement("canvas");
canvas.width = original.width * scale;
canvas.height = original.height * scale;
canvas.getContext("2d").drawImage(original, 0, 0, canvas.width, canvas.height);
return canvas
}
Now, to create thumbnails, you simply do the equivalent of this:
var image = document.getElementsByTagName("img")[0];
var thumbnail = getThumbnail(image, 1/5);
document.body.appendChild(thumbnail);
Note: Remember to make sure that the image is loaded (using onload) before trying to make a thumbnail of it.
Okay, the way I can see this working is drawing the image to the canvas at a smaller size, then exporting the canvas. Say you want a 64px thumbnail:
var thumbSize = 64;
var canvas = document.getElementById("canvas");
canvas.width = thumbSize;
canvas.height = thumbSize;
var c = canvas.getContext("2d");
var img = new Image();
img.onload = function(e) {
c.drawImage(this, 0, 0, thumbSize, thumbSize);
document.getElementById("thumb").src = canvas.toDataURL("image/png");
};
img.src = fileDataURL;
With this code, an image element with the id "thumb" is used as the thumbnail element. fileDataURL is the data URL that you got from the file API.
More information on drawing images to the canvas: http://diveintohtml5.info/canvas.html#images
And on exporting canvas data: http://msdn.microsoft.com/en-us/library/ie/ff975241(v=vs.85).aspx