How to get a gif to show up on a blob - javascript

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);
}
})

Related

How to preview a file in different pages with one selection in JS

I am making a PDF Viewer. I am using ADOBE View SDK. I have a File input but the problem is that I want to show the file in different views - Full Screen, Half Screen and In-Line. But when the user selects a file and selects a different view the whole page reloads and then the user has to select the file again. I don't want the user to select the file again.
File Input:
<input type='file' onchange="listenForFileUpload(this);" id="file-picker" accept="application/pdf">
listenForFileUpload function:
var fileToRead = document.getElementById("file-picker");
fileToRead.addEventListener("change", function (event) {
var files = fileToRead.files;
var input = document.getElementById('file-data').value
input = files
console.log(files)
document.getElementById('file-form').submit()
if (files.length > 0 && isValidPDF(files[0])) {
var fileName = files[0].name;
var reader = new FileReader();
reader.onloadend = function (e) {
var filePromise = Promise.resolve(e.target.result);
previewFile(filePromise, fileName);
};
reader.readAsArrayBuffer(files[0]);
}
}, false);
}
Please help me to change the view without reloading.
It's this line here:
document.getElementById('file-form').submit()
You are submitting the form there. I'd just remove it.

How to save canvas on Right-Click dialog as jpg

I'm using this code to capture images as canvas from a video URL in my site:
var videoId = 'video';
var scaleFactor = 0.55; // increase or decrease size
var snapshots = [];
/**
* Captures a image frame from the provided video element.
*
* #param {Video} video HTML5 video element from where the image frame will be captured.
* #param {Number} scaleFactor Factor to scale the canvas element that will be return. This is an optional parameter.
*
* #return {Canvas}
*/
function capture(video, scaleFactor) {
if(scaleFactor == null){
scaleFactor = 1;
}
var w = video.videoWidth * scaleFactor;
var h = video.videoHeight * scaleFactor;
var canvas = document.createElement('canvas');
canvas.width = w;
canvas.height = h;
var ctx = canvas.getContext('2d');
ctx.drawImage(video, 0, 0, w, h);
var uniq = 'img_' + (new Date()).getTime();
canvas.setAttribute('id', uniq);
return canvas ;
}
/**
* Invokes the <code>capture</code> function and attaches the canvas element to the DOM.
*/
function shoot(){
var video = document.getElementById(videoId);
var output = document.getElementById('output');
var canvas = capture(video, scaleFactor);
snapshots.unshift(canvas);
output.innerHTML = '' ;
for(var i=0; i<10; i++){
output.appendChild(snapshots[i]);
}
}
My two problems:
1 - Currently, browsers treat <canvas> like they they treat a <div> and this make it impossible to save any generated canvas as an image because when I right-click on each and everyone, it always opens the windows dialog here I have to choose Save image as....
2 - The windows right-click dialog always opens by default the option to save image as transfer.png and I would like to save the image with their ID attribute (var uniq) and a jpg extension.
Example of what I need:
The output canvas is like this: <canvas width="352" height="198" id="img_1575807516362"></canvas>.
I want the right-click to open the windows dialog offering to save image like this img_1575807516362.jpg.
Alternatively, it would be nice tho have a download button for each canvas to export the canvas as an image like this transfer.jpg.
Is it possible to make this work with this code?
Apologies in advance. It took me some time, but I wanted to make sure that I got it working properly. I am not sure if there is a way to do a windows dialog to save to file (Where it pulls up the save as... prompt), but you can definitely create a download button to do this.
Downloading the Image
First, we need to create a download button:
<button onmousedown="download()">Download</button>
Second, we can create a function to download the image with a key.
The easiest way to do this is creating a downloadable <a> tag:
var download = function(){
var link = document.createElement('a'); //Creates an 'a' element
var thisCanvas = document.getElementsByTagName('canvas')[0]; //gets the first canvas element on the page, assuming the canvas you want to download is this element.
link.download = `${thisCanvas.id}.jpeg`; //Gives the download an output link
link.href = thisCanvas.toDataURL("image/jpeg") //Gives the data to the link
link.click(); //Clicks the 'a' element we created
}
If you wanted to ask for user input whether or not they want to download, you can use:
var download = function() {
if (window.confirm("Would you like to download this frame?")) {
var link = document.createElement('a'); //Creates an 'a' element
var thisCanvas = document.getElementsByTagName('canvas')[0]; //Gets the canvas
link.download = `${thisCanvas.id}.jpeg`; //Gives the download an output link
link.href = thisCanvas.toDataURL("image/jpeg") //Gives the data to the link
link.click(); //Clicks the 'a' element we created
}
}
You can always change the name of the image file as well with link.download = imageName + ".jpeg"
Creating A Button in JS
EDIT: If you want to create the button in javascript instead of html, you can do the following:
var createbutton = function() {
var b = document.createElement('button'); //Creates the button
b.onmousedown = function() { //Creates an onmousedown event for the button
download(); //This is the download function above
}
b.innerHTML = "Download"; //Gives the button Text
//Here, you can insert button styles using: b.style
document.body.appendChild(b); //Appends the button to the body
}
You can call this function whenever you need to create the download button. This function creates a button at the end of the body, but you can change the location:
//Where it says document.body.appendChild(b); , replace it with:
document.getElementById(`myCustomId`).appendChild(b);
//This places the button in any element on the page with 'myCustomId'
Canvas onmousedown events, and downloading all images
EDIT (2):
If you have multiple canvases that are created within snapshots, then you can do the following to download all the snapshots:
var download = function(){
var link = document.createElement('a'); //Creates an 'a' element
snapshots.forEach(snap => {
link.download = `${snap.id}.jpeg`; //Gives the download an output link
link.href = snap.toDataURL("image/jpeg") //Gives the data to the link
link.click(); //Clicks the 'a' element we created
});
}
If you want to download one image at a time, you can give them an onmousedown event when you add them. Let's edit the download function to support this:
var download = function(canvas){
var link = document.createElement('a'); //Creates an 'a' element
link.download = `${canvas.id}.jpeg`; //Gives the download an output link
link.href = canvas.toDataURL("image/jpeg") //Gives the data to the link
link.click(); //Clicks the 'a' element we created
}
//We also need to edit the shoot() function
function shoot(){
var video = document.getElementById(videoId);
var output = document.getElementById('output');
var canvas = capture(video, scaleFactor);
canvas.onmousedown = function() {
download(canvas);
}
snapshots.unshift(canvas);
output.innerHTML = '' ;
for(var i=0; i<10; i++){
output.appendChild(snapshots[i]);
}
}
This way whenever you append all of the snapshots, each canvas comes with it's own mousedown event, so clicking on it will return the image. You can even add a confirm box or check if right mouse is clicked here.
Question 2: It doesn't matter where the functions go, only where you call them.
If you have any questions, let me know!

