How to fit canvas to wrap image size - javascript

Hello I have this canvas and image in it but I need to make it so the canvas wraps the image linked to its size. Right now i have put a test image and put size to be fixed. I want when i put and image the canvas to wrap it 100% width 100% height of the image.
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
var boxWidth=100;
var boxHeight=100;
var boxRows=Math.ceil(865/boxHeight);
var boxCols=Math.ceil(1152/boxWidth);
var boxes=new Array(boxRows*boxCols);
for(var i=0;i<boxes.length;i++){boxes[i]=false;}
var img=new Image();
img.onload=start;
img.crossOrigin='anonymous';
img.src="http://i.imgur.com/RrHayx8.png?1";
function start(){
ctx.drawImage(img,0,0);
var d=ctx.getImageData(0,0,cw,ch).data;
for(var i=0;i<d.length;i+=4){
if(d[i+3]>200){
var px=parseInt(i/4);
var pixelY=parseInt(px/cw);
var pixelX=px-pixelY*cw;
var boxX=parseInt(pixelX/boxWidth);
var boxY=parseInt(pixelY/boxHeight);
boxes[boxY*boxCols+boxX]=true;
}
}
ctx.globalAlpha=0.25;
ctx.fillStyle='red';
for(var i=0;i<boxes.length;i++){
var y=parseInt(i/boxCols);
var x=i-y*boxCols;
if(boxes[i]==true){
ctx.fillRect(x*boxWidth,y*boxHeight,boxWidth,boxHeight);
}
}
ctx.globalAlpha=1.00;
ctx.fillStyle='black';
}
https://jsfiddle.net/kdichev/Lmqdrkp2/

If you always load the image to position (0,0), then you can set the size of the canvas to the size of the loaded image by adding
canvas.width = img.width;
canvas.height = img.height;
ctx=canvas.getContext("2d");
to the very beginning of your start() function. The first two lines resize the canvas. After resizing the context has to be updated to make it work properly.

Related

Change Image() object dimensions (width and height)

