I am trying to capture a div with canvas inside. it is a tshirt editor. now i am capturing this div with html2canvas and then printing it in pdf using jspdf. Now the problem is that the captured image is of very low quality and blurry. its dpi are very low.
This is the original div picture:
and this is the printed version of that div:
You can see the quality difference between them is huge.
Anyway here is the code of capturing the div and then converting it into pdf
var myimage;
function print() {
window.scrollTo(0, 0);
html2canvas(document.getElementById('shirtDiv')).then(function(canvas) {
myimage = canvas.toDataURL("image/jpeg");
setTimeout(print2, 1);
var doc = new jsPDF();
doc.addImage(myimage, 'JPEG', 35, 20, 130, 155);
doc.save('Test.pdf');
});
}
<div id="shirtDiv" class="page" style="width: 530px; height: 630px; position: relative; background-color: rgb(255, 255, 255); " >
<img name="tshirtview" id="tshirtFacing" src="img/crew_front.png">
<div id="drawingArea" style="position: absolute;top: 100px;left: 160px;z-index: 10;width: 200px;height: 400px;">
</div></div>
Please ignore the on-line CSS
Ok i did it because of the similar question asked by someone else in this link but the answer wasn't marked correct because he didn't explained it right maybe. Anyway here is the solution.
var myimage;
function print() {
window.scrollTo(0, 0);
html2canvas(document.getElementById('shirtDiv')[0],{scale:4}).then(function(canvas) {
myimage = canvas.toDataURL("image/jpeg");
var doc = new jsPDF();
doc.addImage(myimage, 'JPEG', 35, 20, 130, 155);
doc.save('Test.pdf');
});
}
The scale property was mentioned everywhere but i was having trouble to apply it. yes i know i am stupid but maybe someone else is like me and this might help them :)
UPDATE VERSION
This HTML2CANVAS solution was still not working good for me because the scale option does increase the target div's size before capturing it but it won't work if you have something inside that div which won't resize e.g in my case it was canvas for my editing tool. Anyway for this i opted for domtoimage and trust me i think that this is the best solution of them all. I didn't had to face any problem of html2canvas for example: need to be at the top of webpage so html2canvas can capture the shot completely and Low dpi problem
Anyway sorry for the story but i thought everyone should know and here is the code
function print() {
var node = document.getElementById('shirtDiv');
var options = {
quality: 0.95
};
domtoimage.toJpeg(node, options).then(function (dataUrl) {
var doc = new jsPDF();
doc.addImage(dataUrl, 'JPEG', -18, 20, 240, 134.12);
doc.save('Test.pdf');
});
}
Cdn for dom to image: https://cdnjs.com/libraries/dom-to-image
Cdn for jspdf: https://cdnjs.com/libraries/jspdf
Related
I am adding an image to my PDF document using the jsPDF library:
loadImageFromURL(URL, function (image) {
document.circle(20, 20, 10, 'S');
document.addImage(image, 'JPEG', 20, 20);
});
function loadImageFromURL(URL, callback) {
var image = new Image();
image.src = URL;
image.onload = function () {
callback(image);
};
}
The problem is that I want to fit the image in the circle that I create before adding the image. How can I transform my image to crop into a circle and fit it in my previous circle?
I have tried to:
image.style.borderRadius = "50%";
But this didn't take any effect. How can I crop my image into a circle?
EDIT:
After some research I have found out that jsPDF doesn't accept styles. I have also found that jsPDF has a "clip" function, but I am not sure how to use it. Could I somehow add my image and then clip it with a circle?
I have a hack to get a rounded image in jspdf library by simply using an image and circle.
//First I Created Background from Rectangle with some color
doc.setFillColor(94,101,121);
doc.setDrawColor(94,101,121);
doc.rect(0, 0,width, 115, 'FD');
//Secondly I take a picture in square format
doc.addImage(img, 'JPEG', 84, 9, 52, 52,3,3);
doc.setLineWidth(0);
doc.setDrawColor(0)
doc.setFillColor(255, 255, 255)
//Third,I Created a circle and increased the line width until
it covers all the corners of image in circuralar format
doc.setLineWidth(15)
doc.setDrawColor(94,101,121);
doc.setFillColor(255, 0, 0)
doc.circle(110, 35, 33, 'Fd')
First , Try this code in https://parall.ax/products/jspdf then implement the idea according to your need.
I m creating a PDF file in nodejs using PDFkit, that contains a background image and an profile image of user. I tried looking through the documentation of pdfkit, but could not find any parameter to make another image float over the previous one.
Is there any solution present to make that happen or do I need to switch to other packages?
Any help would be appreciated.
//Background Image
doc.image(__dirname+'../../../resources/images/' + 'background.jpg',
{
height:400,
width:600,
margin: 0,
padding:0
});
//Image to be floated
doc.image(body,
{
height:200,
width:200,
margin: 0,
padding:0,
absolutePosition: {x: 50, y: 100}
}).moveTo(100, 150);
I expect a image over background but pdfkit is making new image to be pushed down the orignal image.
Can see this was asked a long time ago, but it is definitely doable today. Try this example.
let defaultImageOptions = {
width: 200,
height: 300,
};
// Add background image
doc.image("bg_image.png", 0, 0, defaultImageOptions);
doc.image("front_image.png", 0, 0, defaultImageOptions);
I'm working on my first HTML5 Canvas game. I am trying to put in a background image, and I don't know how to do it. The game will change backgrounds throughout levels, but I think I understand how to make that happen. However, if I just try to draw an image, then it appears above my title text. Any ideas how to fix this? I don't think the CSS method will work, because the background will change. Here is my code:
<!DOCTYPE html>
<html>
<head>
<title>How Well Do You Know Your Swedish?</title>
</head>
<body>
<canvas width="640" height="480" id="game" style="display: block; margin-left: auto; margin-right: auto; border: 1px solid black;" Your Browser is not compatible with this game. We recommend Google Chrome, Mozilla Firefox, or Opera.></canvas>
<script>
var game_canvas = document.getElementById("game");
var game_context = game_canvas.getContext("2d");
var swedishflagbg = new Image();
swedishflagbg.src = "resources/images/swedishflagbg.png";
swedishflagbg.onload = function() {
game_context.drawImage(swedishflagbg, 0, 0);
}
game_context.fillStyle = "#000000";
game_context.font = "35px Ubuntu";
game_context.textAlign = "center";
game_context.textBaseline = "top";
game_context.fillText("How Well Do You Know Your Swedish?", 320, 0);
</script>
</body>
</html>
I am new to JavaScript, and even newer to the HTML5 Canvas.
Extending from comment:
The "why":
Because the background image is drawn in an onload event, which will happen "later", while text is drawn immediately.
So the text is drawn first, and then sometimes later the image is drawn, thus causing the text to be covered.
The "how":
Depending on how "dynamic" the background image is, you can consider:
use CSS background-image on cancas/canvas container, and use className/classList to switch between different backgrounds;
put an <img> tag underneath the canvas, and change its src property;
use an additional "background" canvas underneath the current one, so you can draw the game content in current one, and draw the (probably not frequently-updated) background in the new one.
Credit of idea 1 and 2 goes to #markE :)
First things:
Check the size of your image. It should be equivalent to the size of the canvas.
context.drawImage can also take width and height parameter for the image.
Syntax: context.drawImage(img, x, y, width, height);
After editing, it should look like this
let game_canvas = document.getElementById("game");
let game_context = game_canvas.getContext("2d");
let swedishflagbg = new Image();
swedishflagbg.src = "resources/images/swedishflagbg.png";
swedishflagbg.onload = function() {
game_context.drawImage(swedishflagbg, 0, 0, game_canvas.width, game_canvas.height);
}
game_context.fillStyle="#000000";
game_context.font="35px Ubuntu";
game_context.textAlign="center";
game_context.textBaseline="top";
game_context.fillText("How Well Do You Know Your Swedish?", 320, 0);
To anyone who is still facing the problem of background image overlaying text (Image above text), I thought "why not drawing text inside onload function after loading bg image!?"
And it worked!! The browser (Or whatever) loads image first and load my text above image.
<canvas width="534" height="104" id="game" style="display: block; margin-left: auto; margin-right: auto; border: 1px solid black;" Your Browser is not compatible with this game. We recommend Google Chrome, Mozilla Firefox, or Opera.></canvas>
<script>
let game_canvas = document.getElementById("game");
let game_context = game_canvas.getContext("2d");
let swedishflagbg = new Image();
swedishflagbg.src = "./img/logo1.png";
swedishflagbg.onload = function() {
game_context.drawImage(swedishflagbg, 0, 0, game_canvas.width, game_canvas.height);
game_context.fillStyle = "#000000";
game_context.font = "35px Ubuntu";
game_context.textAlign = "center";
game_context.textBaseline = "top";
game_context.fillText("How Well Do You Know Your Swedish?", 320, 0);
}
</script>
I have a canvas where the user can create a design using images in another div that they click, sending it to the Fabric.js canvas where it gets moved around and so on. Since the canvas's size is width="270"and height="519", smaller than what the finished product is, I need to recreate it with a canvas that has the size width="1001"and height="1920" and then screenshot it so that I get it all in 1 single image. How do I do this?
This is what my code looks like so far:
HTML
<div id="CanvasContainer">
<canvas id="Canvas" width="270" height="519"></canvas>
</div>
CSS
#CanvasContainer {
width: 270px;
height: 519px;
margin-left: 15px;
}
#Canvas {
overflow: hidden;
}
JAVASCRIPT
//Defining Canvas and object array
var canvas = new fabric.Canvas('Canvas');
//When clicked
$(document).ready(function () {
$("#Backgrounds img").click(function () {
var getId = $(this).attr("id");
//adding all clicked images
var imgElement = document.getElementById(getId);
var imgInstance = new fabric.Image(imgElement, {
left: 135,
top: 259,
width: 270,
height: 519
});
//Corner color for clicked images
imgInstance.set({
borderColor: 'white',
cornerColor: 'black',
transparentCorners: false,
cornerSize: 12
});
canvas.add(imgInstance);
});
});
Fabric has a built in function to convert to data urls. You can use the download property of a link to make the link a download link. Finally you can use the DOM click() function to emulate clicking the download link. The end result is:
function download(url,name){
// make the link. set the href and download. emulate dom click
$('<a>').attr({href:url,download:name})[0].click();
}
function downloadFabric(canvas,name){
// convert the canvas to a data url and download it.
download(canvas.toDataURL(),name+'.png');
}
now when you want to download the canvas call
downloadFabric(canvas,'<file name>');
I am trying to use JCrop to crop an image. However the results are frustratingly wrong and I am not sure why. I have an image uploader that when someone selects in image a javascript changes the source of an image already on the page to match the newly upload image. I then have this code:
$('#myForm').ajaxForm({
dataType: 'json',
success: function (result) {
$("#image-editor-preview img")
.attr("src", "/Profiles/AvatarWorker/" + _id + "?random=" + Math.random())
.Jcrop({
aspectRatio: 1,
setSelect: [100, 100, 50, 50],
minSize: [160, 160],
maxSize: [160, 160],
onChange: setCoords,
onSelect: setCoords
});
}
});
var x = 0, y = 0, w = 0, h = 0;
function setCoords(c) {
x = c.x;
y = c.y;
w = c.w;
h = c.h;
};
However this is what happens:
I have tried tried quite a bit to fix this but the end results are ALWAYS the same. Anyone have any ideas? Thanks.
I had the same problem, but I found, why it happens so.
In my css file I had this code:
img {
width: 100%;
height: auto;
border: none;
}
When I removed width and height from this definition, plugin started working correctly.
I was able to figure it out. Turns out that JCrop inside a twitter bootstrap modal has an issue with the width of the JCrop box. The twitter bootstrap modal is overriding the CSS inside the JCrop css. Had to modify the CSS in JCrop to not have this happen.
According to the Jcrop docs, it does not actually do the cropping. It only creates a image cropping UI. It then depends on the server doing the actual cropping; see http://deepliquid.com/content/Jcrop_Implementation_Theory.html . So it looks like the plugin is doing exactly what it is designed to do. It's now leaving the rest for you to do yourself on the server, as they show.