FabricJS toDataURL returning wrong scale? - javascript

After rendering the canvas the toDataURL returning image with canvas scale(My canvas scale is 700 x 600). How to return image with my Original Height and Width. Not canvas Width and Height. Here is the code section.
$(document).on('click','#btn-save-canvas', function(event) {
if (!fabric.Canvas.supports('toDataURL')) {
alert('This browser doesn\'t provide means to serialize canvas to an image');
}
else {
canvas.overlayImage.filters = [];
canvas.overlayImage.applyFilters();
canvas.renderAll();
var multi = maskOriWidth/maskWidth;
console.log(multi);
window.open(canvas.toDataURL({
format: 'png',
multiplier: 0,
}));
}
});

Related

Placing an image on a canvas JS

I have the following in html:
<img id="MarkingImage"></img>
<canvas id="MarkingCanvas"></canvas>
And on css:
#MarkingCanvas { width: 100%; background-color: #7986CB; height: 96%; }
#MarkingImage { position: absolute; }
And on js:
function LoadImage()
{
var markingImage = new Image();
markingImage.addEventListener('load', function()
{
m_imageWidth = this.naturalWidth;
m_imageHeight = this.naturalHeight;
m_markingCanvasContext.drawImage(markingImage, 0, 0, m_imageWidth, m_imageHeight);
});
markingImage.src = 'PICT0001.JPG';
}
The thing is that this output stretches the image and it's quality gets really poor (see attached "Original" and "Result").
When I debug, I can see that the sizes if my canvas are:
width - 1410
height - 775
The sizes if my image are:
width - 551
height - 335
So my question is: why isn't the image placed in it's original size? I mean, there's enough space on the canvas. Also, why does the image gets stretched, and as a result gets in pretty low quality. Appears like it stretches beyond the size of the canvas.
What am I missing here?
You need to set the canvas width and height dynamically according to the browser window's width and height. also, there is no need to use the image's naturalWidth / naturalHeight.
var m_markingCanvas = document.getElementById('MarkingCanvas');
var m_markingCanvasContext = m_markingCanvas.getContext('2d');
// setting canvas width and height dynamically
m_markingCanvas.width = window.innerWidth;
m_markingCanvas.height = window.innerHeight;
function LoadImage() {
var markingImage = new Image();
markingImage.addEventListener('load', function() {
m_markingCanvasContext.drawImage(this, 0, 0);
});
markingImage.src = 'https://i.stack.imgur.com/a3Wpy.jpg';
}
LoadImage();
<canvas id="MarkingCanvas"></canvas>

fabricjs set clipped object as background to canvas after clipping

In my fabricjs I am making a canvas and adding an image to it and setting the image as background. and then I am clipping the cavas to some width and height.
After I clip the canvas I want a new canvas or same canvas with clipped area as background all covering the canvas with its width and height or can make new canvas with clipped area's height and width
Currently I am doing this..
function crop(url, name, left, top, width, height, callback) {
var c = document.createElement('canvas')
var id = "canvas_" + name
c.id = id
var canvas = new fabric.Canvas(id)
fabric.Image.fromURL(url, function(oImg) {
oImg.set({
selectable:false,
})
canvas.setDimensions({width:oImg.width, height:oImg.height})
canvas.add(oImg)
canvas.clipTo = function (ctx) {
ctx.rect(left, top, width, height)
console.log(ctx)
};
canvas.centerObject(oImg)
canvas.renderAll()
var img = canvas.toDataURL('image/png')
console.log(img)
callback(img)
}, {crossOrigin: "Anonymous"})
}
Here I can easyly clip the canvas with my given left, top, width and height but I am getting the same canvas with clipped clipped part and removed part with another color. But after clipping I want the clipped part to paint over canvas or set clipped part as background.
How can I do that ??
Actually you cropped the rendering of the canvas.
To save the cropped area you must use Canvas.toDataURL() method, as you can see there is parameters top, left, width, height just use the same as you put into ctx.rect(left, top, width, height) and it will returns you a string representing the cropped area (base64 encoded).
Then use this string as your canvas new background image with Canvas.setBackgrounsImage
Your code should look like:
function crop(url, name, left, top, width, height, callback) {
var c = document.createElement('canvas')
var id = "canvas_" + name
c.id = id
var canvas = new fabric.Canvas(id)
fabric.Image.fromURL(url, function(oImg) {
oImg.set({
selectable:false,
})
canvas.setDimensions({width:oImg.width, height:oImg.height})
canvas.add(oImg)
canvas.centerObject(oImg)
canvas.renderAll()
var img = canvas.toDataURL({
format: 'image/png',
left: left,
right: right,
width: width,
height: height
})
console.log(img)
canvas.setBackgroundImage(img)
callback(img)
}, {crossOrigin: "Anonymous"})
}

