I use getImageData from a canvas and display it on another canvas using putImageData. But it doesn't cover the entire canvas.It displays the picture in its original size.Is there a way to make the cropped picture cover the whole canvas.Thank you in advance.Both canvases are 300 by 300 in size.
var c = document.getElementById("area_c");
var c2 = document.getElementById("area_c2");
var ctx = c.getContext("2d");
var ctx2 = c2.getContext("2d");
var imgData = ctx.getImageData(tx,new_ty ,x, new_y);
ctx2.putImageData(imgData, 0, 0);
In this snippet you can see how to scale another canvas with css (I used a string instead of an image to avoid CORS)
I also added a class if you want to use nearest-neighbor or pixelated
var c = document.getElementById("area_c");
var c2 = document.getElementById("area_c2");
var ctx = c.getContext("2d");
var ctx2 = c2.getContext("2d");
var w = 150;
var h = 70;
c.width = w;
c.height = h;
ctx.font = "50px Arial";
ctx.fillText('Image',0,50);
var x = 5;
var y = 15;
var cw = 60;
var ch = 35;
c2.width = cw;
c2.height = ch;
var scale = 2;
c2.style.width = scale*cw+'px';
c2.style.height = scale*ch+'px';
var imgData = ctx.getImageData(x,y,cw,ch);
ctx2.putImageData(imgData, 0, 0);
document.querySelector('input[name=pixelate]').addEventListener('change',()=>{c2.classList.toggle('pixelate')});
canvas {
border: 1px solid #333;
}
.pixelate {
image-rendering: auto;
image-rendering: crisp-edges;
image-rendering: pixelated;
}
<canvas id="area_c"></canvas>
<canvas id="area_c2"></canvas>
<input name="pixelate" type="checkbox"><label for="pixelate">Pixelate</label>
Related
How can I return the canvas on this function as webp image?
function capture(video) {
if(scaleFactor == null){
scaleFactor = 1;
}
//var w = video.videoWidth * scaleFactor;
//var h = video.videoHeight * scaleFactor;
var w = 700;
var h = 400;
var canvas = document.createElement('canvas');
canvas.width = w;
canvas.height = h;
var ctx = canvas.getContext('2d');
ctx.drawImage(video, 0, 0, w, h);
var uniq = 'img_' + (new Date()).getTime();
canvas.setAttribute('id', uniq);
return canvas ;
}
Canvas has a method known as .toDataURL(type, encoderOptions).
I this case the following snippet should suffice
canvas.toDataURL('image/webp');
This will give you a data url which is a base64 encoding of the image and will look something like
data:image/webp;base64,UklGRqgCAABXRUJQVlA4WAoAAAAwAAAAxwAAYwAASUNDUBgCAAAAAAIYAAAAAAQwAABtbnRyUkdCIFhZWiAAAAAAAAAAAAAAAABhY3NwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAA9tYAAQAAAADTLQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlkZXNjAAAA8AAAAHRyWFlaAAABZAAAABRnWFlaAAABeAAAABRiWFlaAAABjAAAABRyVFJDAAABoAAAAChnVFJDAAABoAAAAChiVFJDAAABoAAAACh3dHB0AAAByAAAABRjcHJ0AAAB3AAAADxtbHVjAAAAAAAAAAEAAAAMZW5VUwAAAFgAAAAcAHMAUgBHAEIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFhZWiAAAAAAAABvogAAOPUAAAOQWFlaIAAAAAAAAGKZAAC3hQAAGNpYWVogAAAAAAAAJKAAAA+EAAC2z3BhcmEAAAAAAAQAAAACZmYAAPKnAAANWQAAE9AAAApbAAAAAAAAAABYWVogAAAAAAAA9tYAAQAAAADTLW1sdWMAAAAAAAAAAQAAAAxlblVTAAAAIAAAABwARwBvAG8AZwBsAGUAIABJAG4AYwAuACAAMgAwADEANkFMUEgPAAAAAQcQEREAUKT//yWi/6lwAFZQOCBSAAAA8AcAnQEqyABkAD5tNplJpCMioSBoAIANiWlu4XXwADuh1VJsmIdVSbJiHVUmyYh1VJsmIdVSbJiHVUmyYh1VJsmIdVSbJhYAAP7/wbAAAAAAAA==
More information for this can be found on https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toDataURL
I am having an issue creating an image of a canvas and translating it onto another canvas. The end goal is to create a loupe magnifier for a cgm viewer/editor, but I'm stuck on this issue. Here is an example.
HTML:
<canvas id="canvas" width=240 height=240 style="background-color: aqua;
left:0;right:0;margin:auto;z-index:1;margin-top:0px;">
</canvas>
<canvas id="canvas1" width=240 height=240 style="background-color:#808080;">
</canvas>
<p></p>
<a id="download" href="" onclick="draw_image();">Download to myImage.jpg</a>
JS:
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var ox = canvas.width / 2;
var oy = canvas.height / 2;
ctx.font = "42px serif";
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.fillStyle = "#800";
ctx.fillRect(ox / 2, oy / 2, ox, oy);
draw_image = function() {
let canvas1 = document.getElementById('canvas1')
var image = canvas1.toDataURL("image/png")
let ctx1 = canvas1.getContext("2d");
ctx.drawImage(image, 0, 0)
};
You probably wanted to just draw a canvas, no some url
And you wanted to type ctx1 and not ctx
draw_image = function() {
let canvas1 = document.getElementById('canvas1')
let ctx1 = canvas1.getContext("2d");
// just draw the original canvas
ctx1.drawImage(canvas, 0, 0)
};
I am trying to resize a canvas in all directions the way Photoshop does.
I tried with JS but it's not matching the output I got from the Photoshop CC canvas size feature.
Original Image (600 x 439): http://i.imgur.com/rXURSWC.jpg
Resized with JS code (580 x 430): http://i.imgur.com/fwUiHyF.png
Resized with Photoshop CC (Image->Canvas Size) (580 x 430): http://i.imgur.com/smXTNv2.jpg
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
var x = 0;
var y = 0;
var width = 580;
var height = 430;
var imageObj = new Image();
imageObj.onload = function() {
context.drawImage(imageObj, x, y, width, height);
};
imageObj.src = 'https://i.imgur.com/rXURSWC.jpg';
<body>
<canvas id="myCanvas" width="580" height="430"></canvas>
</body>
So, any idea how I can resize canvas in all directions the way photoshop CC does so that it can match to output of Photoshop CC.
JSFiddle: https://jsfiddle.net/f2L4b942/
What you are asking for is just to crop your image, but keep the anchor point in the middle.
This is easily implemented :
Set the x and y parameters of drawImage to the difference between the required size and the original one, divided by 2.
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
var requiredWidth = canvas.width = 580;
var requiredHeight = canvas.height = 430;
var img = new Image();
img.onload = function() {
// all you need is here
var offsetX = (requiredWidth - img.naturalWidth) / 2;
var offsetY = (requiredHeight - img.naturalHeight) / 2;
context.drawImage(img, offsetX, offsetY, img.naturalWidth, img.naturalHeight);
};
img.src = 'http://i.imgur.com/rXURSWC.jpg';
<canvas id="myCanvas" width="580" height="430"></canvas>
You could accomplish this by redefining the canvas width and height upon image load ...
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
var x = 0;
var y = 0;
var imageObj = new Image();
imageObj.onload = function() {
canvas.width = this.width;
canvas.height = this.height;
context.drawImage(imageObj, x, y);
};
imageObj.src = 'http://i.imgur.com/rXURSWC.jpg';
body {
margin: 0px;
padding: 0px;
}
#myCanvas {
border: 1px solid black;
}
<canvas id="myCanvas" width="580" height="430"></canvas>
I am making a Canvas Pattern using the following javascript:
//$('#canvas1').height($(document).height());
//console.log($('#canvas1').width($(document).width()));
var can = document.getElementById('canvas1');
var ctx = can.getContext('2d');
// set up a pattern
var pattern = document.createElement('canvas');
pattern.width = 80;
pattern.height = 80;
var pctx = pattern.getContext('2d');
pctx.beginPath();
pctx.lineWidth = "3";
pctx.strokeStyle = "red";
pctx.rect(74, 74, 3, 3);
pctx.stroke();
var pattern = ctx.createPattern(pattern, "repeat");
ctx.rect(0,0,800,800);
ctx.fillStyle = pattern;
ctx.fill();
The resulting pattern doesn't seem to repeat even when the ctx.rect values are defined as 800. The canvas is as follows:
<canvas id="canvas1"style="position:absolute;left:0;top:0;"></canvas>
How can I make it repeat throughout the height and width of current page. I know that I can set the height and width using jQuery and I tested that, but the pattern is still not repeating. Where am I going wrong?
Well, I guess you got confused with .rect()'s parameters. It should be pctx.rect(3, 3, 74, 74).
var can = document.getElementById('canvas1');
var ctx = can.getContext('2d');
// set up a pattern
var pattern = document.createElement('canvas');
pattern.width = 80;
pattern.height = 80;
var pctx = pattern.getContext('2d');
pctx.beginPath();
pctx.lineWidth = "3";
pctx.strokeStyle = "red";
pctx.rect(3, 3, 74, 74);
pctx.stroke();
var _pattern = ctx.createPattern(pattern, "repeat");
ctx.rect(0, 0, can.width, can.height);
ctx.fillStyle = _pattern;
ctx.fill();
<canvas id="canvas1" width="320" height="320" style="border: 1px solid black; position: absolute; left: 0; top: 0;"></canvas>
I'm not sure if that's the root of your problem, but when you change the width, you should write pattern.style.width = "80px";
The same applies for height
Let me know if that fixes your problems
Basic text stroke code.
<body>
<canvas id="myCanvas" width="578" height="200"></canvas>
<script>
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
var x = 80;
var y = 110;
context.font = '100pt arial';
context.lineWidth = 37;
context.strokeStyle = "rgba(255,0,0,0.5)";
context.strokeText('Ho', x, y);
</script>
Output in Chrome and Firefox is :
The overlapping area between 'H' and 'o' is darker than non overlapping area.
I want to have same opacity/alpha for the stroke text.
I tried it in Safari on Mac system and there was not such a problem. In safari i got uniform opacity/alpha for both overlapping and non-overlapping region.
I need to understand why this is happening in chrome and what should i do to have uniform opacity/alpha.
The behaviour is not what is to be expected, the strokeText call one would expect to be part of a single path, and would consider it a bug in both Chrome and Firefox.
Nevertheless you need a solution. The only one I can think of is to create a second canvas. Render the text without opacity on that canvas then render that canvas onto the original canvas using ctx.globalAlpha = 0.5
Example.
var canvas = document.createElement("canvas");
canvas.width = 500;
canvas.height = 500;
var ctx = canvas.getContext("2d");
document.body.appendChild(canvas);
var x = 40;
var y = 110;
ctx.font = '100pt arial';
ctx.lineWidth = 20;
ctx.fillRect(10,y,500,10);
ctx.strokeStyle = "rgba(255,0,0,0.5)";
ctx.strokeText('Bad', x, y);
var workCan = document.createElement("canvas");
workCan.width = canvas.width;
workCan.height = canvas.height;
var ctx1 = workCan.getContext("2d");
ctx1.font = '100pt arial';
ctx1.lineWidth = 20;
ctx1.strokeStyle = "rgba(255,0,0,1)";
x = 40;
y = 260;
ctx1.strokeText('Good', x, y);
ctx.fillRect(10,y,500,10);
ctx.globalAlpha = 0.5;
ctx.drawImage(workCan,0,0);
You can use plain CSS gradient with alpha values, and the alpha will not add up:
background: -webkit-linear-gradient(top, rgba(10, 14, 15, 0.3), rgba(10, 14, 15, 0.3));
-webkit-background-clip: text;
-webkit-text-stroke: 1vw transparent;