Using JS I creating a video from a series of screen grabs from a canvas element. E.g.
let encoder = new Whammy.Video(25); //25 is fps
for(...) {
//do stuff on canvas every x ms
....
//get a dataURL from the canvas
let dataURL = canvas.toDataURL('image/webp');
//add the dataURL to the encoder
encoder.add(dataURL);
}
// Now we want to create a video from the array of data urls
encoder.compile(false, (webm_output) => {
//webm_output is a blob
//create dataURL from blob
let url = URL.createObjectURL(webm_output);
let vid = documentGetElementById('myVid');
vid.src = url;
})
This all works, however, if the user would like to download the video (using in built controls), the name of the video is a random string.
Is it possible to manually specify the name?
On this demo:
<a style="" id="download" download="clock.webm" href="blob:[blob-url]">Download WebM</a>
The video name and extension is provided using the download= attribute.
Related
I have a function that brings users to a blob when a button is clicked and selections are made. The point is for them to click a download button and it take them to a blob with the gif on the page made based off their selections. I have working js/html/css that creates and downloads the gif for them but I am trying to now make code that makes the gif appear on the blob. It is successfully taking users to the blob but the gif is not appearing on the page. Any help would be appreciated.
js for creating the gif and sending users to the blob.
var directory = '/directory/here';
// add an event listener for the 'change' event on the dropdown menu
dropdown_fg2.addEventListener('change', function() {
// check if the selectedValue1 and selectedValue2 variables have been assigned values
if (!isNaN(selectedValue1) && !isNaN(selectedValue2)) {
// create an array of images
var images = [];
// set the starting image
var startImage = selectedValue1;
// set the ending image
var endImage = selectedValue2;
// set the step size for the images
var step = 6;
// create a loop to add the images to the array
for (var i = startImage; i <= endImage; i += step) {
var filePath = directory +"gfs_6hr_2m_temp_hour_"+i+ '.png';
// add the image to the array
images.push(filePath);
}
const downloadButton = document.getElementById('download-button2');
// Handle the button click
downloadButton.addEventListener('click', function () {
/// Generate gif
gifshot.createGIF({
'images': images,
'gifWidth': 1144,
'gifHeight': 894,
'interval': 0.33
},function(obj) {
if(!obj.error) {
const reader = new FileReader();
// Read the contents of the image file as a ArrayBuffer
reader.readAsArrayBuffer(obj.image);
reader.onload = function() {
// Create a Blob object that represents the GIF file
const gifBlob = new Blob([reader.result], {type: 'image/gif'});
// Use the URL.createObjectURL() method to create a URL for the Blob
const gifUrl = URL.createObjectURL(gifBlob);
console.log(gifUrl)
window.open(gifUrl);
// You can then use the URL to open the GIF file in a new window or to display it on your website
// var animatedImage = document.createElement('img');
var animatedImage = document.getElementById('my-image')
animatedImage.src = gifUrl;
console.log(animatedImage)
}
});
});
console.log(images);
}
})
I am converting an image to Base64 from Image URL using canvas. The approach I am taking is similar to below 2 links but the converted Base64 string is not opening up the image when viewed in Chrome Tab.
Links
CONVERT Image url to Base64
(1st answer with 81 thumbs up).
https://jsfiddle.net/3qshvc54/
I tried consoling the img, canvas, ctx in fiddle and my code. The console output is the same. Please see below screenshots.
If I do it by fiddle the converted Base64 URL opens up fine in a new tab, but the one generated from my code does not display an image when opened up in a new tab.
I am using same Image URL in my code and Fiddle
Console screenshot when running from my code
Console screenshot when running from Fiddle
The Base64 generated from my code:
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEQAAABDCAYAAAAlFqMKAAAApklEQVR4Xu3VsQ0AIAwEMbL/0tShQLrejHB6kzneKjB67AKCPIsQRJD/J2EhFmIh6ZAigwwyyKQCyCCTBuPKIIMMMqkAMsikwbgyyCCDTCqADDJpMK4MMsggkwogg0wajCuDDDLIpALIIJMG48oggwwyqQAyyKTBuDLIIINMKoAMMmkwrgwyyCCTCiCDTBqMK4MMMsikAsggkwbjyiCDDDKpADL/XBfFQABED54eAwAAAABJRU5ErkJggg==
I tried validating the same online it shows that the Base64 string is valid:
When I try to decode the same:
It seems that the result of decoding is a binary data (MIME type detected as “image/png”) and because of this the data from “Text” may be damaged during the output.
My code:
<div className='image-root'>
<img id={`imageBlock-${props.photoBoxID}`} className="multi-image-photo" src={props.imgUrl} alt="photo"></img>
</div>
getBase64Image = (img) => {
img.crossOrigin = 'Anonymous';
var canvas = document.createElement("CANVAS");
canvas.width = img.width;
canvas.height = img.height;
console.log('img', img);
var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0);
console.log('canvas', canvas);
console.log('ctx', ctx);
var dataURL = canvas.toDataURL();
console.log('dataURL', dataURL);
}
componentDidUpdate(prevProps, prevState){
if(this.props.isUploaded && (prevProps.isUploaded !== this.props.isUploaded)){
let imageRef = document.getElementById(`imageBlock-${this.props.photoBoxID}`);
imageRef.onload = this.getBase64Image(imageRef);
}
}
Can you suggest why the Base64 string generated is not opening up fine if converted from my code, though it opens up from Fiddle? Is it corrupted?
onload is an event you need function there and in that function you need to update src.
componentDidUpdate(prevProps, prevState){
if(this.props.isUploaded && (prevProps.isUploaded !== this.props.isUploaded)){
let imageRef = document.getElementById(`imageBlock-${this.props.photoBoxID}`);
imageRef.onload = () => {
delete imageRef.onload;
imageRef.src = this.getBase64Image(imageRef);
};
}
}
but better is to add base64 image to state and don't use getElementById directly in React applications.
EDIT:
for infinite loop I would create 2 images, if you need to render image on canvas you usually render outside of DOM:
componentDidUpdate(prevProps, prevState){
if(this.props.isUploaded && (prevProps.isUploaded !== this.props.isUploaded)){
let imageRef = document.getElementById(`imageBlock-${this.props.photoBoxID}`);
var srcImg = new Image();
srcImg.onload = () => {
imageRef.src = this.getBase64Image(srcImg);
};
srcImg.src = prevProps.imgUrl;
}
}
and remove the props from JSX template you will not need it.
And side note: if you have big image it's better to create object URL from blob, because there is limit of data that can be put into URL (for smaller images it should not matter):
function asObjectUrl(canvas) {
return new Promise(function(resolve) {
canvas.toBlob(function(blob) {
resolve(URL.createObjectURL(blob));
});
});
}
The object url need to be removed when not needed to not create memory leaks (use URL.revokeObjectURL)
change your img's src attribute adding src="data:image/jpeg;base64 tag with the encoded string like below:
<img id={`imageBlock-${props.photoBoxID}`} className="multi-image-photo" src="data:image/jpeg;base64, ${props.imgUrl}" alt="photo"></img>
This should work.
N.B.: Please check your imageString variable carefully, I might have used the wrong one, not sure.
I have a canvas which shows a graph and I'm trying to take a screenshot of the canvas using html2canvas() with the code below :
<div class="chartContainer" id="chart1"></div>
<div id="displayCanvas" style="display:none;" class="stx-dialog"></div>
html2canvas($('#chart1'),{onrendered:function(canvas1)
{$('#displayCanvas').append(canvas1)}});
Here when the chart container is loaded the it uses the div with the id "displayCanvas" and appends the screenshot of the canvas.
How can I download the screenshot of the canvas which is displayed?
I have already tried using something like below to download the image:
var link = document.createElement('a');
link.download = stx.chart.symbol+".png";
link.href = stx.chart.canvas.toDataURL("png");
link.click();
but it only downloads the data on the canvas as an image without the background (it does not download the screenshot but only the data) which when opened after downloading shows a black screen with data in it. Can anyone help me on how to download the image directly of the screenshot taken from the html2Canvas()?
TRY THIS:
In the HTML:
Give the element that you want to screenshot, an ID of "capture".
Give the button/element that you would need to click to take the screenshot, an ID of "btn".
Load the html2canvas.min.js file.
In the Javascript:
Create the capture() function.
Bind the capture() function to whatever event you are using—in this case it's on the btn click event.
DONE! Watch the magic happen when you click on the btn.
HTML:
<h1 id="capture">Hellooooo</h1>
<button id="btn">Capture</button>
<script src="https://html2canvas.hertzen.com/dist/html2canvas.min.js"></script>
Javascript:
function capture() {
const captureElement = document.querySelector('#capture') // Select the element you want to capture. Select the <body> element to capture full page.
html2canvas(captureElement)
.then(canvas => {
canvas.style.display = 'none'
document.body.appendChild(canvas)
return canvas
})
.then(canvas => {
const image = canvas.toDataURL('image/png').replace('image/png', 'image/octet-stream')
const a = document.createElement('a')
a.setAttribute('download', 'my-image.png')
a.setAttribute('href', image)
a.click()
canvas.remove()
})
}
const btn = document.querySelector('#btn')
btn.addEventListener('click', capture)
Here's the JSFiddle
💡 QUICK TIP: If you want to capture the whole document/webpage, then just add the "capture" ID to the <body> tag.
If there is black background at image your chart must be visible on screen. Because html2canvas like a taking screenshot. If you want converting data
to canvas, you must be sure data is appear in screen.
In case someone is using React, here is some code you can copy:
async function download() {
const canvas = await html2canvas(document.querySelector("#screenshot"));
canvas.style.display = "none";
document.body.appendChild(canvas);
const image = canvas.toDataURL("image/png").replace("image/png", "image/octet-stream");
const a = document.createElement("a");
a.setAttribute("download", `info.png`);
a.setAttribute("href", image);
a.click();
}
<a href="#" onClick={() => download()}>Download</a>
This worked for me:
HTML
<div id="canvasDiv">
<canvas id="canvas" height="100" width="100">
Your browser does not support the HTML canvas tag.
</canvas>
</div>
<button onclick="screenShot()" type="button">Take a screenshot</button>
Javascript
function screenShot(){
html2canvas(document.querySelector("#canvasDiv")).then(canvas => {
var dataURL = canvas.toDataURL( "image/png" );
var data = atob( dataURL.substring( "data:image/png;base64,".length ) ),
asArray = new Uint8Array(data.length);
for( var i = 0, len = data.length; i < len; ++i ) {
asArray[i] = data.charCodeAt(i);
}
var blob = new Blob( [ asArray.buffer ], {type: "image/png"} );
saveAs(blob, "photo.png");
});
}
I just used the code provided in html2canvas site, then i used this code to download the screenshot.
Is there anyway that I can put an image on my site that changes.
I know how to change the source of an image element. What I mean is like:
the image is located here
http://mywebsite.com/image.png
this doesn't change but I want the actual image to change.
More examples:
https://huggle.jdf2.org/
This site creates a bbcode element that contains the img username.png
[url=http://huggle.jdf2.org/hug/username][img]http://huggle.jdf2.org/sig/username.png[/img][/url]
This image changes depending on how many huggles you have.
How would I do this?
You can dynamically set the image source URL with:
var yourURLHere = 'ADD YOUR URL HERE';
image.src = yourURLHere;
If you want the your image to randomly change, you can use Math.random() to select a random URL from an array.
Example: Random teddy bear images (see below).
<image src="#" id="my-image"/>
Click to change image randomly.
<button id="my-btn">Change it!</button>
<script>
var imageURLs = [
'https://s-media-cache-ak0.pinimg.com/originals/4e/da/9f/4eda9f56de08463bcc18d154f654ab6d.jpg',
'http://lcdn.inthelighturns.com/media/product/e85/sweet-memories-blue-teddy-bear-urn-b83.jpg',
'https://s-media-cache-ak0.pinimg.com/originals/3c/80/3c/3c803ce72e8c0325d7ea0fcd32f81ed9.jpg',
'http://cliparting.com/wp-content/uploads/2016/07/Cartoon-teddy-bear-clipart.gif',
'http://cliparts.co/cliparts/rcn/Kox/rcnKox65i.png',
'https://s-media-cache-ak0.pinimg.com/originals/f2/d6/25/f2d6258ef0fa6de2160778066ccec832.jpg',
'https://s-media-cache-ak0.pinimg.com/236x/90/3a/6c/903a6c59c0a2f42e7d6e7cb9427a8337.jpg',
'https://s-media-cache-ak0.pinimg.com/564x/a9/ee/30/a9ee30a4f8d196a111aa5c3db7b13b6e.jpg',
'http://cdn3.volusion.com/9nxdj.fchy5/v/vspfiles/photos/BB-1433-2.jpg?1415360799'
];
var image = document.getElementById('my-image');
function pickRandomURL() {
return imageURLs[Math.floor(Math.random() * imageURLs.length)];
}
image.src = pickRandomURL();
image.width = 200;
var btn = document.getElementById('my-btn');
btn.onclick = function() {
image.src = pickRandomURL();
image.width = 200;
};
</script>
Using socket.io, I'm pushing images from a server to the client using base64 encoded strings:
socket.on('send_picture', function (data){
socket_data = (socket_data + data);
document.getElementById('imgid').src = socket_data
})
How can I reset the src of 'imgid' at the next socket.io event? It works fine one time, but then won't display new images until I refresh the page
I've found that the most reliable way to load new image content is to create a new image element each time and replace the prior image object with the new one. You could do that like this:
socket.on('send_picture', function (data){
socket_data = socket_data + data;
var oldImg = document.getElementById('imgid');
var newImg = new Image();
newImg.src = socket_data;
newImg.id = 'imgid';
oldImg.parentNode.replaceChild(newImg, oldImg);
});