HTML5/ Javascript - Stretch image source - javascript

Hi I'm getting image from webcam and I save it on canvas, what I want to do is to stretch it by x and y cooridnates keeping same img dimensions, what I mean is, this is the original webcam picture:
and this is how I wanna it to be when stretched:
<canvas id="canvas" width="640" height="480" style="border:1px solid #d3d3d3;"></canvas>
this is the piece of code that shows source image to <img> element in html , so I have to stretch source image before to show it in html
function snap() {
if (localMediaStream) {
ctx.drawImage(video, 0, 0);
var oImg=document.createElement("img");
oImg.setAttribute('src', canvas.toDataURL());
oImg.setAttribute('alt', 'na');
oImg.setAttribute('width', '1300');
oImg.setAttribute('height', '1300');
var img = document.body.appendChild(oImg);
return img;
}
}
any idea on how to stretch the canvas.toDataUrL() source by x and y coordinates and return it stretched to the the src <img> element?
The real problem imo is how to stretch image without altering width
and height (as shown via example photos above), is this possible?

You can use the extended properties on context.drawImage that allow scaling/positioning.
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var img=new Image();
img.onload=function(){
var w=img.width;
var h=img.height;
canvas.width=w; // set the canvas size to the original image size
canvas.height=h;
ctx.drawImage(img,
0,0,w,h, // start with the image at original size
-w/4,0,w*1.25,h // widen the original image by 1.25X
// and start drawing 1/4th off the left edge of the canvas
);
}
img.src="temp18.png";

Related

Add white spaces to image Javascript

is there a way to add white spaces to an image in javascript ?
I this the image 1 and I want to edit or create a new image, to add white spaces and the result would be the image 2.
The following code achieves this task. Basically, we create a canvas and set it to the size of the desired output. We then fill it with white before drawing the original image at (0,250) This centers the image (I should have done this with code, but instead looked at your output image in an image editor. (OutputHeight-InputHeight)/2 = Y offset to draw image at.
Since you're not actually adding any detail, it's possible this isn't the best way to go about what you're trying to achieve. It's possible that you should use margin/padding to expand the room the image appears to occupy.
window.addEventListener('load', onLoaded, false);
function onLoaded(evt)
{
let img = document.querySelector('img');
let canvas = document.querySelector('#output');
let ctx = canvas.getContext('2d');
ctx.fillStyle = '#fff';
ctx.fillRect(0,0,759,759);
ctx.drawImage(img, 0, 250);
}
body{
background-color: #ddd;
}
<img src='https://i.stack.imgur.com/bN5hp.jpg'/>
<hr>
<canvas id='output' width=760 height=760/></canvas>
You can do it using the canvas object.. if you have the image for instance
<img src="some.jpeg" id="myImg">
You can copy it to a new canvas and play with the drawImage properties
var img = document.getElementById('myImg');
var canvas = document.createElement('canvas');
canvas.width = img.width; // add here the extra width you want
canvas.height = img.height; // add here the extra height you want
canvas.getContext('2d').drawImage(img, 0, 0, img.width, img.height); // play here with the position, 0, 0 are the top x,y axis
Here is the link to mozilla documentation:
https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/drawImage

How to export Canva Render has GIF with CSS modification

I'm using p5.js to make a GIF animation but I have an issue when I want to export it.
I did a pixelased effect on my animation by adding these css properties to the Canva (140*140) :
image-rendering: pixelated;
width:500px;
height:500px;
My problem is that I can't export this Canva with the properties I added. (I'm using CCapture)
My gif is in 140x140 without the pixelated effect.
How can I get the rendering I need?
There is a difference between the width & height you can set for a HTML element e.g. <canvas width='140' height='140'> and the CSS width & height properties.
The former defines the actual size of the canvas - 140x 140in this case.
If we now set the CSS width & height to something deviating from the HTML element's width & height e.g. <canvas width='140' height='140' style='width: 500px; height:500px;'> the actual size in pixels of the canvas does not change - it stays 140 x 140 pixels. The CSS properties just control the displayed size of the element inside the browser, meaning the 140 x 140 are simply stretched to 500 x 500.
So if you get actual pixel data of the canvas - for exporting to gif/png - the final image will have the original dimensions of the canvas - not the rendered.
The fix is quite simple though. Instead of directly using the source canvas for exporting, draw it's content on a second canvas, the size of your desired resolution.
To force the 'export' canvas to not use any filtering/smoothing, you need to set the imageSmoothingEnabled property of it's context to false.
Here's an example (you can right-click and save both images to see the difference):
var ctx = document.getElementById('canvas').getContext('2d');
var image = new Image();
image.onload = function() {
ctx.drawImage(image, 0, 0);
let sourceCanvas = document.getElementById("canvas");
let virtualWidth = parseInt(getComputedStyle(sourceCanvas).width);
let virtualHeight = parseInt(getComputedStyle(sourceCanvas).height);
var canvas = document.getElementById("exportCanvas");
canvas.width = virtualWidth;
canvas.height = virtualHeight;
canvas.getContext('2d').imageSmoothingEnabled = false;
canvas.getContext('2d').drawImage(sourceCanvas, 0, 0, virtualWidth, virtualHeight);
}
image.src = 'https://mdn.mozillademos.org/files/12640/cat.png';
canvas {
width: 500px;
height: 500px;
}
<span>Rendered canvas</span><br>
<canvas id="canvas" width="140" height="140"></canvas><br>
<span>Export canvas</span><br>
<canvas id="exportCanvas"></canvas>

