JavaScript Canvas drawImage deforms my image - javascript

No matter what I try, I can't figure out why does drawImage vertically stretch a picture. Here is the code:
<canvas id="canvas" style="padding:0;border:0;margin:0 auto;
width:320px;height:456px;z-index:0;"></canvas>
<script type="text/javascript">
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
var d = new Image
d.src = './images/portadilla.jpg';
d.onload = function a(){context.drawImage(d, 0, 0);}
</script>
My image is 456px high and 320px wide, same as the canvas. I've tried using different images and formats, but the problem remains. How would you solve this?

Because you're not setting the size of the canvas correctly. Don't use CSS/style to set the size but use its attributes:
<canvas id="canvas" width=320 height=456 style="..."></canvas>
Your image is stretched because the default size of the bitmap for a canvas element is 300x150 pixels so if you don't set the size properly the canvas bitmap will be stretched to fit the element size set with CSS.
You can also set the size using JavaScript:
var canvas = document.getElementById('canvas');
canvas.width = 320;
canvas.height = 456;

Related

CreateJs Canvas resize Bitmap

I'm currently working with createJS canvas. I have an image with a predefined size into a Json file and boxes that are link to an eventListener on "mouseout" and "mouseover").
var stage = new createjs.Stage("testCanvas");
createjs.Touch.enable(stage);
stage.enableMouseOver(10);
Bitmap for the image:
var image = new Image();
image.onload = function () {
var img = new createjs.Bitmap(event.target);
stage.addChild(img);
then i draw my boxes (rectangles):
angular.forEach(..., function(value){
var rectGreen = new createjs.Shape();
rectGreen.graphics.beginFill("green")
.drawRect(
value.shapeDimension....,
value.shapeDimension....,
value.shapeDimension....,
value.shapeDimension....
);
rectGreen.alpha = 0.01;
stage.addChild(rectGreen);
my mouse events:
rectGreen.addEventListener("mouseover", function (event) {
var target = event.target;
target.alpha = 0.35;
stage.update();
});
rectGreen.addEventListener("mouseout", function (event) {
var target = event.target;
target.alpha = 0.01;
stage.update();
});
So, it's working but I have some difficulties with the canvas/image size.
If I don't set any width/heigth to the canvas Html, it results in a
300*150 canvas but the image is not resized so it displays only a
slight piece of the real image.
If i set width and height in the canvas html, (real size is 1700*1133), the image appears only 842*561 and the canvas takes place).
I tried different solution with Setting DIV width and height in JavaScript
but nothing enabled me to set my image correctly, and responsive so that the size of my rectangles adpt to the screen size of the image.
In order to dynamically resize the Canvas to the exact size of the image, you can do this:
//to get a variable reference to the canvas
var canvas = document.getElementById("testCanvas");
//supposing the Bitmap is the variable named 'img'
canvas.width = img.image.width;
canvas.height = img.image.height;
If you have more elements on the screen and the total size is bigger than the image itself, you can add everything on the screen in a container, and then scale the container itself to fit the canvas perfectly, like this:
var container = new createjs.Container();
container.addChild(img, [your other rectangle elements here]);
stage.addChild(container);
//will downscale or upscale the container to fit the canvas
container.scaleX = container.scaleY = canvas.width / img.image.width;

Is there any way to make an html5 canvas element resizeable?

Is there a native solution that provides a handle in the corner of my HTML5 canvas similar to that in a default <textarea> element.
<textarea>resizeable</textarea>
I assume this will clear the canvas and will require a redraw as this is the case when resizing the canvas programmatically with canvas.width and canvas.height.
I looked around and found nothing, but wanted to check before rolling my own. If anyone is sure that there is no "easy" way, then that is a perfectly acceptable answer. Thanks!
The best I could come up with was use jQueryUI Resizable like so
jsFiddle : https://jsfiddle.net/n24dbaw9/
Html
<div class="resizable">
<canvas id="myCanvas"></canvas>
</div>
CSS
.resizable{
width: 400px;
height: 400px;
}
#myCanvas{
width: 100%;
height: 100%;
}
Javascript
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
ctx.fillStyle = "#777";
$(function() {
$(".resizable").resizable();
});
setInterval(function(){ ctx.fillRect(0, 0, 400, 400); }, 3);
Basically I have styled the canvas to fit inside of the "resizble" div, which is set to 400 by 400 at default. The canvas has a style which is 100% width and height so when the user resizes the "resizble" div the canvas will then just stretch out.
You will want to put the canvas into a JavaScript draw() function:
function draw() {
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext('2d');
ctx.canvas.width = window.innerWidth;
ctx.canvas.height = window.innerHeight;
}
and your body element in css should have height and width set to 100%

a circle gets distorted in canvas

trying to draw a simple circle .but it is getting distorted .and the color is also fade.why is that happening?
<html>
<body>
<script>
function makeit(){
var canvas=document.createElement('canvas');
var atts=document.createAttribute('style');
atts.value="width:400px;height:400px;border:1px solid black;";
canvas.setAttributeNode(atts);
document.body.appendChild(canvas);
var ctx=canvas.getContext("2d");
ctx.beginPath();
ctx.strokeStyle="black";
ctx.arc(100,100,25,0,2*Math.PI);
ctx.stroke();
}
window.onload=makeit;
</script>
</body>
</html>
this is because you set the width and height over the style object.
try canvas.width= canvas.height=
style.width style.height defines the appearance of canvas in the html dom.
canvas.width canvas.height defines the canvas width and height...
for example if you define a canvas width and height with 400 and 400. and you want canvas to show with 800px width and 800 px height over the style object. it gets distorted because of resizing to bigger multiplied each dimension by 2.
normally its 1 to 1

How to modify an image with canvas

In my html I have an image already loaded:
<img usemap="#prototypeMap" src="../../projects/tcas/TCAS display.jpg" style="z-index: 2;">
Is it possibile create a canvas to modify that image, by javascript?
For example drawing a line in it, changing colours in it (for some pixels) and so on...
EDIT:
I have found a method on Internet but it doesn't works good for me:
var imgElement = document.getElementById('prototypeMap');
var canvas = document.createElement("canvas");
canvas.width = imgElement.offsetWidth;
canvas.height = imgElement.offsetHeight;
var ctx = canvas.getContext("2d");
ctx.drawImage(imgElement,0,0); //ERROR
The last line give me this error:
TypeError: Value could not be converted to any of: HTMLImageElement, HTMLCanvasElement, HTMLVideoElement.
You can try using SVG image tag:
https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/SVG_Image_Tag
And then use the other SVG elements to draw on top.

Canvas image sized wrong when using an external css file

I am working with the HTML5 canvas element. I am using the following javascript to draw an image into the canvas:
var img = new Image();
var canvas = this.e;
var ctx = canvas.getContext('2d');
img.src = options.imageSrc;
img.onload = function() {
ctx.drawImage(img,0,0);
}
This works fine. However I am experiencing some weird css issues. When I use inline css like the following, the image scales perfectly in the canvas:
<canvas id="canvas" width="800" height="448"></canvas>
However, when I remove the inline css and use an external css file the image is drawn too big for the canvas and I only see the top left corner of the image. Here is the css I am using:
#canvas {
height:448px;
width:800px;
border:none;
}
When I use the inline css is the drawn image somehow inheriting the css from the canvas? Not sure what is going on here but I would like to use the external css file.
EDIT
If I provide no styling for the canvas element, it is smaller but still shows just the top corner of the image. When I do style it with a css file, the canvas is bigger but it is as if it just zoomed in on the image. The same amount of the image is shown, it is now just bigger.
EDIT 2
Based on the answer received I am now sizing the dom size of the canvas with javascript. I changed my img.onload function to the following:
img.onload = function() {
if (options.imageWidth == 0 && options.imageHeight == 0) {
canvas.height = this.height;
canvas.width = this.width;
} else {
canvas.height = options.imageHeight;
canvas.width = options.imageWidth;
}
ctx.drawImage(img,0,0);
}
Canvases have two sizes - the actual pixel grid size (in the width and height attributes) and the CSS size.
If the pixel size is not specified it typically defaults to something like 300x300.
The CSS size only specifies the amount of space taken in the page, and defaults to the pixel size. If they are not equal the image will be scaled.
You MUST specify the pixel size in the <canvas> element, or set it using Javascript:
var img = new Image();
var canvas = this.e;
var ctx = canvas.getContext('2d');
img.src = options.imageSrc;
img.onload = function() {
canvas.width = this.width; // new code
canvas.height = this.height; // "
ctx.drawImage(img, 0, 0);
}
Try putting !important on your external styles, might be that something is overriding it, but inline it overrides last.
#canvas {
height:448px !important;
width:800px !important;
border:none !important;
}

Categories

Resources