Drawing image on a canvas with toDataURL - javascript

I have toDataURL which I want drawn on a new canvas, which is 300 by 300 in size. The image doesn't stretch over the full space provided. I want it to be stretched over the canvas fully. Even appending to a div is okay which I tried but didn't work out, it also didn't fully occupy the space.The orginal image is anyway less than 300 and 300.Also when I remove the alert code doesn't function at all.
var c4 = document.getElementById("area_c4");
var ctx4 = c4.getContext("2d");
var dataURL = c2.toDataURL();
var myImg = new Image;
myImg.src = dataURL;
myImg.width = c4.width; // c4.width is 300px
myImg.height = c4.height; //c4.height is 300px
alert(c4.width); // when I remove this alert code doesn't work
ctx4.drawImage(myImg,0, 0 ,c4.width,c4.height); // the image doesnt strtch over 300px 300px region. It is displayed in its original size

To resize the image you will have to use the following version of CanvasRenderingContext2D.drawImage()
void ctx.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight)
image: An element to draw into the context.
sx: The x-axis coordinate of the top left corner of the sub-rectangle of the source image to draw into the destination context.
sy: The y-axis coordinate of the top left corner of the sub-rectangle of the source image to draw into the destination context.
sWidth: The width of the sub-rectangle of the source image to draw into the destination context. If not specified, the entire rectangle from the coordinates specified by sx and sy to the bottom-right corner of the image is used.
sHeight: The height of the sub-rectangle of the source image to draw into the destination context.
dx: The x-axis coordinate in the destination canvas at which to place the top-left corner of the source image.
dy: The y-axis coordinate in the destination canvas at which to place the top-left corner of the source image.
dWidth: The width to draw the image in the destination canvas. This allows scaling of the drawn image. If not specified, the image is not scaled in width when drawn.
dHeight: The height to draw the image in the destination canvas. This allows scaling of the drawn image. If not specified, the image is not scaled in height when drawn.
Also you will have to wait for the image to process the data uri before you can draw it onto the canvas. For this you can use the load event:
myImg.onload = function() {
// here you can draw the image on the canvas
}
The input image in the example is 10x10 pixels wide and will be stretched to 300x300 pixels.
const c4 = document.getElementById("area_c4");
var ctx4 = c4.getContext("2d");
var dataURL = "data:image/bmp;base64,Qk26AQAAAAAAAHoAAABsAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAAQkdScwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAABUVPxUVPxUVPxUVPxUVPz/AAD/AAD/AAD/AAD/AAAAAFRU/FRU/FRU/FRU/FRU/P8AAP8AAP8AAP8AAP8AAAAAVFT8VFT8VFT8VFT8VFT8/wAA/wAA/wAA/wAA/wAAAABUVPxUVPxUVPxUVPxUVPz/AAD/AAD/AAD/AAD/AAAAAFRU/FRU/FRU/FRU/FRU/P8AAP8AAP8AAP8AAP8AAAAAVFT8VFT8VFT8VFT8VFT8/wAA/wAA/wAA/wAA/wAAAABUVPxUVPxUVPxUVPxUVPz/AAD/AAD/AAD/AAD/AAAAAFRU/FRU/FRU/FRU/FRU/P8AAP8AAP8AAP8AAP8AAAAAVFT8VFT8VFT8VFT8VFT8/wAA/wAA/wAA/wAA/wAAAABUVPxUVPxUVPxUVPxUVPz/AAD/AAD/AAD/AAD/AAAAAA==";
var myImg = new Image();
// wait until the data uri has been processed
myImg.onload = function() {
// draw the image and scale it to the size of the canvas
ctx4.drawImage(this,
0, 0, this.width, this.height, /* source */
0, 0, c4.width, c4.height); /* destination */
}
myImg.src = dataURL;
/* not necessary for the solution, just to show the size of the input image */
document.getElementById("showcase").src = dataURL;
canvas {
width: 300px;
height: 300px;
}
<p>
<!-- not necessary for the solution, just to show the size of the input image -->
Input:<br /><img id="showcase" />
</p>
<p>
Output:<br /><canvas id="area_c4" width="300px" height="300px"></canvas>
</p>

Related

Split parts from a regular sized image sheet into separate images with JS

I am trying to display parts from an image sheet into separate images.
There's a way to do it with CSS, as in how Reddit Flairs work on the old version of Reddit.
Below is an image that acts as a sheet. I am going to call it unicode_page_00.png
body {
background-color: rgb(20, 20, 20);
}
<body>
<div>
<div style="background: url(https://i.stack.imgur.com/GxJOx.png); image-rendering: pixelated; width: 64px; height: 64px; background-size: 1024px; background-position: -64px 0px;">
</div>
</div>
<br>
<div>
<img src="https://i.stack.imgur.com/GxJOx.png">
</div>
</body>
https://jsfiddle.net/0ztpr5cq/1/
 