How do I find the src value of an image uploaded using fileReader?

I'm building a program that allows the user to choose an image to upload. Once the user chooses one, it triggers the previewFile() function, which uses FileReader to display the image.
Now I'm building a function that will download the same image that the user uploaded (and add some style changes). First, I created a new image element, but now I'm stuck, since I can't figure out how to reference the src value of the original image. Once I do get the src value, I can finish adding the styles, then download the edited image.
Here's what I have so far - can anyone help me out?
HTML:
<input type="file" onchange="previewFile()">
<img src="" alt="Preview File...">
JavaScript:
function previewFile() {
const preview = document.querySelector('img');
const file = document.querySelector('input[type=file]').files[0];
const reader = new FileReader();
reader.addEventListener("load", function () {
preview.src = reader.result;
}, false);
if (file) {
reader.readAsDataURL(file);
}
}
And the function I need help with:
function createAndDownload() {
const editedImage = document.createElement('img');
/*
Here's where I need help: I need to figure out how to get the image src
from the original image, and set it equal to editedImage.src
*/
//add styles
//download editedImage
}
You assigned it this way:
const preview = document.querySelector('img');
preview.src = reader.result;
So you do the same thing to read it back:
const preview = document.querySelector('img');
const something = preview.src;

JavaScript reading and previewing multiple images

I have found code for reading multiple images on the
internet.
Here is the code:
HTML
<input id="browse" type="file" onchange="previewFiles()" multiple>
JavaScript
function previewFiles() {
var preview = document.querySelector('#preview');
var files = document.querySelector('input[type=file]').files;
function readAndPreview(file) {
// Make sure `file.name` matches our extensions criteria
if ( /\.(jpe?g|png|gif)$/i.test(file.name) ) {
var reader = new FileReader();
reader.addEventListener("load", function () {
var image = new Image();
image.height = 100;
image.title = file.name;
image.src = this.result;
preview.appendChild( image );
}, false);
reader.readAsDataURL(file);
}
}
if (files) {
[].forEach.call(files, readAndPreview);
}
}
I have a problem with it, as I do not fully understand what is happening and why it does not preview/seems like it is storing multiple files.
The main problem in the included code is that there is no element with the id preview (ref: var preview = document.querySelector('#preview');)
Adding this and it will work. However, you can skip FileReader as it isn't needed. Instead treat the File as a Blob (they are essentially the same) and use createObjectURL() with it - the performance and the memory footprint are significant better in case you want to display a high amount of images.
document.querySelector('#browse').onchange = function() {
var preview = document.querySelector('#preview');
[].forEach.call(this.files, function(file) {
if (/image\/.*/.test(file.type)) { // use any image format the browser can read
var img = new Image;
img.onload = remURL; // to remove Object-URL after use
img.style.height = "100px"; // use style, "width" defaults to "auto"
img.src = (URL || webkitURL).createObjectURL(file);
preview.appendChild(img); // add image to preview container
}
});
function remURL() {(URL || webkitURL).revokeObjectURL(this.src)}
};
<input id="browse" type="file" multiple>
<div id=preview></div> <!-- an element with this ID was missing -->
Your final lines of code:
if (files) {
[].forEach.call(files, readAndPreview);
}
Should do nothing. It goes for each over an empty array.
I think you were trying to do something like:
files.forEach(readAndPreview)
Which would actually go over all of the files in the files array and call readAndPreview for them.

How to change image src after set by socket.io event?

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);
});

Categories