I am attempting to resize an image's dimensions, whilst retaining it's aspect ratio. This seems like a very simple task, but I cannot find a rellevent answer anywhere.. (relating to JavaScript's Image() object). I'm probably missing something very obvious. Below is what I am trying to achieve:
var img = new window.Image();
img.src = imageDataUrl;
img.onload = function(){
if (img.width > 200){
img.width = 200;
img.height = (img.height*img.width)/img.width;
}
if (img.height > 200){
img.height = 200;
img.width = (img.width*img.height)/img.height;
}
};
This is to proportionally resize an image before being drawn onto a canvas like so: context.drawImage(img,0,0,canvas.width,canvas.height);.However it would appear I cannot directly change Image()dimensions, so how is it done? Thanks.
Edit: I haven't correctly solved the image proportions using cross-multiplication. #markE provides a neat method of obtaining the correct ratio. Below is my new (working) implementation:
var scale = Math.min((200/img.width),(200/img.height));
img.width = img.width*scale;
img.height = img.height*scale;
clearCanvas(); //clear canvas
context.drawImage(img,0,0,img.width,img.height);
Here's how to scale your image proportionally:
function scalePreserveAspectRatio(imgW,imgH,maxW,maxH){
return(Math.min((maxW/imgW),(maxH/imgH)));
}
Usage:
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var img=new Image();
img.onload=start;
img.src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/balloon.png";
function start(){
canvas.width=100;
canvas.height=100;
var w=img.width;
var h=img.height;
// resize img to fit in the canvas
// You can alternately request img to fit into any specified width/height
var sizer=scalePreserveAspectRatio(w,h,canvas.width,canvas.height);
ctx.drawImage(img,0,0,w,h,0,0,w*sizer,h*sizer);
}
function scalePreserveAspectRatio(imgW,imgH,maxW,maxH){
return(Math.min((maxW/imgW),(maxH/imgH)));
}
body{ background-color: ivory; }
canvas{border:1px solid red;}
<h4>Original Balloon image resized to fit in 100x100 canvas</h4>
<canvas id="canvas" width=100 height=100></canvas>
The image dimensions are set in the constructor
new Image(width, height)
// for proportionally consistent resizing use new Image(width, "auto")
or
the context.drawImage()
the arguments are as follows:
context.drawImage(image source, x-coordinate of upper left portion of image,
y-coordinate of upper left portion of image,image width,image height);
simply position the the image with the first two numeric coordinates and then manually adjust the size with the last two (width,height)
//ex.
var x = 0;
var y = 0;
var img = new Image (200, "auto");
img.src = "xxx.png";
context.drawImage(img,x,y,img.width,img.height);

Resize HTML canvas with .scale()

I'm trying to resize a <canvas> with an image already drawn, but I'm misunderstanding how to use the canvas.scale() method because it doesn't shrink...
Code:
ImageRender.prototype.resizeTo = function () {
var canvas = $('#myCanvas')[0];
var ctx = canvas.getContext("2d");
//current image
var currImg = ctx.getImageData(0, 0, canvas.width, canvas.height);
//
var tempCanvas = $('canvas')[0];
var tempCtx = tempCanvas.getContext("2d");
tempCtx.putImageData(currImg, 0, 0)
//
ctx.scale(0.5, 0.5);
//redraw
ctx.drawImage(tempCanvas, 0, 0);
};
What am I overlooking?
Thanks!
You can scale your canvas with content by "bouncing" the content off a temporary canvas while you resize the original canvas. This save+redraw process is necessary because canvas content is automatically cleared when you resize the canvas width or height.
Example code:
var myCanvas=document.getElementById("canvas");
var ctx=myCanvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
var tempCanvas=document.createElement("canvas");
var tctx=tempCanvas.getContext("2d");
var img=new Image();
img.crossOrigin='anonymous';
img.onload=start;
img.src="https://dl.dropboxusercontent.com/u/139992952/multple/Dog-With-Cute-Cat.jpg";
function start(){
myCanvas.width=img.width;
myCanvas.height=img.height;
ctx.drawImage(img,0,0);
resizeTo(myCanvas,0.50);
}
function resizeTo(canvas,pct){
var cw=canvas.width;
var ch=canvas.height;
tempCanvas.width=cw;
tempCanvas.height=ch;
tctx.drawImage(canvas,0,0);
canvas.width*=pct;
canvas.height*=pct;
var ctx=canvas.getContext('2d');
ctx.drawImage(tempCanvas,0,0,cw,ch,0,0,cw*pct,ch*pct);
}
body{ background-color: ivory; }
#canvas{border:1px solid red; margin:0 auto; }
<h4>Canvas resized to 50%</h4>
<canvas id="canvas" width=300 height=300></canvas>
<h4>Img with original image</h4>
<img src='https://dl.dropboxusercontent.com/u/139992952/multple/Dog-With-Cute-Cat.jpg'>
Simpler way would be using the extra parameters of drawImage(). 4th and 5th parameters let you set the final width and height.
Also, you can paint an image (or a canvas) directly, without the need of getting the ImageData.
Also(2), I think you may want to resize the canvas too (just use its width and height properties)
https://jsfiddle.net/mezeL06o/

Copy Canvas Image into a Frame

As starting point I have a image on my canvas:
var canvas = $('canvas')[0];
var ctx=canvas.getContext("2d");
var img=document.getElementById("scream");
ctx.drawImage(img,0,0,240,297);
Now I would like to add a frame to this Image on the same canvas. For this:
I first replace the image with the Frame.
Next I try to copy the old canvas content inside of this frame
I try to do this like that:
var frame = document.getElementById("frame");
var ctx = $('canvas')[0].getContext("2d");
var dst = ctx.canvas;
ctx.drawImage(frame,0,0, 240, 297);
ctx.drawImage(dst, 40, 40);
But the code is not working because it copies the frame again to the canvas instead of the image: Here you can see a demo: https://jsfiddle.net/35mxfsv0/
What do I wrong? What do I have to change? Thanks
As you just assign the original canvas to dst, when you draw anything on that canvas, the dst will also changed (because they're pointing to same canvas).
So you have to assign a new canvas to dst, and draw the image from origin to dst, then draw the frame on origin, and last, draw dst's image to origin.
window.onload = function() { // Make it safe that window.onload ensures all images loaded.
var canvas = $('canvas')[0];
var ctx=canvas.getContext("2d");
var img=document.getElementById("scream");
ctx.drawImage(img,0,0,240,297);
//START OF MY CODE
var frame = document.getElementById("frame");
// Comment out as we demo in same scope, ctx is already have what we want.
//var ctx = $('canvas')[0].getContext("2d");
// Create a new canvas, and draw the image on the origin canvas to it.
var dst = document.createElement('canvas');
dst.width = canvas.width;
dst.height = canvas.height;
var dstCtx = dst.getContext('2d');
dstCtx.drawImage(canvas, 0, 0);
// Above is what you suppose the canvas should do.
//var dst = ctx.canvas;
// Draw frame
ctx.drawImage(frame,0,0, 240, 297);
// As your frame is not an opacity one, you have to copy to specific position.
ctx.drawImage(dst, 0, 0, dst.width, dst.height, 10, 10, 220, 277);
}
img{display:none}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<canvas id="myCanvas" width="240" height="297" style="border:1px solid #d3d3d3;">
</canvas>
<img src="http://www.w3schools.com/tags/img_the_scream.jpg" id="scream"/>
<img src="http://www.wpclipart.com/page_frames/picture_frames/wood_picture_frame.jpg" id="frame"/>
However, if you still have the access to that scream image, you can just draw frame first, then draw image on it:
var canvas = $('canvas')[0];
var ctx=canvas.getContext("2d");
var img=document.getElementById("scream");
var frame = document.getElementById("frame");
ctx.drawImage(frame,0,0, 240, 297);
// 10, 10 seems to fit the frame.
ctx.drawImage(img, 10, 10);
Please change id of your html and js file.

Cannot crop the image with correct location or original x,y.

I can get the location of top,left,width,height, but I can't crop as the alert show.
<script>
$(document).ready(function(e) {
$("#crop").click(function(){
var canvas=document.getElementById("Mystore1");
var context=canvas.getContext("2d");
var top=$('#face').offset().top;
var left=$('#face').offset().left;
var width=$('#face').width();
var height=$('#face').height();
alert(top);
alert(left);
alert(width);
alert(height);
var imageSrc ='../../../Public/Pictures/Sample Pictures/Desert.jpg';
var imageObj=new Image();
imageObj.onload=function(){
context.drawImage(imageObj, top, left, width, height, top, left, width, height);
};
imageObj.src=imageSrc;
});
});
</script>
here is an working demo. i found some problem in your code. on ready function param you should
send $ and on click an event variable named e (whatever you want).
croparea is the face area selected by your crop tool. main image is the image portion.
your js should be like so
$(document).ready(function($) {
$("#crop").click(function(e){
var Imgwidth = $('#face').width(),
Imgheight = $('#face').height(),
faceOffset = $('#face').offset(),
imgOffset = $('#imgHolder').find('img').offset(),
imgX1 = faceOffset.left-imgOffset.left,
imgY1 = faceOffset.top-imgOffset.top,
imgX2 =imgX1+Imgwidth,
imgY2 = imgY1+Imgheight;
var imageSrc ='http://www.html5canvastutorials.com/demos/assets/darth-vader.jpg';
var imageObj=new Image();
imageObj.src=imageSrc;
selx1 = imgX1;
sely1 = imgY1;
selx2 = imgX2;
sely2 = imgY2;
selw = Imgwidth;
selh = Imgheight;
console.log(imgX1);
console.log(imgY1);
/*console.log(imgX2);
console.log(imgY2);*/
var canvas=document.getElementById("Mystore1");
var context=canvas.getContext("2d");
context.canvas.height = Imgheight;
context.drawImage(imageObj, imgX1, imgY1, selw, selh, 3, 3, Imgwidth, canvas.height-5);
});
});
when you select an area ( here #face div) from an image to crop then i calculate the top-left(X,Y) co-ordinate of the selected area in this line
imgX1 = faceOffset.left-imgOffset.left,
imgY1 = faceOffset.top-imgOffset.top,
and the right-bottom co-ordinate in these line
imgX2 =imgX1+Imgwidth,
imgY2 = imgY1+Imgheight;
and thus we get a rectangular co-ordinate system to draw the portion of the image that we selected to crop. for drawImage documentation please go to the link that i post in comment. i hope now its clear how i get the exact position to crop.
here is a working demo click here

canvas overlay export

I have 2 canvas, canvas1 and canvas2. Both work well, but I want to mix them to export as image. Overlay css based do not work as it prints 2 images. Any point to start? thank you.
<canvas id="canvas1" style="position:relative; float:left;border:1px solid #000 " width="547" height="154">
</canvas>
<canvas id="canvas2" style="z-index: 1; position:absolute; float:left;" width="547" height="500">
</canvas>
Well, there are a few ways to go about this, and what do you mean by mix?
If you simply want to overlay canvas2 over canvas1, but don't want to alter either original canvas, you can send their data to another canvas, and then get that data.
method to follow:
draw canvas1 to canvas3
draw canvas2 to canvas3
get canvas3 image
working javascript:
// Make all the canvas and context variables */
var c1 = document.getElementById('c1');
var c2 = document.getElementById('c2');
var c3 = document.getElementById('c3');
var c4 = document.getElementById('c4');
var ctx1 = c1.getContext('2d');
var ctx2 = c2.getContext('2d');
var ctx3 = c3.getContext('2d');
var ctx4 = c4.getContext('2d');
/* */
// Draw square on canvas 1
ctx1.fillRect(0,0,50,50);
// Draw offset square on canvas 2
ctx2.fillRect(25,25,50,50);
// Make third image and onload function
var img3 = new Image();
img3.onload = function(){
// Draw this image to canvas 4 so that we know it worked
ctx4.drawImage(this,0,0);
}
// So we know when both have loaded
var imagesLoaded = 0;
function draw(){
// increment number loaded
imagesLoaded++;
// draw this image to canvas 3
ctx3.drawImage(this,0,0);
// if the have both loaded, then...
if (imagesLoaded == 2){
// set third image's src to the canvas 3 image
img3.src = c3.toDataURL();
}
}
// First image
var img1 = new Image();
// So it will draw on canvas 3
img1.onload = draw;
// Set the src to canvas 1's image
img1.src = c1.toDataURL();
// Second image
var img2 = new Image();
// So it will draw on canvas 3
img2.onload = draw;
// Set the src to canvas 2's image
img2.src = c2.toDataURL();
Working example here.
However, if that wasn't what you were looking for, I am sorry.

Categories