How to get Coordinate of Cropped Image by CropperJS?

I am using cropper JS to crop my image. I am able to get width and height of my canvas, however, need to know co-ordinates (X and Y) of cropped image.
Here is my code-
(function () {
//getting ratio
function getImageRatio(sourceCanvas) {
var canvas = document.createElement('canvas');
var context = canvas.getContext('2d');
var width = sourceCanvas.width;
var height = sourceCanvas.height;
canvas.width = width;
canvas.height = height;
context.beginPath();
context.arc(width / 2, height / 2, Math.min(width, height) / 2, 0, 2 * Math.PI);
context.strokeStyle = 'rgba(0,0,0,0)';
context.stroke();
context.clip();
context.drawImage(sourceCanvas, 0, 0, width, height);
return canvas;
}
window.addEventListener('DOMContentLoaded', function () {
var image = document.getElementById('image');
var button = document.getElementById('button');
var result = document.getElementById('result');
var croppable = false;
var cropper = new Cropper(image, {
aspectRatio: 1,
viewMode: 1,
built: function () {
croppable = true;
}
});
button.onclick = function () {
var croppedCanvas;
var roundedCanvas;
var roundedImage;
if (!croppable) {
return;
}
// Crop
croppedCanvas = cropper.getCroppedCanvas();
console.log(getImageRatio(croppedCanvas));
};
});
})();
Any idea, how to get coordinate of cropped image, so that I can crop this image by PHP.
So, if i understand properly, you are looking for the method getData.
It will return these properties as the documentation says:
x: the offset left of the cropped area
y: the offset top of the cropped area
width: the width of the cropped area
height: the height of the cropped area
rotate: the rotated degrees of the image
scaleX: the scaling factor to apply on the abscissa of the image
scaleY: the scaling factor to apply on the ordinate of the image
Although, i suggest taking a look at this section of the doc:
https://github.com/fengyuanchen/cropper#getcroppedcanvasoptions
Specifically at this part:
After then, you can display the canvas as an image directly, or use HTMLCanvasElement.toDataURL to get a Data URL, or use HTMLCanvasElement.toBlob to get a blob and upload it to server with FormData if the browser supports these APIs.
If you cannot use the toBlob method because some browser limitation (you can always add a polyfill), you can get the image using toDataUrl over the canvas (IE9+). And send it to the backend service already cropped. For this you are going to need to do something like this:
var formData = new FormData();
formData.append('image', canvas.toDataURL());
You can check the formData browser support in caniuse
Hope you find it helpful!

canvas not drawing complete image from uri

i am using ionic and trying to draw selected image on canvas and convert it into base64 string. when i select image of low quality/size it appear perfectly fine but when image of high quality is selected, it only shows the upper part of image like image gets cropped.
$scope.getImages = function() {
$scope.modal.hide();
// Image picker will load images according to these settings
var options = {
maximumImagesCount: 1, // Max number of selected images, I'm using only one for this example
width: 800,
height: 800,
quality: 80 // Higher is better
};
$cordovaImagePicker.getPictures(options).then(function (results) {
// Loop through acquired images
for (var i = 0; i < results.length; i++) {
$scope.selectedImage = results[i];
}
}, function(error) {
console.log('Error: ' + JSON.stringify(error)); // In case of error
});
}
this is how image is being selected. the question is how can i draw complete selected image on canvas or in other words how can i get the image width and height in the loop, coz results[i] get only the uri of image.
This will help
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
var img = new Image();
img.onload = function()
{
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
}
img.src = imagePath

drawimage to a secified canvas width and height

If the source svg is in a responsive environment, how do I use drawImage() to draw a to a given canvas size?
Example: How do I get the svg drawn to a 412.5 x 487.5 canvas, if the original svg is 550 x 650 and it is being viewed on a mobile device (so obviously the svg will be seen smaller than the original size)?
Fiddle
svgToImage(svg2, function(img2){
ctx2.drawImage(img2, 0, 0);
});
function svgToImage(svg2, callback) {
var nurl = "data:image/svg+xml;utf8," + encodeURIComponent(svg2),
img2 = new Image;
img2.onload = function() {
callback(img2);
}
img2.src = nurl;
}
When you SVG has loaded, simply set the canvas size, then draw in the image using the width and height arguments of drawImage.
Note that a bitmap can only take integer values so your canvas has to be either 413x488 or 412x487. If you don't set the canvas size it will default to 300x150 and then stretch to the size you use for style/CSS:
svgToImage(svg2, function(img2){
ctx2.canvas.width = 413; // set canvas size
ctx2.canvas.height = 488;
ctx2.drawImage(img2, 0, 0, 413, 488); // draw SVG/image at same size
});
Updated fiddle

Categories