How to detect transparent area click OR if user draw in transparent area in canvas?

I'm drawing an image onto a canvas using drawImage. It's a PNG that is surrounded by transparent pixels, like this:
How can I detect a drawing move path in the transparent part of that image on the canvas? I want to detect if a user draws in a transparent part.
I am trying this tutorial and I did as showing in the tutorial.
var ctx = canvas.getContext('2d'),
img = new Image;
img.onload = draw;
img.src = "http://i.stack.imgur.com/UFBxY.png";
function draw() {
// draw original image in normal mode
ctx.drawImage(img, 10, 10);
}
<canvas id=canvas width=500 height=500></canvas>
Check it out full code on Github
Check it out live demo IonCanvas
To find out is a pixel is transparent get the pixel using ctx.getImageData and look at the alpha value.
Example
// assumes ctx is defined
// returns true if pixel is fully transparent
function isTransparent(x, y) { // x, y coordinate of pixel
return ctx.getImageData(x, y, 1, 1).data[3] === 0; // 4th byte is alpha
}

How to create an image generator for combining multiple images?

I am working on an image generator using HTML5 canvas and jQuery/JS. What I want to accomplish is the following.
The user can upload 2 or max 3 images (type should be png or jpg) to the canvas. The generated images should always be 1080x1920. If the hart uploads only 2 images, the images are 1080x960. If 3 images are uploaded, the size of each image should be 1080x640.
After they upload 2 or 3 images, the user can click on the download button to get the merged image, with a format of 1080x1920px.
It should make use of html canvas to get this done.
I came up with this:
HTML:
<canvas id="canvas">
Sorry, canvas not supported
</canvas><!-- /canvas.offers -->
<input id="fileInput" type="file" />
Generate
jQuery:
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
canvas.height = 400;
canvas.width = 800;
var img1 = loadImage('http://www.shsu.edu/dotAsset/0e829093-971c-4037-9c1b-864a7be1dbe8.png', main);
var img2 = loadImage('https://upload.wikimedia.org/wikipedia/commons/thumb/c/c5/Ikea_logo.svg/266px-Ikea_logo.svg.png', main);
var minImages = 2;
var imagesLoaded = 0;
function main() {
imagesLoaded += 1;
if(imagesLoaded >= minImages) {
ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.save();
ctx.drawImage(img1, 0, 0);
// ctx.translate(canvas.height/2,canvas.width/2); // move to the center of the canvas
// ctx.rotate(270*Math.PI/180); // rotate the canvas to the specified degrees
// ctx.drawImage(img2,0,canvas.height/2);
ctx.translate(-canvas.height/2,canvas.width/2); // move to the center of the canvas
ctx.rotate(90*Math.PI/180); // rotate the canvas to the specified degrees
ctx.drawImage(img2,-img2.width/2,-img2.width/2);
ctx.restore(); // restore the unrotated context
}
}
function loadImage(src, onload) {
var img = new Image();
img.onload = onload;
img.src = src;
console.log(img);
return img;
}
Above code will create the canvas and place both images (that are now hard-coded in JS) to the created canvas. It will rotate 90 degrees, but it will not position to the right corner. Also the second image should be position beside the first one.
How can I do the rotation and positioning of each image side by side?
Working Fiddle: https://jsfiddle.net/8ww1x4eq/2/
Have a look at the updated jsFiddle, is that what you wanted?
Have a look here regarding image rotation
Updated jsFiddle, drawing multiple images.
Notice:
The save script was just a lazy way to make sure I've got the
external scripts loaded before I save the merged_image...
There is no synchornisation in the sample script, notice that addToCanvas
was called on image loaded event, there could be a race condition
here (but I doubt it, since the image is loaded to memory on
client-side)
function addToCanvas(img) {
// resize canvas to fit the image
// height should be the max width of the images added, since we rotate -90 degree
// width is just a sum of all images' height
canvas.height = max(lastHeight, img.width);
canvas.width = lastWidth + img.height;
ctx.clearRect(0, 0, canvas.width, canvas.height);
if (lastImage) {
ctx.drawImage(lastImage, 0, canvas.height - lastImage.height);
}
ctx.rotate(270 * Math.PI / 180); // rotate the canvas to the specified degrees
ctx.drawImage(img, -canvas.height, lastWidth);
lastImage = new Image();
lastImage.src = canvas.toDataURL();
lastWidth += img.height;
lastHeight = canvas.height;
imagesLoaded += 1;
}
PS: I've added some script to download the merged image, but it would fail. The error message was: "Uncaught SecurityError: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported."
I've done a quick Google search and it seemed to be related to Cross-origin resources. I assumed that it wouldn't be an issue with FileReader. I haven't had time to test that so please test it (and please let me know :) It works with FileReader!
You can use toDataURL. But in this way user must do something like Save image as...
var img = canvas.toDataURL("image/png");
And then set for example img result src:
$("#result").attr("src",img);
Canvas is already an Image.
The canvas and img are interchangeable so there is no need to add the risky step of canvas.toDataURL which can fail depending on the image source domain. Just treat the canvas as if it were and img and put it in the DOM. Converting to a jpg does not save space (actually a resource hungry operation) as the an img needs to be decoded before it can be displayed.
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
canvas.height = 400;
canvas.width = 800;
document.body.appendChild(canvas); // add to the end of the document
// or add it to a containing element
var container = document.getElementById("containerID"); // or use JQuery
if(container !== null){
container.appendChild(canvas);
}