The first part displays an image taken from the image sheet. For this example, the sheet is 256x256 pixels and each character is 16x16 pixels.
I took it and zoomed it in by 4. So the first image shows as 64x64. Then I've shifted the position to display the second character on the sheet from left to right.
And below is the entire image sheet for demonstration.
This is done with CSS. The issue is that you can not save the image the way it was cropped and modified with CSS. Even if it would be made possible with CSS, it would take the entire image sheet and save that instead.
I am trying to display every character on the image sheet as separate images. That you could then freely zoom in with the pixelated effect.
 
The idea that I have is to turn them into Base64 or something and make the modifications there or before. And at the end, display the final result back into an image, as base64 or blob or other. And that all with the help of JavaScript.
But how would it work? What would the actual process be?
A good solution I came up with was this https://jsfiddle.net/1rmya08u/
You would have to use the canvas element. Here's the solution:
<canvas id="canvas" width="64" height="64"></canvas>
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
ctx.imageSmoothingEnabled = false; // For pixelated drawing
var sheet = new Image();
sheet.src = "https://i.stack.imgur.com/GxJOx.png";
sheet.onload = function () {
var sx = 0;
var sy = 0;
var sWidth = 16;
var sHeight = 16;
var dx = 0;
var dy = 0;
var dWidth = 64;
var dHeight = 64;
ctx.drawImage(sheet, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);
};
We're taking a 16x16 sample from the image sheet and rendering it at 64x64. For a better understanding of these arguments, take a look at the reference for ctx.drawImage()
And finally, you can get the result as an image with HTMLCanvasElement.toDataURL()

Canvas/Photo - getImageData not working

