I have a button and when it is pressed it calls common_save_project(). What happens right now is the canvas is produced correctly on the screen, but the image that is created by canvas.toDataURL is black where rasterizeHTML.drawHTML was called. I am using http://cburgmer.github.io/rasterizeHTML.js/.
Here is the relevant code:
function common_save_project()
{
var image = common_screenshot();
$.ajax
(
{
type: "POST",
processData: false,
url: SITE_URL + "/system/xml/import/" + app_type + "/" + session_id + "/?prjid=" + project_id,
data: "xml=" + common_order_xml + "&prodid=" + product_id + "&file=" + image.src
}
).done(function( msg )
{
console.log("Project saved. " + msg);
});
}
function common_screenshot()
{
var canvas = document.getElementById("save_image_canvas");
var ctx = canvas.getContext('2d');
if (typeof(moulding_canvas) === "undefined")
{
canvas.height = parseInt($("#matte_canvas").height());
canvas.width = parseInt($("#matte_canvas").width());
}
else
{
canvas.height = parseInt($("#moulding_canvas").height());
canvas.width = parseInt($("#moulding_canvas").width());
}
canvas.style.backgroundColor = "#FFFFFF";
var moulding_top = 0;
var moulding_left = 0;
if (document.getElementById("moulding_canvas"))
{
moulding_top = -1 * parseInt(document.getElementById("moulding_canvas").style.top);
moulding_left = -1 * parseInt(document.getElementById("moulding_canvas").style.left);
}
var mattes_html = document.getElementById("mattes").innerHTML;
mattes_html = mattes_html.replace(/<\/?script\b.*?>/g, "");
mattes_html = mattes_html.replace(/ on\w+=".*?"/g, "");
rasterizeHTML.drawHTML(mattes_html).then(function (renderResult)
{
ctx.drawImage(renderResult.image, moulding_left, moulding_top);
});
ctx.drawImage(matte_canvas, moulding_left, moulding_top);
if (typeof(moulding_canvas) !== "undefined")
{
ctx.drawImage(moulding_canvas, 0, 0);
}
var image = new Image();
image.src = canvas.toDataURL("image/jpeg");
return image;
}
Original:
After rasterizeHTML.drawHTML:
Final result (after canvas.toDataURL):
It will work fine if you will re-declare the canvas again for saving.
Try this:
<script type="text/javascript">
var canvas = document.getElementById("canvas");
rasterizeHTML.drawHTML('<h1>hello Im here</h1>Some <span style="color: green; font-size: 20px;">HTML</span>', canvas);
$('#saveImg').click(function(){
var canvas = document.getElementById("canvas");
var dataURL = canvas.toDataURL("image/png");
window.open(dataURL, "toDataURL() image", "width=600, height=200");
});
</script>
Related
based on this question
How to use LUT with JavaScript?
I tried to use this code
http://jsfiddle.net/gxu080ve/1/
var img = new Image,
canvas = document.getElementById("myCanvas"),
ctx = canvas.getContext("2d"),
src = "http://i.imgur.com/0vcCTK9.jpg?1"; // insert image url here
img.crossOrigin = "Anonymous";
img.onload = function() {
canvas.width = img.width;
canvas.height = img.height;
ctx.drawImage( img, 0, 0 );
// alternateImage(img, canvas, ctx);
localStorage.setItem( "savedImageData", canvas.toDataURL("image/png") );
loadNew();
}
img.src = src;
// make sure the load event fires for cached images too
if ( img.complete || img.complete === undefined ) {
img.src = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==";
img.src = src;
}
var imgLut = new Image,
canvasLut = document.getElementById("myCanvasLut"),
ctxLut = canvasLut.getContext("2d"),
srcLut = "https://gm1.ggpht.com/nX2ZUYrMwPSXu5zGeeoMKyZP_R4nE205ivAdc3_yaccMEy8QYInfY_ynUB-NmrjvPKn0i1k7bdtHyk3Ul99ndvjvoCASud8FdIdq1fRrqDOCGK01rXgZZQ34ATKvtrkoysUCBmTUG70ZW_-TQxHExbu8gjhH-haIg0EuiWgJSxkL45jE1B4xWaOQNQXgJtmb7i1bSVcRgdmJq0XbttjsZnZn3YTW_LYw_3F-WyEEryTRritkZm6CW6NgaoVUfGH6XIaHp5Igs_dzm01lci9XwvoUwS0KA85w3npkjseL0zZX6u-pYWbSXOzkTLDJDMKPpOPt1VH6UUwARlD1YH1dQb0qdq4FrN8_beghJc00UaO9WHgyLyQ-NXMXFt5zXpeKuWtGwWtB0bzDhEvUXUhoDeOwaTbHlEjv3NgrqfzzpLBfLMM9J2BZLZodaEFA6WiroIsq70Qh6g_yMCVg02oi3s-L_2SSW2duayIIcfljyOxmC5AHbjzS2i-4RnKlVzK5Ge39wmiXX_4wtL0nb5XeDPwGbqqJsCPaeIYFN7z43HW6bA--5E3pUo3mjxLPTMSa8T-omZIw7w=w1896-h835-l75";
function loadNew(){
imgLut.crossOrigin = "Anonymous2";
imgLut.onload = function() {
canvasLut.width = imgLut.width;
canvasLut.height = imgLut.height;
ctxLut.drawImage( imgLut, 0, 0 );
filterImage(img, imgLut, canvasLut, ctxLut);
localStorage.setItem( "savedImageDataLut", canvasLut.toDataURL("image/png") );
}
imgLut.src = srcLutbyte;
// make sure the load event fires for cached images too
if ( imgLut.complete || imgLut.complete === undefined ) {
imgLut.src = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==";
imgLut.src = srcLutbyte;
}
}
function alternateImage(img, canvastoapply, ctxToApply){
//var c=document.getElementById("myCanvas");
//var img=document.getElementById("scream");
ctxToApply.drawImage(img,0,0);
var imgData=ctxToApply.getImageData(0,0,canvastoapply.width,canvastoapply.height);
// invert colors
for (var i=0;i<imgData.data.length;i+=4){
imgData.data[i]=255-imgData.data[i];
imgData.data[i+1]=255-imgData.data[i+1];
imgData.data[i+2]=255-imgData.data[i+2];
imgData.data[i+3]=255;
}
ctxToApply.putImageData(imgData,0,0);
};
function filterImage(img, filter, canvastoapply, ctxToApply){
//var c=document.getElementById("myCanvas");
//var img=document.getElementById("scream");
// ctxToApply.drawImage(img,0,0);
var lutWidth = canvasLut.width;
var imgData=ctx.getImageData(0,0,canvas.width,canvas.height);
var filterData=ctxToApply.getImageData(0,0,canvastoapply.width,canvastoapply.height);
// invert colors
for (var i=0;i<imgData.data.length;i+=4){
var r=Math.floor(imgData.data[i]/4);
var g=Math.floor(imgData.data[i+1]/4);
var b=Math.floor(imgData.data[i+2]/4);
var a=255;
var lutX = (b % 8) * 64 + r;
var lutY = Math.floor(b / 8) * 64 + g;
var lutIndex = (lutY * lutWidth + lutX)*4;
var Rr = filterData.data[lutIndex];
var Gg = filterData.data[lutIndex+1];
var Bb = filterData.data[lutIndex+2];
imgData.data[i] = filterData.data[lutIndex];
imgData.data[i+1] = filterData.data[lutIndex+1];
imgData.data[i+2] = filterData.data[lutIndex+2];
imgData.data[i+3] = 255;
}
ctx.putImageData(imgData,0,0);
for the attached LUT and it does not work properly because it only has 5 colums instead of 8. Of course I read the comment from How to use LUT with JavaScript? which says "This code only applies for 64x64x64 3DLUT images. The parameters vary if your LUT has other dimensions; the / 4, * 64, % 8, / 8 must be changed for other dimensions, but in this question's scope the LUT is 64x64x64."
i tried to do so and only ended in a mess.
What would I please have to change to make it work?
I am attempting to read images from a list of paths (10 items long) returned via an ajax function, resize each one and then display one after the other on the page. However, the below code only displays the first image (resized) and none of the others. I am fairly sure the resizing works as the printed sizes look correct. Below is my code in JavaScript:
// Helper function
function scaleSize(maxW, maxH, currW, currH){
var ratio = currH / currW;
if(currW >= maxW && ratio <= 1) {
currW = maxW;
currH = currW * ratio;
} else if(currH >= maxH) {
currH = maxH;
currW = currH / ratio;
}
return [currW, currH];
}
function get_similar_images(image_name) {
console.log(image_name)
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "/get_similar",
dataType: "json",
async: true,
data: JSON.stringify({name: image_name}),
success: function(data) {
console.log(data);
image_list = data['images']
category = data['category']
for (var i=0; i<image_list.length; i++) {
var img = document.createElement("img");
img.src = "static/products/"+category+"/"+image_list[i];
var actualH;
var actualW;
var newH;
var newW;
img.onload = function(){
actualW = this.width;
actualH = this.height;
console.log(actualW, actualH)
var newSize = scaleSize(300, 300, actualW, actualH);
console.log(newSize)
img.width = newSize[0];
img.height = newSize[1];
document.getElementById('imageDiv').appendChild(img)
};
}
},
error: function(xhr, status, error) {
// console.log(xhr.responseText);
}
})
}
If we simplify your for loop like that :
var img = document.createElement("img");
img.src = image_list[0];
img.onload = function() {
console.log(img);
};
var img = document.createElement("img");
img.src = image_list[1];
img.onload = function() {
console.log(img);
};
You will understand where your mistake comes from. onload is an event, which means it's running asynchronously from your your code. You're updating img value with a new image element (and a new href attribute) before the first load event is triggered. Thus the onload event is actually called after the last update of the img variable, which actually happen when your reach the last loop of your for.
Why ?
Because a for loop doesn't create a new scope for the variable img, so each time you touch the img var, even if you're putting var in front, the original img is updated.
You should then use a function, because a function actually create a new scope for variables that are declared (var myVar) inside it :
function injectAndResize(imageUrl) {
var img = document.createElement("img");
img.src = imageUrl;
var actualH;
var actualW;
var newH;
var newW;
img.onload = function() {
actualW = this.width;
actualH = this.height;
var newSize = scaleSize(300, 300, actualW, actualH);
this.width = newSize[0];
this.height = newSize[1];
document.getElementById('imageDiv').appendChild(img);
};
}
for (var i = 0; i < image_list.length; i++) {
injectAndResize(image_list[i]);
}
There are a few issues in your code.
1) Image width and height are CSS properties and may be undefined in your img.onload handler. Use this.naturalWidth instead.
2) img.src = 'url'; triggers image load. Place it after img.onload.
success: function(data) {
console.log(data);
image_list = data.images;
category = data.category;
for (var i=0; i<image_list.length; i++) {
var img = document.createElement("img");
img.onload = function(){
var actualW = this.naturalWidth;
var actualH = this.naturalHeight;
console.log(actualW, actualH)
var newSize = scaleSize(300, 300, actualW, actualH);
console.log(newSize)
this.width = newSize[0];
this.height = newSize[1];
//also think what to do with images which are already there
//probably remove
document.getElementById('imageDiv').appendChild(this)
};//img.onload
img.src = "static/products/"+category+"/"+image_list[i];
}//for
},//success
Good day,
I try to draw all tiles, on cavas using leaflet.js as provider.
But, as it used translate3d transform
1 level - map Pane
2 level - overlay Pane(I also lokking for solution about SVG Pane. I use canVG to convert svg to canvas, but don't understand how to create canvas correctly)
How to draw tiles on canvas?
For example
1 level - transform: translate3d(-247px, 184px, 0px);
This is part of code:
var svgE = $(overlayPane).find('svg');
var xml;
var mapPane = $(".leaflet-map-pane")[0];
var mapTransform = mapPane.style.transform.split(",");
var mapX = parseFloat(mapTransform[0].split("(")[1].replace("px", ""));
var mapY = parseFloat(mapTransform[1].replace("px", ""));
var canvas = document.createElement("canvas");
canvas.className = "screenShotTempCanvas";
canvas.width = map.getSize().x;
canvas.height = map.getSize().y;
var ctx = canvas.getContext('2d');
$(canvas).insertBefore($(".leaflet-zoom-animated"));
if ($("img.leaflet-tile").length !== 0) {
var myTiles = $("img.leaflet-tile");
var tilesLeft = [];
var tilesTop = [];
var tileMethod = [];
for (var i = 0; i < myTiles.length; i++) {
if (myTiles[i].style.left != "") {
tilesLeft.push(parseFloat(myTiles[i].style.left.replace("px", "")));
tilesTop.push(parseFloat(myTiles[i].style.top.replace("px", "")));
tileMethod[i] = "left";
} else if (myTiles[i].style.transform != "") {
var tileTransform = myTiles[i].style.transform.split(",");
tilesLeft[i] = parseFloat(tileTransform[0].split("(")[1].replace("px", ""));
tilesTop[i] = parseFloat(tileTransform[1].replace("px", ""));
myTiles[i].style.transform = "";
tileMethod[i] = "transform";
} else {
tilesLeft[i] = 0;
tilesRight[i] = 0;
tileMethod[i] = "neither";
};
myTiles[i].setAttribute('crossOrigin', 'anonymous');
myTiles[i].style.left = (tilesLeft[i]) + "px";
myTiles[i].style.top = (tilesTop[i]) + "px";
ctx.drawImage(myTiles[i], tilesLeft[i], tilesTop[i])
};
}
setTimeout(function() {
var myImage = canvas.toDataURL("image/jpeg");
var link = document.createElement('a');
link.download = "test.jpeg";
link.href = myImage;
document.body.appendChild(link);
$(link).css("display", "none");
link.click();
document.body.removeChild(link);
console.log(sdfsdfgsdfg)
}, 10000)
Second question how to correctly create canvas for SVG?
if ($(map.getContainer()).find('svg').length !== undefined && $(map.getContainer()).find('svg').length !== 0) {
svgE.each(function() {
L.DomUtil.getPosition(svgE);
xml = new XMLSerializer().serializeToString(this);
canvg(canvas, xml);
$(canvas).insertBefore(this);
$(this).attr('class', 'tempHide').attr("id", "TempSvgToHide").hide();
});
}
#cap is a div i want to capture.
I used ctx.drawImage($('#cap').get(0),0,0,640,480);window.open(canvas.getDataURL('image/jpeg'));
got a Type error
and how do i send it to php to save as a.jpeg
UPDATE
http://jsfiddle.net/3qNJB/ is not working help html2canvas is not a function
< DIV > elements cannot be drawn on canvas using drawImage() method.Have a look at Html2Canvas library
Example:
html2canvas(document.getElementById('DivToCapture'), {
onrendered: function(canvas) {
// document.body.appendChild(canvas);
window.open(canvas.toDataURL('image/jpeg'));
}
});
Heres the Fiddle
Instead of opening the image with javascript, just POST it to your server so PHP can receive it, save it on the server, and then send it back to the browser.
I found this DivsToJPG() function here: Convert html div having multiple images to single image using javascript
var DivsToJPG = function( parent ) {
this.canvasSizeX = 0;
this.canvasSizeY = 0;
this.init = function( parent ) {
this.images = parent.find('img');
this.setSizes();
this.createCanvas();
this.drawImages();
this.exportJPG();
}
this.setSizes = function() {
for (var i = 0, l = this.images.length; i < l ; i++) {
var currentImage = this.images.eq(i);
var posX = currentImage.position().left;
var width = currentImage.width();
this.canvasSizeX = this.canvasSizeX > (posX+width) ? this.canvasSizeX : posX + width;
//console.log(this.canvasSizeX);
var posY = currentImage.position().top;
var height = currentImage.height();
this.canvasSizeY = this.canvasSizeY > (posY+height) ? this.canvasSizeY : posY + height;
}
}
this.createCanvas = function() {
this.canvas = document.createElement('canvas');
this.canvas.id = "exportCanvas";
this.canvas.width = this.canvasSizeX;
this.canvas.height = this.canvasSizeY;
this.ctx = this.canvas.getContext("2d");
document.body.appendChild(this.canvas);
}
this.drawImages = function() {
for (var i = 0, l = this.images.length; i < l ; i++) {
var currentImage = this.images[i];
var $currentImage = this.images.eq(i);
this.ctx.drawImage(currentImage, $currentImage.position().left, $currentImage.position().top, $currentImage.width(), $currentImage.height());
}
}
this.exportJPG = function() {
var dataURL = this.canvas.toDataURL();
this.img = document.createElement('img');
this.img.id = "createdImage";
this.img.src = dataURL;
document.body.appendChild(this.img);
}
this.init( parent );
}
var divsToJPG = new DivsToJPG($('#cap'));
$.ajax({
type : "POST",
url : "make-image.php",
data : {
imgBase64 : divsToJPG
}
}).done(function(data) {
});
Then in PHP
$img = base64_decode($_POST['imgBase64']);
I have searched a few results regarding this issue but none of them works for me, so I am posting here to get some helps. Basically my issue is when I clicked on the generate button, I want the image from canvas to be displayed in a img element. However, the image will show up in chrome but not firefox! Below is my coding...
<body onload="onLoad();">
<canvas id="aimage">Your browser does not support the canvas tag.</canvas>
<input type="button" value="Generate" onclick="genImage();" />
<img id="cImg" name="cImg" src="${param.src}" />
...
</body>
And the javascript...
var tcanvas;
var scanvas;
var tcontext;
var imageURL;
function onLoad() {
tcanvas = document.getElementById("aimage");
tcontext = tcanvas.getContext("2d");
scanvas = document.getElementById("cImg");
imageURL = "${param.src}";
update();
}
function update() {
var image = new Image();
image.onload = function () {
if (image.width != tcanvas.width)
tcanvas.width = image.width;
if (image.height != tcanvas.height)
tcanvas.height = image.height;
tcontext.clearRect(0, 0, tcanvas.width, tcanvas.height);
tcontext.drawImage(image, 0, 0, tcanvas.width, tcanvas.height);
}
image.crossOrigin = 'anon';
image.src = imageURL;
}
function genImage() {
var url = tcanvas.toDataURL("image/jpeg");
scanvas.crossOrigin = 'anon';
scanvas.src = url;
if(scanvas.width > 1000){
scanvas.width = 1000;
}
if(scanvas.height > 1000){
scanvas.height = 1000;
}
}
try this:
var scanvas, tcontext, tcanvas;
function genImage() {
var url = tcanvas.toDataURL("image/jpeg");
scanvas.src = url;
if (scanvas.width > 1000) {
scanvas.width = 1000;
}
if (scanvas.height > 1000) {
scanvas.height = 1000;
}
}
window.onload = function () {
tcanvas = document.getElementById("aimage");
tcontext = tcanvas.getContext("2d");
scanvas = document.getElementById('cImg');
var img = new Image();
img.onload = function () {
tcontext.drawImage(img, 0, 0, img.width, img.height)
};
img.src = "yourImage.jpg";
}