Replacing divs with background images with canvas elements

I am trying to replace any divs that have background images with canvas elements with those background images drawn onto them.
I've got the basics working but I am slightly stumped by the difference in image quality between the background-image on a div and the same image drawn onto a canvas.
Here is the code I am using to do this:
$('#container div').each(function(){
if($(this).css('background-image') != 'none'){
var bgImage = $(this).css('background-image').replace(/^url|[\(\)]/g, '');
var image = new Image();
var attrs = $(this)[0].attributes;
var dimensions = new Array();
var canvas = document.createElement('canvas');
dimensions.push($(this).height())
dimensions.push($(this).width());
$(canvas).attr('width',dimensions[0]);
$(canvas).attr('height',dimensions[1]);
$(canvas).css('background-image', 'none');
for(var i = 0; i < attrs.length; i++){
$(canvas).attr(attrs[i].nodeName,attrs[i].nodeValue);
}
var ctx = canvas.getContext('2d');
image.onload = function () {
ctx.drawImage(image, 0, 0, image.height, image.width);
}
image.src = bgImage;
$(this).replaceWith(canvas);
}
});
Here are the results:
It looks like the image is being stretched for some reason but I've tried to console.log the width/height of the image that I am using in drawImage and the values match up to the image dimensions. The results show just a crop of the image - the real one is 900x4000ish pixels.
Here is a jsfiddle link showing the problem in action:
http://jsfiddle.net/xRKJt/
What is causing this odd behaviour?
Ha! (took some seconds to figure out)
Image has naturalWidth and naturalHeight attributes which reflect its pixel dimensions. Change your code
image.onload = function () {
ctx.drawImage(image, 0, 0, image.naturalWidth, image.naturalHeight);
}
Because the image is so large, if you open the image in the browser it zooms out it by default. I think you'll get those zoomed out width and height attributes if you try to access image.width and image.height. Or something along the lines.

Categories