Can I use a BPG image as a <div> or <body> background? background: url('bg.bpg'); doesn't work.
There is a Javascript decoder which allows .bpg images to be displayed in <img> tags, but I want to use one as a <body> background.
The Javascript BPG decoder works by converting the source .bpg file into an ImageData object, which can then be drawn to a canvas. So all you need to do is get the canvas as a PNG data string and set that as the body background image:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>BPG background example.</title>
<!-- Decoder script from http://bellard.org/bpg/ -->
<script src="bpgdec8a.js"></script>
<script>
"use strict";
function setBackground(filename)
{
// Create a hidden canvas with the same dimensions as the image.
var canvas = document.createElement("canvas");
canvas.style.visibility = "hidden";
canvas.width = 512;
canvas.height = 512;
document.body.appendChild(canvas);
// Create a drawing context and a BPG decoder.
var ctx = canvas.getContext("2d");
var img = new BPGDecoder(ctx);
// Attempt to load the image.
img.onload = function()
{
// Once the image is ready, draw it to the canvas...
ctx.putImageData(this.imageData, 0, 0);
// ...and copy the canvas to the body background.
document.body.style.background = "url('" + canvas.toDataURL("image/png") + "')";
};
img.load(filename);
}
</script>
</head>
<body onload="setBackground('lena512color.bpg');">
<p>Hello, World!</p>
</body>
</html>
Related
I am trying to use an image as the background of my canvas. However, I have a hard time to make the image load -- it always shows as blank:
<html>
<script>
var background = new Image();
background.src = "img/map.png";
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
window.onload = function() {
ctx.drawImage(background, 0, 0);
}
</script>
<body>
<canvas id="myCanvas" width="400" height="400"> </canvas>
</body>
</html>
However, if I put the following two lines into the window.onload function, then the image loads without any issue. what causes this issue? As I will use canvas and ctx in other functions, I really want to define them globally rather than individually define them in each function.
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
you can still use them globally. As canvas is not available immediately you are not able to draw picture before on load.
<script>
var background = new Image();
background.src = "img/map.png";
var canvas;
var ctx ;
window.onload = function() {
canvas = document.getElementById("myCanvas");
ctx = canvas.getContext("2d");
ctx.drawImage(background, 0, 0);
} </script>
1) The first option is to declare the canvas and context and assign them values after the document has loaded
<!DOCTYPE html>
<html lang="en">
<head>
<title>Onload</title>
<script>
const background = new Image();
background.src = "img/map.png";
let canvas;
let ctx;
window.onload = function() {
canvas = document.getElementById("myCanvas");
ctx = canvas.getContext("2d");
ctx.drawImage(background, 0, 0);
}
</script>
</head>
<body>
<h1>Method One</h1>
<p>Defined variables globally and assign then after the load event is fired</p>
<canvas id="myCanvas" width="400" height="400"></canvas>
</body>
</html>
2) The second method would be to put the script block after the canvas element so that it is already loaded in the DOM when your javascript tries to access it.
<!DOCTYPE html>
<html lang="en">
<head>
<title>Onload</title>
</head>
<body>
<h1>Method Two</h1>
<p>Put the script after the DOM element you wish to access</p>
<canvas id="myCanvas" width="400" height="400"></canvas>
<script>
const background = new Image();
background.src = "img/map.png";
const canvas = document.getElementById("myCanvas");
const ctx = canvas.getContext("2d");
window.onload = function() {
ctx.drawImage(background, 0, 0);
}
</script>
</body>
</html>
I've used the new const and let keywords just to highlight the difference between these two approaches, although using var instead will work fine too. (see let and const)
If you want to avoid global variables then you might structure your code like this
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Onload</title>
<script>
const background = new Image();
background.src = "img/map.png";
draw = context => {
context.drawImage(background, 0, 0);
}
window.addEventListener('load', () => {
const canvas = document.querySelector("#myCanvas");
const ctx = canvas.getContext("2d");
draw(ctx);
});
</script>
</head>
<body>
<h1>Refactor</h1>
<p>Add an event listener and pass in context to draw function</p>
<canvas id="myCanvas" width="400" height="400"></canvas>
</body>
</html>
It doesn't matter that I'm using arrow functions, or querySelector, I just prefer these newer methods. The point is to pass in the canvas context to any function that needs it draw(ctx).
The two lines of code creating the Image() and then setting the background had to be done before the document had finished loading, this is a bit of a fudge. What we really need to do is make sure that the image we are trying to set as the background has loaded before calling drawImage() Using images
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Onload</title>
<script>
draw = context => {
const background = new Image();
background.src = "img/map.png";
background.addEventListener('load', () => {
context.drawImage(background, 0, 0);
});
}
window.addEventListener('load', () => {
const canvas = document.querySelector("#myCanvas");
const ctx = canvas.getContext("2d");
draw(ctx);
});
</script>
</head>
<body>
<h1>Final</h1>
<p>Add an event listener to the image</p>
<canvas id="myCanvas" width="400" height="400"></canvas>
</body>
</html>
I am trying to write some code that converts the first page of a PDF to a PNG thumbnail. I have found several examples here on stackoverflow and other place on the web and it seems like a simple thing to do, but I cannot make it work.
I have a HTML file that looks like this
<!DOCTYPE html>
<html>
<head>
<title>JR PDF test</title>
</head>
<body>
<script type="text/javascript" src="/build/pdf.js"></script>
<script type="text/javascript" src="jr-pdf.js"></script>
<script type="text/javascript" src="canvas2image.js"></script>
</body>
<div id="pdf-main-container">
<a id="download-image" href="#">Download PNG</a>
</div>
</div>
</html>
<canvas id="the-canvas"></canvas>
and a the jr-pdf.js looks like this
// URL of PDF document
var url = "REGLEMENT_FOR_RALLY_2012.pdf";
// Asynchronous download PDF
PDFJS.getDocument(url)
.then(function(pdf) {
return pdf.getPage(1);
})
.then(function(page) {
// Set scale (zoom) level
var scale = 1.5;
// Get viewport (dimensions)
var viewport = page.getViewport(scale);
// Get canvas#the-canvas
var canvas = document.getElementById('the-canvas');
// Fetch canvas' 2d context
var context = canvas.getContext('2d');
// Set dimensions to Canvas
canvas.height = viewport.height;
canvas.width = viewport.width;
// Prepare object needed by render method
var renderContext = {
canvasContext: context,
viewport: viewport
};
// Render PDF page
page.render(renderContext);
// JR experiments
console.log('hej');
url = canvas.toDataURL();
downloadButton = document.getElementById('download-image');
downloadButton.setAttribute('download', 'jr.png');
downloadButton.setAttribute('href', url);
});
The first page of the PDF file is rendered correctly to the screen and a jr.png file is generated. When I look at the PNG file the header seems right, but when I try to view the file with an image viewer it is empty (actually it is shown as transparent).
So I guess these lines are wrong:
url = canvas.toDataURL();
downloadButton = document.getElementById('download-image');
downloadButton.setAttribute('download', 'jr.png');
downloadButton.setAttribute('href', url);
Any suggestions on how to make a correct PNG file?
page.render is asynchronous function -- you need to wait until it finishes painting
var renderTask = page.render(renderContext);
renderTask.promise.then(function () {
// use canvas now
var url = canvas.toDataURL();
var downloadButton = document.getElementById('download-image');
downloadButton.setAttribute('download', 'jr.png');
downloadButton.setAttribute('href', url);
});
I am in the process of building an app for my research and I am new to canvas. I am trying to make a video out of a set of images and I need to be able to dynamically change a particular frame. I was successful in making the video but unable to modify a particular frame when I reach it. Below is the code for the same.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Images with intervals</title>
</head>
<body>
<canvas id="myCanvas1" width="400" height="200" style="position:absolute;right:0; margin-right:auto; background-color:#bbb"></canvas>
<canvas id="myCanvas2" width="400" height="200" style="position:absolute;left:0; margin-left:auto; background-color:#666"></canvas>
<script type="text/javascript">
var canvas = document.getElementById('myCanvas2');
var context = canvas.getContext('2d');
var i = 0;
var im1 = 'images/img1.png';
function drawScreen() {
context.drawImage(im1, 0, 0,50,50);
}
setInterval(function() {
var im = ['images/img1.png', 'images/img2.png', 'images/img3.png', 'images/img4.png', 'images/img5.png'];
// Create the image object
var img = new Image();
//alert(window["i"]);
// If the image is loaded draw it on canvas
img.addEventListener('load', function() {
canvas.width = img.width;
canvas.height = img.height;
context.drawImage(img, 0, 0);
});
//alert(window["i"]);
// pass in the image source
img.src = im[i++];
alert(window["i"]);
// if the image is last, change it back to the first
i = i > im.length - 1 ? 0 : i;
//alert(window["i"]);
if(i==3)
{ drawScreen();
//alert(window["i"]);
}
}, 1000);
</script>
</body>
</html>
When the value of i=3(meaning in 3 seconds according to the setInterval function), I am trying to display another image 'im1' as an example, which I am unable to do. I am new with HTML5 and canvas. Any help and suggestions here is deeply appreciated.
index.html
<html lang="en-US">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=8" />
<title>DCView</title>
<script type="text/javascript" src="dcview.js"></script>
</head>
<body>
<div style="float:center; text-align:center;">
<canvas id="dcviewCanvas" width="1024" height="1024"/>
<img id="bgImage" src="" hidden="true"/>
</div>
</body>
</html>
dcview.js
var backgroundImage,
backgroundImageSrc,
canvas,
context;
window.onload = function()
{
//Initially set the background image source to DCView.png
backgroundImageSrc = "Foundation\\WebService\\Downloads\\DCView.png";
//Load the background image with the given source
loadBackgroundImage(backgroundImageSrc);
}
function loadBackgroundImage(imageSrc)
{
canvas = document.getElementById("dcviewCanvas");
context = canvas.getContext("2d");
backgroundImage = document.getElementById("bgImage");
backgroundImage.src = imageSrc;
context.drawImage(backgroundImage, 0, 0);
}
When I try to load index.html in chrome it doesn't load the background image. But when I hard-code the src of the img tag in to that path, it proceeds to load it in.
The only error chrome gives me is:
Uncaught SyntaxError: Unexpected token .
It points this error to line 47 in dcview.js.
Is the way I am going about this completely wrong? I am a beginner with HTML and Javascript.
Thanks,
Virat
UPDATED
dcview.js
window.onload = function()
{
//Initially set the background image source to DCView.png
backgroundImageSrc = 'Foundation/WebService/Downloads/Layout_Basement.png';
//Load the background image which is initially set to DCView.png
loadBackgroundImage(backgroundImageSrc);
//Load the other various pin images;
loadPinImages();
}
function loadBackgroundImage(imageSrc)
{
context = document.getElementById('dcviewCanvas').getContext('2d');
backgroundImage = new Image();
backgroundImage.src = imageSrc;
backgroundImage.onload = function(){
context.drawImage(backgroundImage, 0, 0);
};
}
UPDATED
Once I have loaded the background image, other images I draw on top are being drawn underneath the background image. Ideas?
window.onload = function()
{
//Initially set the background image source to DCView.png
backgroundImageSrc = 'Foundation/WebService/Downloads/Layout_Basement.png';
//Load the background image which is initially set to DCView.png
loadBackgroundImage(backgroundImageSrc);
canvas = document.getElementById('dcviewCanvas');
context = canvas.getContext('2d');
context.drawImage(sortationLanePinBlue, 0, 0);
}
You can use the Javascript Image class to draw to a canvas. See this article on MDN.
I'm having a problem with retrieving the base64 version of an image displayed on a canvas. I've looked at the other questions but none of the solutions including canvas2image seem to work.
Here's my code:
<!DOCTYPE>
<html>
<head>
<style>#canvas {cursor: pointer;}</style>
</head>
<body>
<canvas id="canvas"></canvas>
<script type="text/javascript">
var can = document.getElementById('canvas');
var ctx = can.getContext('2d');
var img = new Image();
img.onload = function(){
can.width = img.width;
can.height = img.height;
ctx.drawImage(img, 0, 0, img.width, img.height);
}
img.src = 'http://sstatic.net/stackoverflow/img/newsletter-ad.png';
can.onclick = function() {
ctx.translate(img.width-1, img.height-1);
ctx.rotate(Math.PI);
ctx.drawImage(img, 0, 0, img.width, img.height);
};
document.write(can.toDataURL()); //isn't writing the correct base64 image
</script>
</body>
</html>
Here's the test link: http://jsfiddle.net/mrchief/hgTdM/1/ thanks, Mrchief
What I need is the correct base64 output of the image in the canvas.
The problem is that it won't output the correct base64 version of the image.. But as you can see, the image inside the canvas is displayed without any problems.
I've tested it on chrome & firefox
Thanks very much..
Your document.write() call occurs immediately upon page load, before your img is loaded and drawn and before your onclick handler can ever run. You need to wait to generate the data URI until after everything has finished happening to the canvas.
Ignoring the onclick, here's something that writes out the data url after the image has loaded and been drawn to the canvas in a rotated fashion:
<!DOCTYPE html>
<html><head>
<title>Rotated Image Data URL</title>
<style type="text/css" media="screen">
canvas, textarea { display:block }
</style>
</head><body>
<canvas id="canvas"></canvas>
<textarea id="data" rows="20" cols="80"></textarea>
<img id="echo">
<script type="text/javascript">
var can = document.getElementById('canvas');
var ctx = can.getContext('2d');
var img = new Image();
img.onload = function(){
can.width = img.width;
can.height = img.height;
ctx.translate(img.width-1, img.height-1);
ctx.rotate(Math.PI);
ctx.drawImage(img, 0, 0, img.width, img.height);
var url = document.getElementById('data').value = can.toDataURL();
document.getElementById('echo').src = url;
}
img.src = 'gkhead.jpg';
</script>
</body></html>
You can see this demo in action here: http://phrogz.net/tmp/upside-down-image-url.html
Note that the image you load must be on the same domain as your script, or else you will not be allowed to create the data URL.