I am loading a picture into a canvas; I drawImage(), store getImageData() into a variable for manipulating. I would like to be able to manipulate the data many times for example: add/remove various filters. How can I store the data so that it updates every time I draw the picture with putImageData()?
Basically, I think I am misunderstanding the use of getImageData or using it incorrectly. My thought was that any manipulation that was done to the picture, I could run getImageData and update the variable that contained the information, and use it to "redraw" the picture.
Example:
In the snippet below Lets say I run a function that turn the picture black and white. I have another function that resizes the picture when it is clicked. When I resize the picture the the black and white filter disappears. What am I doing wrong to keep the information of the picture?
//Read in picture
var reader = new FileReader();
reader.onload = function leDraw(e){
imgObj = new Image();
picWidth = canvas.width/2;
picHeight = canvas.height/2;
imgObj.src = e.target.result;
newX = 0;
newY = 0;
ctx.drawImage(imgObj,0,0, picWidth, picHeight);
imageData = ctx.getImageData(newX,newY, canvas.width, canvas.height);
originalCopy = ctx.getImageData(newX,newY, picWidth, picHeight);
data = imageData.data;
function resize(val){ Resizes picture
userPicHeight = document.getElementById("cSelect").value;
userPicWidth = document.getElementById("cSelect").value;
ctx.clearRect(0,0, canvas.width, canvas.height);
ctx.drawImage(imgObj, newX, newY, userPicWidth, userPicHeight);
window['imageData'] = ctx.getImageData(newX,newY, userPicWidth, userPicHeight);
ctx.putImageData(imageData, newX, newY);
};
imageData is a snapshot of canvas pixel data. In your case it's the entire canvas's (colored--not B&W) pixel data.
So when you do .putImageData(imageData...) the unaltered snapshow is again displayed on the canvas.
If you want to rescale a B&W version of your picture:
Draw your color image on a new canvas created with var memCanvas = document.createElement. Size the canvas to the image size. The canvas can be left in-memory -- no need to appendChild it into the DOM.
Apply the filter to the new canvas with getImageData, modify pixel data, putImageData. Now you have an "image-canvas" that you can later use to resize, etc.
Draw the image-Canvas onto the visible canvas: context.drawImage(memCanvas,0,0). Yes, the memCanvas can be an image source for drawImage.
To scale the B&W version of the image, just clear the canvas, scale the canvas with context.scale & then draw the scaled B&W image with drawImage(memCanvas,0,0)
If you later want to re-rescale the B&W image, you can do Step#4 again.
Example code and a Demo using a grayscale filter:
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
var img=new Image
img.crossOrigin='anonymous';
img.onload=start;
img.src="https://dl.dropboxusercontent.com/u/139992952/multple/kingcard.png";
function start(){
// create a grayscale image-canvas
var grayImg=makeFilteredImageCanvas(img,grayscaleFilter);
// scale the visible canvas
ctx.scale(1.25,1.25);
// draw the grayscale imag-canvas on the canvas
// (the result will be scaled)
ctx.drawImage(grayImg,0,0);
}
function makeFilteredImageCanvas(img,filter){
var c=document.createElement('canvas');
var cctx=c.getContext('2d');
iw=c.width=img.width;
ih=c.height=img.height;
cctx.drawImage(img,0,0);
filter(cctx);
return(c);
}
function grayscaleFilter(context){
var canvas=context.canvas;
var w=canvas.width;
var h=canvas.height;
var imageData=context.getImageData(0,0,w,h);
var data=imageData.data;
for(var i=0;i<data.length;i+=4){
var gray=data[i]*0.33+data[i+1]*0.5+data[i+2]*0.16;
data[i]=data[i+1]=data[i+2]=gray;
}
context.putImageData(imageData,0,0);
}
body{ background-color: ivory; }
#canvas{border:1px solid red; margin:0 auto; }
<h4>Grayscale image scaled up by 25%</h4>
<canvas id="canvas" width=300 height=300></canvas>
<h4>Original Image:</h4>
<img src='https://dl.dropboxusercontent.com/u/139992952/multple/kingcard.png' crossOrigin='anonymous'>

Javascript - Putting ImageData Onto a Canvas Element - CanvasRenderingContext2D

I want to take a source image and put its pixel data into a element with a CanvasRenderingContext2D grid.
I'm writing a javascript function to work with certain pixel points of data,
but I keep getting an error from this line:
ctx.putImageData(sourceImage, 0, 0);
Here is my current javascript function that accepts a class ID of an img element as its argument:
function mapMyImage(sourceImageID) {
// Declare variable for my source image
var sourceImage = document.getElementById(sourceImageID);
// Creates a canvas element in the HTML to hold the pixels
var canvas = document.createElement('canvas');
// Create a 2D rendering context for our canvas
var ctx = canvas.getContext('2d');
// After the image has loaded, put the source image data into the
// 2D rendering context grid
function imgToPixelArray() {
// In the context of the canvas, make an array of pixels
ctx.putImageData(sourceImage, 0, 0);
}
// Call the above function once the source image has loaded
sourceImage.onload = imgToPixelArray();
// Get Access to the pixel map now stored in our 2D render
var imageData = ctx.getImageData(0, 0, 400, 300);
}
Why am I getting an error when I am trying to put my source image's pixel data into a 2D rendering context grid?
It looks like you want to clip a 400x300 subsection of the image and draw it into the canvas.
You don't need .getImageData and .putImageData to accomplish that.
You can use the clipping version of .drawImage to do that:
context.drawImage(
img, // the image source
0,0, // start clipping from the source at x=0, y=0
400,300 // clip a subsection that's 400x300 in size
0,0 // draw that clipped subsection on the canvas at x=0,y=0
400,300 // make the drawing 400x300 (don't scale)
)
Here's example code and a Demo:
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
var img=new Image();
img.onload=start;
img.src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/landscape2.jpg";
function start(){
ctx.drawImage(img, 0,0,400,300, 0,0,400,300);
}
body{ background-color: ivory; padding:10px; }
#canvas{border:1px solid red;}
<h4>subsection clipped to the canvas</h4>
<canvas id="canvas" width=400 height=300></canvas>
<h4>The original image</h4>
<img src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/landscape2.jpg">

Javascript SVG clipto with clip rule (fabricjs)

There is the exemple in img
http://imgur.com/rFdcctc
I have a background where i put an image (phone case).
After that i put a rectangle on the top side (50% top). (canvas)
On that i put an svg that is an another mask (that follow the case curves).
The svg is the same as the entire background in size. So to only have the top of the SVG i "clip" a rectangle on to it.
var clipTo = function(ctx) {
var w = mask.width, h = mask.height;
var x = -w/2, y = -h/2;
var rx = 0, ry = 0;
ctx.moveTo(x+rx, y);
ctx.lineTo(x+w-rx, y);
ctx.lineTo(x+w, y+(h/2)-ry);
ctx.lineTo(x+rx,y+(h/2));
ctx.lineTo(x,y+ry);
ctx.closePath();
};
mask.setClipTo(clipTo);
And it works fine. But when i put a dragable image on it the image is mask by the SVG but not the clip rectangle, as if the clip is still there. (in the image, the content of the red rectangle should be invisible)
I have found that there is a clip-rule :
https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/clip-rule
that could maybe with luck enventually should do it, but i have no idea how to apply it in javascript (i use fabricjs)
So if someone has an idea... :)
Thank you

Creating a repeating image during zooming for kineticJS?

I'm using KineticJS and trying to get proper zoom functionality. I have a layer to which I have appended a background image at the original dimensions I want.
However when I zoom in (via layer.setScale()), my image shrinks when zooming in along with everything else (leaving exposed white areas).
So how can I make my image repeat even when this happens? Here is the code I used to add my image:
var imageObj = new Image();
imageObj.onload = function() {
var image = new Kinetic.Image({
image: imageObj,
width: width,
height: height
});
// add the shape to the layer
main_layer.add(image);
// add the layer to the stage
stage.add(main_layer);
};
imageObj.src = 'images/blueprint_background.png';
Try to create rectangle and then fill it with the image.
var rect = new Kinetic.Rect({
x: 0,
y: 0,
width: 2 * imageObj.width,
height: imageObj.height,
fillPatternImage: imageObj,
fillPatternRepeat: 'repeat-x'
});
This rectangle will repeat your image twice by Ox.
You can try to create long rectangle then when you will scale layer or you can dynamically resize rectangle as scale changes.

Categories

Resources