html2canvas not support transform property? - javascript

I build an image editor in javascript for my customer and we issue one huge problem. When we want to generate image where is some text rotated, canvas not generate full image with all contents over background.
Here is example:
When I click on save button I get empty background like this:
On other way, when I just add content and NOT do rotation, transform not exists in CSS, I can change color of text, change font, change background and all will look nice like on this example:
Result is perfect:
Here is my code:
function generateImage(canvas, width){
var img = new Image();
img.crossOrigin = "Anonymous";
img.width = width;
img.height = (img.width / ( 16 / 9 ));
img.src = canvas.toDataURL();
img.align = 'middle';
img.class = 'img-responsive';
img.style.width = '100%';
img.style.maxWidth = width;
document.body.appendChild(img);
}
html2canvas($this, {
onrendered: function(canvas) {
generateImage(canvas, ($this.width()+2));
},
width: $this.width()+2,
height: $this.height()+2
});
The main question is:
Is there a way to add in canvas CSS transition support to can render proper full image or some 3D canvas drawing which work properly?

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 handle SVG and canvas in pdfmake & html2pdfmake

I am using html2pdfmake to convert a div to pdf. My div contains tables and also contains some svg charts. But i am not getting the svg into the pdf. I tried converting it using base64 but is paste the base64 code into the pdf.
I converted my svg to base64 like :
var html = d3.select('#idOfSVG').select("svg").attr("version", 1.1).attr("xmlns", "http://www.w3.org/2000/svg").node().parentNode.innerHTML;
var imgsrc = 'data:image/svg+xml;base64,'+ btoa(html);
var base_image = new Image();
base_image.src = imgsrc;
canvas = document.createElement('canvas');
canvas.id = 'canvas'
document.body.appendChild(canvas);
canvas.width = 500;
canvas.height = 500;
canvas.getContext('2d').drawImage(base_image,0,0);
Then i added the same into the content.
Also when i used ParseHtml(content,document.getElementById("myPDFDiv"))
My div myPDFDiv gets deleted from the DOM.
Any help will be highly appreciated !!
You can use html2pdfmake, it iterates all the elements in the div and make JSON for the same which you can use with pdfmake.
You can add SVG support by adding a switch case for SVG like :
Case 'SVG' :
addImage(cnt,e);
function addImage (cnt,e) {
//Serialize the svg element and then put it in a canvas
//Then update the cnt object
var url = canvas.toDataURL('image/png');
cnt.push({image: url,
width: 200,
height: 250,
margin: [ 20, 0, 0, 0 ]
});
}
Hope it helps !!

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);
}

How to make html5 canvas display crisp image based off chrome screencap

I am making a chrome extension that uses the chrome.tabs.captureVisibleTab method to grab a screencap of the current tab and then displays that in a popup from the chrome extension. If I use the img tag and use the data coming from the chrome function, such as data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAMCAgMCAgMDAwMEAwME…UUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAf/2Q==, the <img> displays pixel perfect, it is crisp and that's what I want. Problem is that I need to make it into a canvas, and when I do that, it becomes blurry.
This is a screencap of the <img> that uses the link data provided by Google to be used as a comparison to the canvas which is below.
This is the blurry canvas.
This is the code that I am using to try to do this, but I can't figure out how to make the canvas crisp like the image.
chrome.runtime.sendMessage({msg: "capture"}, function(response) {
console.log(response.imgSrc);
var img = document.createElement('img');
var _canvas = document.createElement("canvas");
img.src = response.imgSrc;
img.height = 436;
img.width = 800;
document.getElementById('main-canvas').appendChild(img);
draw(response);
});
function draw(response) {
var canvas = document.getElementById('imageCanvas');
canvas.height = window.innerHeight;
canvas.width = window.innerWidth;
//Get a 2d context
var ctx = canvas.getContext('2d');
//use image to paint canvas
var _image = new Image();
_image.onload = function() {
ctx.drawImage(_image, 0, 0, 800, 436);
}
_image.src = response.imgSrc;
document.getElementById('main-canvas').appendChild(canvas);
}
This is what I used to fix my problem: High Resolution Canvas from HTML5Rocks

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