I have created a chrome extention to take full page screen shot. It is working fine while openening Image element in new window. But I need to display image in Canvas element to allow editing in canvas.
Here is the code for event listener of chrome.tabs.CaptureTab :
background.js
chrome.runtime.onMessage.addListener(
function(request,sender,sendResponse) {
if(Array.isArray(request.image)) {
var canvas = document.createElement('canvas'),
context = canvas.getContext('2d'),
image,
done = 0;
canvas.width = request.width;
canvas.height = request.height;
for(var i = 0; i < request.image.length; i++) {
(function(i) {
image = new Image();
image.onload = function() {
context.drawImage(this, 0, request.image[i].position, this.width, this.height);
if(++done == request.image.length) {
screenshot = canvas.toDataURL('image/png');
var htmlCode = "<html><body> Image here: <p><img border=\"2\" src=" + screenshot +"><p> End Image </body></html>";
var url = "data:text/html," + encodeURIComponent(htmlCode);
chrome.tabs.create({url: url});
}
}
image.src = request.image[i].image;
})(i);
}
} else {
var htmlCode = "<html><body> Image here: <p><img border=\"2\" src=" + request.image +"><p> End Image </body></html>";
var url = "data:text/html," + encodeURIComponent(htmlCode);
chrome.tabs.create({url: url});
return;
}
});
Now, I tried :
var htmlCode = "<html><body> Image here: <p><img border=\"2\" src=" + screenshot +"><p> End Image <hr> " + canvas + " </body></html>";
It Gives : [object HTMLCanvasELement]
I need to embed this canvas element while creating the chrome tab
So I solved the same using :
chrome.tabs.create({url:chrome.extension.getURL("../capturetab.html?tabImage=" + request.source )});
capturetab.html :
<html>
<head>
<script type="text/javascript" src="Scripts/jquery-2.1.1.min.js"></script>
<script type="text/javascript" src="Scripts/visibletab.js"></script>
</head>
<body>
<br/><br/>
<canvas id="canvas"></canvas>
<br/><br/>
</body>
</html>
visibketab.js
$( document ).ready(function() {
var imageblob = getUrlParameter('tabImage');
//Set canvas attribute
var myCanvas = document.getElementById('canvas');
var ctx = myCanvas.getContext('2d');
var img = new Image;
img.onload = function(){
// set width and height
ctx.canvas.height = this.height;
ctx.canvas.width = this.width;
ctx.drawImage(img,0,0); // Or at whatever offset you like
};
img.src = imageblob;
});
function getUrlParameter(sParam)
{
var sPageURL = window.location.search.substring(1);
var sURLVariables = sPageURL.split('&');
for (var i = 0; i < sURLVariables.length; i++)
{
var sParameterName = sURLVariables[i].split('=');
if (sParameterName[0] == sParam)
{
return sParameterName[1];
}
}
}
Related
I am currently working on a Javascript project and I am struggling with exporting the entire SVG image on the canvas. So far I've been only able to export the visible part of the canvas, with out the "hidden" parts.
How do I capture the full canvas content?
Is there a way to do it without messing around with the original canvas size?
I am using D3.js V3
Screenshot of my project
Here's my code:
var svgString;
window.onload = function(){
setTimeout(function() {
exportSVG = document.getElementById("canvas");
document.getElementById("canvas").style.fontFamily= "lato";
document.getElementById("canvas").style.width= exportSVG.getBBox().width * 1;
document.getElementById("canvas").style.height= exportSVG.getBBox().height * 1;
svgString = getSVGString(exportSVG);
console.log(exportSVG.getBBox().width + " / " + exportSVG.getBBox().height);
svgString2Image(svgString, exportSVG.getBBox().width, exportSVG.getBBox().height, 'png', save); // passes Blob and filesize String to the callback
console.log("svg export code loaded");
// console.log(svgString.getBBox().width); document.getElementById("canvas").getBBox().width
}, 5000);
};
function save(dataBlob, filesize) {
saveAs(dataBlob, 'D3 vis exported to PNG.png'); // FileSaver.js function
}
// Below are the functions that handle actual exporting:
// getSVGString ( svgNode ) and svgString2Image( svgString, width, height, format, callback )
function getSVGString(svgNode) {
svgNode.setAttribute('xlink', 'http://www.w3.org/1999/xlink');
var cssStyleText = getCSSStyles(svgNode);
appendCSS(cssStyleText, svgNode);
var serializer = new XMLSerializer();
var svgString = serializer.serializeToString(svgNode);
svgString = svgString.replace(/(\w+)?:?xlink=/g, 'xmlns:xlink='); // Fix root xlink without namespace
svgString = svgString.replace(/NS\d+:href/g, 'xlink:href'); // Safari NS namespace fix
return svgString;
function getCSSStyles(parentElement) {
var selectorTextArr = [];
// Add Parent element Id and Classes to the list
selectorTextArr.push('#' + parentElement.id);
for (var c = 0; c < parentElement.classList.length; c++)
if (!contains('.' + parentElement.classList[c], selectorTextArr))
selectorTextArr.push('.' + parentElement.classList[c]);
// Add Children element Ids and Classes to the list
var nodes = parentElement.getElementsByTagName("*");
for (var i = 0; i < nodes.length; i++) {
var id = nodes[i].id;
if (!contains('#' + id, selectorTextArr))
selectorTextArr.push('#' + id);
var classes = nodes[i].classList;
for (var c = 0; c < classes.length; c++)
if (!contains('.' + classes[c], selectorTextArr))
selectorTextArr.push('.' + classes[c]);
}
// Extract CSS Rules
var extractedCSSText = "";
for (var i = 0; i < document.styleSheets.length; i++) {
var s = document.styleSheets[i];
try {
if (!s.cssRules) continue;
} catch (e) {
if (e.name !== 'SecurityError') throw e; // for Firefox
continue;
}
var cssRules = s.cssRules;
for (var r = 0; r < cssRules.length; r++) {
if (contains(cssRules[r].selectorText, selectorTextArr))
extractedCSSText += cssRules[r].cssText;
}
}
return extractedCSSText;
function contains(str, arr) {
return arr.indexOf(str) === -1 ? false : true;
}
}
function appendCSS(cssText, element) {
var styleElement = document.createElement("style");
styleElement.setAttribute("type", "text/css");
styleElement.innerHTML = cssText;
var refNode = element.hasChildNodes() ? element.children[0] : null;
element.insertBefore(styleElement, refNode);
}
}
function svgString2Image(svgString, width, height, format, callback) {
var format = format ? format : 'png';
var imgsrc = 'data:image/svg+xml;base64,' + btoa(unescape(encodeURIComponent(svgString))); // Convert SVG string to data URL
var canvas = document.createElement("canvas");
var context = canvas.getContext("2d");
canvas.width = width;
canvas.height = height;
var image = new Image();
image.onload = function() {
context.clearRect(0, 0, width, height);
context.drawImage(image, 0, 0, width, height);
canvas.toBlob(function(blob) {
var filesize = Math.round(blob.length / 1024) + ' KB';
if (callback) callback(blob, filesize);
});
};
image.src = imgsrc;
}
Simply change your <svg> viewBox attribute before you serialize it to a string so that it displays everything:
var svg = document.querySelector('svg');
var toExport = svg.cloneNode(true); // avoids having to reset everything afterward
// grab its inner content BoundingBox
var bb = svg.getBBox();
// update its viewBox so it displays all its inner content
toExport.setAttribute('viewBox', bb.x + ' ' + bb.y + ' ' + bb.width + ' ' + bb.height);
toExport.setAttribute('width', bb.width);
toExport.setAttribute('height', bb.height);
var svgAsStr = new XMLSerializer().serializeToString(toExport);
var blob = new Blob([svgAsStr], {type: 'image/svg+xml'});
var img = new Image();
img.onload = drawToCanvas;
img.src = URL.createObjectURL(blob);
function drawToCanvas(evt) {
var canvas = document.createElement('canvas');
canvas.width = this.width;
canvas.height = this.height;
canvas.getContext('2d').drawImage(this, 0,0);
document.body.appendChild(canvas);
}
svg{border: 1px solid blue}
canvas{border: 1px solid green}
<svg width="50" height="50" viewBox="0 0 50 50">
<rect x="0" y="0" width="200" height="50" fill="#CCC"/>
</svg>
I am trying to export my chart data consisting of image and data in a PDF. It works fine for me in laptop browser, but while I am trying to do the same in Ipad, the img.onload() function is not firing. I am not sure but I feel like it is due to the size of the image that is rendering in it. Can anybody help me with it? Can we change the pixels of the image that is being rendered?
The code is given below:-
function exportData(exportType) {
if (exportType) {
if (exportType == "pdf") {
alert("clicked pdf")
console.log("pdf export ....")
vm.toggleCanvas = !vm.toggleCanvas;
var canvas = "";
var ctxt = "";
// var img = "";
var sheets = "";
var svgURL = "";
canvas = document.getElementById('canvas');
$log.log($window.screen.width)
//resizing image for PDF
if ($window.screen.width >= 1500) {
canvas.width = $window.screen.width - 150;
} else {
canvas.width = $window.screen.width;
}
console.log("before canvas")
ctxt = canvas.getContext('2d');
sheets = document.styleSheets;
svgURL = generateSVGWithStyling('svg');
// var img = document.createElement('img');
var img = new Image();
console.log("after image")
console.log(img)
alert("imb")
img.src = 'data:image/svg+xml; charset=utf8, ' + encodeURIComponent(svgURL);
img.onload = function () {
debugger
console.log("in load")
alert("in load")
ctxt.drawImage(this, 0, 0);
vm.cnvasImg = "";
vm.cnvasImg = canvas.toDataURL();
var content = "";
console.log("on load")
subExportData(vm.cnvasImg, exportType);
}
console.log(img.src)
} else {
vm.cnvasImg = "nothing";
subExportData(vm.cnvasImg, exportType);
}
}
}
Any help would be apprciated.
Can you please try with passing the width, height properties to Image constructor Object.
var img = new Image(Width, Height);
I want to be able to click on a button on my page and load an image into a canvas at some X,Y coordinates?
The following code is what I have below. I would like the image to be in either image/photo.jpg or in the same directory but preferably in a subdirectory of the main page.
**Question: How to make a JPG show up in a canvas with the click of a button on the web page?
Code:
<!DOCTYPE html>
<html>
<script>
function draw(){
var ctx = document.getElementById("myCanvas").getContext("2d");
var img = new Image():
// img.src = "2c.jpg";
img.src = "/images/2c.jpg";
ctx.drawImage(img,0,0);
}
</script>
<body background="Black">
<div align="center">
<button type="button" onclick="draw()">Show Image on Canvas</button>
<canvas id="myCanvas" width="900" height="400" style="border:2px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.
</canvas>
</div>
<script>
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
ctx.font="20px Arial";
ctx.fillText("Royal Flush $",500,50);
ctx.fillText("Striaght Flush $",500,80);
ctx.fillText("Flush $",500,110);
ctx.fillText("Four of a Kind $",500,140);
ctx.fillText("Full House $",500,170);
ctx.fillText("Three of a Kind $",500,200);
ctx.fillText("Two Pair $",500,230);
ctx.fillText("Pair of ACES $",500,260);
ctx.rect(495,10,270,350);
ctx.stroke();
</script>
</body>
</html>
March 6th, 2014 Code:
How is the following code not working. Do you have to have an ID tag on Canvas. The page will display but for some reason the image will not when the button is clicked. The image is in the same directory that my index.html file is in.
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<style type="text/css">
canvas{
border: 5px solid black;
}
</style>
</html>
<button id="galaxy">Add image #1</button>
<button id="circles">Add image #2</button><span></span>
<canvas width="500" height="500"></canvas>
<script>
var Images = {};
function loadImages(list){
var total = 0;
document.querySelector("span").innerText = "...Loading...";
for(var i = 0; i < list.length; i++){
var img = new Image();
Images[list[i].name] = img;
img.onload = function(){
total++;
if(total == list.length){
document.querySelector("span").innerText = "...Loaded.";
}
};
img.src = list[i].url;
}
}
function drawImage(img){
var ctx = document.querySelector("canvas").getContext("2d");
ctx.drawImage(Images[img], 0, 0, 50, 50);
}
loadImages([{
name: "2c.jpg",
url: "mp.jpg"
},{
name: "mp.jpg",
url: "mp.jpg"
}]);
document.querySelector("#galaxy").addEventListener("click", function(){
drawImage("galaxy");
});
document.querySelector("#circles").addEventListener("click", function(){
drawImage("weirdCircles");
});
</script>
</html>
Wait till the image is loaded before drawing:
var img = new Image();
img.onload = function(){ /*or*/ img.addEventListener("load", function(){
ctx.drawImage(img,0,0); ctx.drawImage(img,0,0);
}; };
img.src = "/images/2c.jpg";
Demo: http://jsfiddle.net/DerekL/YcLgw/
If you have more than one image in your game,
It is better to preload all images before it starts.
Preload images: http://jsfiddle.net/DerekL/uCQAH/ (Without jQuery: http://jsfiddle.net/DerekL/Lr9Gb/)
If you are more familiar with OOP: http://jsfiddle.net/DerekL/2F2gu/
function ImageCollection(list, callback){
var total = 0, images = {}; //private :)
for(var i = 0; i < list.length; i++){
var img = new Image();
images[list[i].name] = img;
img.onload = function(){
total++;
if(total == list.length){
callback && callback();
}
};
img.src = list[i].url;
}
this.get = function(name){
return images[name] || (function(){throw "Not exist"})();
};
}
//Create an ImageCollection to load and store my images
var images = new ImageCollection([{
name: "MyImage", url: "//example.com/example.jpg"
}]);
//To pick and draw an image from the collection:
var ctx = document.querySelector("canvas").getContext("2d");
ctx.drawImage(images.get("MyImage"), 0, 0);
Well, I have this code:
http://jsfiddle.net/hv9gB/3/
(function() {
var img = document.getElementById('my_image');
// Original
var width, height;
// Display
var d_width = img.width;
var d_height = img.height;
var updateDetail = function() {
document
.getElementById('display_size')
.innerHTML = 'Display Size: ' + d_width + ' x ' + d_height;
document
.getElementById('native_size')
.innerHTML = 'Original Size: ' + width + ' x ' + height;
};
// Using naturalWidth/Height
if (img.naturalWidth) {
width = img.naturalWidth;
height = img.naturalHeight;
updateDetail();
} else {
// Using an Image Object
img = new Image();
img.onload = function() {
width = this.width;
height = this.height;
updateDetail();
};
img.src = 'http://lorempixel.com/output/nature-q-c-640-480-3.jpg';
}
}());
And that is my site:
http://dhems.x10.mx/
But on my site isn't working show the width and height of image
Why?!?!
Put your code in
window.onload = function() {
//insert code here
}
Your js file is executed before the engine reach the picture..You're getting the following console error:
Uncaught TypeError: Cannot read property 'width' of null
It's also a good practice to put all scripts files in the end of the page and all css files in the begin. It will increase the loading time of your page, because if JS files are in the begin, your browser won't start to render until these files are downloaded.
your code should look like:
window.onload = function() {
var img = document.getElementById('my_image');
// Original
var width, height;
// Display
var d_width = img.width;
var d_height = img.height;
var updateDetail = function() {
document
.getElementById('display_size')
.innerHTML = 'Display Size: ' + d_width + ' x ' + d_height;
document
.getElementById('native_size')
.innerHTML = 'Original Size: ' + width + ' x ' + height;
};
// Using naturalWidth/Height
if (img.naturalWidth) {
width = img.naturalWidth;
height = img.naturalHeight;
updateDetail();
} else {
// Using an Image Object
img = new Image();
img.onload = function() {
width = this.width;
height = this.height;
updateDetail();
};
img.src = 'http://lorempixel.com/output/nature-q-c-640-480-3.jpg';
}
}
Move the script tag after the image in HTML. Script gets executed before the image goes into page.
Put the code at the bottom of your <body> in a <script type='text/javascript'> or use window.onload. If you have other things loading onload the first option is your best choice, otherwise use this code:
<script type='text/javascript'>
(function(){
var pre = window.onload;
onload = function(){
if(pre)pre();
//other code here
}
})();
</script>
This example can be used in your <head>.
<!DOCTYPE html>
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/2.0.2/jquery.min.js"></script>
<script>
function readImage(file) {
var reader = new FileReader();
var image = new Image();
reader.readAsDataURL(file);
reader.onload = function(_file) {
image.src = _file.target.result; // url.createObjectURL(file);
image.onload = function() {
var w = this.width,
h = this.height,
t = file.type, // ext only: // file.type.split('/')[1],
n = file.name,
s = ~~(file.size/1024) +'KB';
$('#uploadPreview').append('<img src="'+ this.src +'"> '+w+'x'+h+' '+s+' '+t+' '+n+'<br>');
};
image.onerror= function() {
alert('Invalid file type: '+ file.type);
};
};
}
$("#choose").change(function (e) {
if(this.disabled) return alert('File upload not supported!');
var F = this.files;
if(F && F[0]) for(var i=0; i<F.length; i++) readImage( F[i] );
});
</script>
<meta charset=utf-8 />
<title>Multiple image upload with preview by Roko C.B.</title>
</head>
<body>
<input type="file" id="choose" multiple="multiple" />
<br>
<div id="uploadPreview"></div>
</body>
</html>
I have written a javascript that is supposed to scroll pictures across the screen using canvas. I am unable to get this to work and would appreciate any help. I was able to get this to work using one picture and no Array but I want to be able to use an Array and load pictures one after another with a small space between them.
Here's a JSFiddle with my code.
var img = new Image[];
img[0] = new Image;
img[0].src = 'Images/Juniors.jpg';
img[1] = new Image;
img[1].src = 'Images/minis.jpg';
img[2] = new Image;
img[2].src = 'Images/senior.jpg';
var CanvasXSize = 1040;
var CanvasYSize = 240;
var speed = 40; //lower is faster
var scale = 1.05;
var y = -4.5; //vertical offset
var dx = 0.75;
var imgW;
var imgH;
var x = 0;
var clearX;
var clearY;
var ctx;
img.onload = function() {
imgW = img.width*scale;
imgH = img.height*scale;
if (imgW > CanvasXSize) { x = CanvasXSize-imgW; } // image larger than canvas
if (imgW > CanvasXSize) { clearX = imgW; } // image larger than canvas
else { clearX = CanvasXSize; }
if (imgH > CanvasYSize) { clearY = imgH; } // image larger than canvas
else { clearY = CanvasYSize; }
ctx = document.getElementById('canvas').getContext('2d'); //Get Canvas Element
}
function draw() {
//Clear Canvas
ctx.clearRect(0,0,clearX,clearY);
//If image is <= Canvas Size
if (imgW <= CanvasXSize) {
//reset, start from beginning
if (x > (CanvasXSize)) { x = 0; }
//draw aditional image
if (x > (CanvasXSize-imgW)) {
ctx.drawImage(img, x-CanvasXSize+1, y, imgW, imgH);
}
}
//If image is > Canvas Size
else {
//reset, start from beginning
if (x > (CanvasXSize)) { x = CanvasXSize-imgW; }
//draw aditional image
if (x > (CanvasXSize-imgW)) { ctx.drawImage(img[0],x-imgW+1,y,imgW,imgH); }
}
for(i = 0; i < img.length; i++) {
ctx.drawImage(img[i],x,y,imgW,imgH);
//amount to move
x += dx;
}
}
To have multiple images loaded when you need them, you shoud use image preloader code:
var imgs=[];
var imagesOK=0;
var imageURLs=[];
imageURLs.push("https://dl.dropboxusercontent.com/u/139992952/stackoverflow/house1.jpg");
imageURLs.push("https://dl.dropboxusercontent.com/u/139992952/stackoverflow/house2.jpg");
imageURLs.push("https://dl.dropboxusercontent.com/u/139992952/stackoverflow/house3.jpg");
loadAllImages();
function loadAllImages(){
for (var i = 0; i < imageURLs.length; i++) {
// put each image in the imgs array
var img = new Image();
imgs.push(img);
// after each image has been loaded, execute this function
img.onload = function(){
// add 1 to imagesOK
imagesOK++;
// if imagesOK equals the # of images in imgs
// we have successfully preloaded all images
// into imgs[]
if (imagesOK>=imageURLs.length ) {
// all loaded--start drawing the images
drawImages();
}
}; // end onload
img.src = imageURLs[i];
} // end for
}
At this point the images are all loaded, so draw the images
You can use context.translate and context.rotate to tilt your images.
What you do is translate (move) to the center of the image you want to rotate. Then do the rotation from that centerpoint. That way the image will rotate around its center. The rotate function takes a radian angle so you can translate degrees to radians like this: 30 degrees = 30 * Math.PI/180 radians
ctx.translate( left+width/2, topp+height/2 )
ctx.rotate( degrees*Math.PI/180 );
Then you draw your image offset by its centerpoint (remember you’re rotating around that centerpoint)
ctx.drawImage(img,0,0,img.width,img.height,-width/2,-height/2,width,height);
It’s a lot to wrap your head around so here’s example code and a Fiddle: http://jsfiddle.net/m1erickson/t49kU/
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
body{ background-color: ivory; }
canvas{border:1px solid red;}
</style>
<script>
$(function(){
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var imgs=[];
var imagesOK=0;
var imageURLs=[];
imageURLs.push("https://dl.dropboxusercontent.com/u/139992952/stackoverflow/house1.jpg");
imageURLs.push("https://dl.dropboxusercontent.com/u/139992952/stackoverflow/house2.jpg");
imageURLs.push("https://dl.dropboxusercontent.com/u/139992952/stackoverflow/house3.jpg");
loadAllImages();
function loadAllImages(){
for (var i = 0; i < imageURLs.length; i++) {
var img = new Image();
imgs.push(img);
img.onload = function(){
imagesOK++;
if (imagesOK>=imageURLs.length ) {
drawImages();
}
}; // end onload
img.src = imageURLs[i];
} // end for
}
ctx.lineWidth=2;
var left=25;
var topp=30;
var width=100;
var height=100;
var rotations=[ -10, 0, 10 ];
function drawImages(){
for(var i=0;i<imgs.length;i++){
var img=imgs[i];
ctx.save()
ctx.beginPath();
ctx.translate( left+width/2, topp+height/2 )
ctx.rotate(rotations[i]*Math.PI/180);
ctx.drawImage(img,0,0,img.width,img.height,-width/2,-height/2,width,height);
ctx.rect(-width/2,-height/2,width,height);
ctx.stroke();
ctx.restore();
left+=125;
}
}
}); // end $(function(){});
</script>
</head>
<body>
<canvas id="canvas" width=400 height=200></canvas>
</body>
</html>