JavaScript object containing multiple Base64 image codes - javascript

Project:
Loading screen with Base64 image in Playcanvas (WebGL)
What I try to do:
Change the image when the Website is loaded with other language (index.html?language=xy)
What I already have:
I get the default image in my WebGL loading javascript.
var logo = document.createElement('img');
logo.src = 'here is my base64 code';
splash.appendChild(logo);
logo.onload = function() {
splash.style.display = 'block';
};
I thought it would be the best option to list all languages in an object, and invoke the object with the language that is currently selected.
Why I can't figure it out myself:
As I just started creating javascript projects, I need to lookup many thing, but when I search up my issue I get stuff like this Base64 encode a javascript object

Define all the images in an object
const images = {
'us': 'data:image/jpeg;base64,...',
'nl': 'data:image/jpeg;base64,...',
'fallback': 'data:image/jpeg;base64,...'
}
Parse the query paramters, use a fallback if not given
const urlSearchParams = new URLSearchParams(window.location.search);
const params = Object.fromEntries(urlSearchParams.entries());
let lanuageKey = params['language'];
if (!images[lanuageKey]) {
lanuageKey = 'fallback';
}
Add the image with desired base64
var logo = document.createElement('img');
logo.src = images[lanuageKey];
document.body.appendChild(logo);
Putting this all together, will give something like the following snippet:
Note 1: Stack Snippets can't read the query params, so you'll need to try this locally
Note 2: Due to the 30k max chars, I had to remove the base64's
const images = {
'us': 'data:image/jpeg;base64...',
'nl': 'data:image/jpeg;base64...',
'fallback': 'data:image/jpeg;base64...'
}
const urlSearchParams = new URLSearchParams(window.location.search);
const params = Object.fromEntries(urlSearchParams.entries());
let lanuageKey = params['language'];
if (!images[lanuageKey]) {
lanuageKey = 'fallback';
}
var logo = document.createElement('img');
logo.src = images[lanuageKey];
document.body.appendChild(logo);

Related

How do I save the inputs of an HTML form into a JSON file with JavaScript?

As my question already reveals, I am trying to save inputs from an HTML form to a json file - However I only get to save the inputs to the localStorage.
let movies = [];
const addMovie = (ev)=>{
ev.preventDefault();
let movie = {
id: Date.now(),
title: document.getElementById('title').value,
year: document.getElementById('yr').value
}
movies.push(movie);
document.querySelector('form').reset();
//saving to localStorage
localStorage.setItem('key', JSON.stringify(movies) );
}
document.addEventListener('DOMContentLoaded', ()=>{
document.getElementById('btn').addEventListener('click', addMovie);
});
Now, I've already tried the fs.writeFile methods but somehow my pc doesn't want to import fs.
So I'm asking if there's another way to write the inputs into JSON or how to fix the import fs bug.
In a web browser, you can invoke download in multiple ways. One of possibilities are window.opening a window, redirection, or creating a link and invoking its click method.
const jsonToDownload = '{"foo":42}'
function download() {
const aElem = document.createElement("A")
aElem.href = 'data:application/octet-stream,' + jsonToDownload
aElem.download = 'filename.json'
aElem.click()
}
<button onclick=download()>Download</button>
You can use any filename. Just set the download attribute on the link to the filename.
If you want do download binary or large data, using BLOB object might be better idea. It is quite simple – create the BLOB, generate its URL, initiate the download and revoke the URL of the BLOB.
const jsonToDownload = '{"foo":42}'
function download() {
const blob = new Blob([jsonToDownload, ], {
type: 'application/json',
})
const url = URL.createObjectURL(blob)
const aElem = document.createElement("A")
aElem.href = 'data:application/octet-stream,' + jsonToDownload
aElem.download = 'a'
aElem.click()
URL.revokeObjectURL(url)
}
<button onclick=download()>Download</button>
Please note that the snippet above will not probably work, because StackOverflow's iframe usage prohibits this behavior in some browsers. Copy the code in your own HTML file adn try it there.

Using pdf.js to render a PDF but it doesn't work and I don't get any error messages to help me debug the issue

I'm trying to build a Flask app where I upload pdf's and I'm working on previewing them before submitting to the back-end.
The script I'm using is as follows:
const imageUploadValidation = (function () {
"use strict";
pdfjsLib.GlobalWorkerOptions.workerSrc =
"https://mozilla.github.io/pdf.js/build/pdf.js";
const onFilePicked = function (event) {
// Select file Nodelist containing 1 file
const files = event.target.files;
const filename = files[0].name;
if (filename.lastIndexOf(".") <= 0) {
return alert("Please add a valid file!");
}
const fileReader = new FileReader();
fileReader.onload = function (e) {
const pdfData = e.target.result;
let loadingTask = pdfjsLib.getDocument({ data: pdfData })
loadingTask.promise.then(function (pdf) {
console.log("PDF loaded", pdf);
pdf.getPage(1).then((page) => {
console.log("page loaded", page);
// var scale = 1.5;
// var viewport = page.getViewport({ scale: scale });
var iframe = document.getElementById("image-preview");
iframe.src = page
// var context = canvas.getContext("2d");
// canvas.height = viewport.height;
// canvas.width = viewport.width;
// var renderContext = {
// canvasContext: context,
// viewport: viewport,
// };
// var renderTask = page.render(renderContext);
// renderTask.promise.then(function () {
// console.log("Page rendered");
// });
});
})
.catch((error) => {
console.log(error);
});
};
const pdf = fileReader.readAsArrayBuffer(files[0]);
console.log("read as Data URL", pdf);
};
const Constructor = function (selector) {
const publicAPI = {};
const changeHandler = (e) => {
// console.log(e)
onFilePicked(e);
};
publicAPI.init = function (selector) {
// Check for errors.
const fileInput = document.querySelector(selector);
if (!selector || typeof selector !== "string") {
throw new Error("Please provide a valid selector");
}
fileInput.addEventListener("change", changeHandler);
};
publicAPI.init(selector);
return publicAPI;
};
return Constructor;
})();
imageUploadValidation("form input[type=file]");
The loading task promise never seems to run. Everything seems to work up until that point. I'm not familiar with this Promise syntax, so I can't be sure if the problem is there or how I'm passing in the pdf file.
P.S. The commented out code is the original way I had this setup, what
s uncommented was just me testing a different way.
Check Datatype
First you might want to check what your getting back from your FileReader, specifically what is the datatype for pdfData. If you have a look at the documentation (direct link) getDocument is expecting a Unit8Array or a binary string.
Add Missing Parameters
The next problem you have is your missing required parameters in your call to getDocument. Here is the minimum required arguments:
var args = {
url: 'https://example.com/the-pdf-to-load.pdf',
cMapUrl: "./cmaps/",
cMapPacked: true,
}
I have never used the data argument in place of the url but as long as you supply the correct datatype you should be fine. Notice that cMapUrl should be a relative or absolute path to the cmap folder. PDFJS often needs these files to actually interpret a PDF file. Here are all the files from the demo repository (GitHub pages): cmaps You'll need to add these to your project.
Instead of using data I would recommend uploading your files as blobs and then all you have to do is supply the blob URL as url. I am not familiar with how to do that, I just know its possible in modern browsers.
Where Is Your Viewer / You Don't Need iFrame or Canvas
PDFJS just needs a div to place the PDF inside of. It's picky about some of the CSS rules, for exmaple it MUST be positioned absolute, otherwise PDFJS generates the pages as 0px height.
I don't see PDFViewer or PDFLinkService in your code. It looks like you are trying to build the entire viewer from scratch yourself. This is no small endeavor. When you get loadingTask working correctly the response should be handled something like this:
loadingTask.promise.then(
// Success function.
function( doc ) {
// viewer is holding: new pdfjsViewer.PDFViewer()
// linkService is: new pdfjsViewer.PDFLinkService()
viewer.setDocument( doc );
linkService.setDocument( doc );
},
// Error function.
function( exception ) {
// What type of error occurred?
if ( exception.name == 'PasswordException' ) {
// Password missing, prompt the user and try again.
elem.appendChild( getPdfPasswordBox() );
} else {
// Some other error, stop trying to load this PDF.
console.error( exception );
}
/**
* Additional exceptions can be reversed engineered from here:
* https://github.com/mozilla/pdf.js/blob/master/examples/mobile-viewer/viewer.js
*/
}
);
Notice that PDFViewer does all the hard work for you. PDFLinkService is needed if you want links in the PDF to work. You really should checkout the live demo and the example files.
Its a lot of work but these example files specifically can teach you all you need to know about PDFJS.
Example / Sample Code
Here is some sample code from a project I did with PDFJS. The code is a bit advanced but it should help you reverse engineer how PDFJS is working under the hood a bit better.
pdfObj = An object to store all the info and objects for this PDF file. I load multiple PDFs on a single page so I need this to keep them separate from each other.
updatePageInfo = My custome function that is called by PDFJS's eventBus when the user changes pages in the PDF; this happens as they scroll from page to page.
pdfjsViewer.DownloadManager = I allow users to download the PDFs so I need to use this.
pdfjsViewer.EventBus = Handles events like loading, page changing, and so on for the PDF. I am not 100% certain but I think the PDFViewer requires this.
pdfjsViewer.PDFViewer = What handles actually showing your PDF to users. container is the element on the page to render in, remember it must be positioned absolute.
// Create a new PDF object for this PDF.
var pdfObj = {
'container': elem.querySelector('.pdf-view-wrapper'),
'document': null,
'download': new pdfjsViewer.DownloadManager(),
'eventBus': new pdfjsViewer.EventBus(),
'history': null,
'id': id,
'linkService': null,
'loaded': 0,
'loader': null,
'pageTotal': 0,
'src': elem.dataset.pdf,
'timeoutCount': 0,
'viewer': null
};
// Update the eventBus to dispatch page change events to our own function.
pdfObj.eventBus.on( 'pagechanging', function pagechange(evt) {
updatePageInfo( evt );
} );
// Create and attach the PDFLinkService that handles links and navigation in the viewer.
var linkService = new pdfjsViewer.PDFLinkService( {
'eventBus': pdfObj.eventBus,
'externalLinkEnabled': true,
'externalLinkRel': 'noopener noreferrer nofollow',
'externalLinkTarget': 2 // Blank
} );
pdfObj.linkService = linkService;
// Create the actual PDFViewer that shows the PDF to the user.
var pdfViewer = new pdfjsViewer.PDFViewer(
{
'container': pdfObj.container,
'enableScripting': false, // Block embeded scripts for security
'enableWebGL': true,
'eventBus': pdfObj.eventBus,
'linkService': pdfObj.linkService,
'renderInteractiveForms': true, // Allow form fields to be editable
'textLayerMode': 2
}
);
pdfObj.viewer = pdfViewer;
pdfObj.linkService.setViewer( pdfObj.viewer );

Is there a way to include images that are of "mp4" and "webM" format from an api call?

Good morning everyone!
I'm currently accessing an API to display a random image of dogs. Now, it's working; however, the function only shows the images that are ".gif" or ".img" format. If the images are of ".mp4" or "WebM" format, then the feature won't display the image.
I've tried to create an if statement that will allow me to access the ".mp4" and ".WebM" images, should they appear. In theory, it works. I've used .split to access the last part of the file, whether it's ".mp4" or "WebM," however, no changes are being made in comparison to what I initially need for it to do, (which is to display the image, regardless of its file type). The code that I'm posting is as far as I've managed to get in regards to progress. I'm stuck on how to proceed forward with it.
const userAction = async () => {
const response = await fetch('https://random.dog/woof.json');
const myJson = await response.json();
return myJson.url
};
function button() {
document.getElementById('btn').onclick = async function () {
const src = await userAction();
const img = document.createElement('img');
img.src = src;
img.width = 500;
img.height = 500;
img.alt = "doggo";
img.id = 'doggo_image';
let pieces = src.split(".");
// Need to figure this part out
if (pieces[pieces.length-1] === "mp4" || pieces[pieces.length-1] === "webM") {
let video = document.createElement("video");
document.body.append(video);
} else {
}
const current_image = document.getElementById(img.id);
if (current_image) {
document.body.replaceChild(img, current_image);
} else {
document.body.appendChild(img);
}
};
}
I'm expecting for the code to print the image if it's mp4, webM, or img. Right now, it's currently only printing img files from the api.
You are not associating the video element with the source of the video.
So before appending the element to the DOM, you need to add the src:
let video = document.createElement("video");
video.src = src;
document.body.append(video);

Google Chromecast subtitle not working

I have this code
var englishSubtitle = new chrome.cast.media.Track(2,chrome.cast.media.TrackType.TEXT);
englishSubtitle.trackContentId = 'english.vtt';
englishSubtitle.trackContentType = 'text/vtt';
englishSubtitle.subtype = chrome.cast.media.TextTrackType.CAPTIONS;
englishSubtitle.name = 'English';
englishSubtitle.language = 'en-US';
englishSubtitle.customData = null;
var tracks = englishSubtitle;
var mediaInfo = new chrome.cast.media.MediaInfo(app.streamState_.manifest);
mediaInfo.contentType = app.streamState_.type;
mediaInfo.metadata = new chrome.cast.media.GenericMediaMetadata();
mediaInfo.customData = null;
mediaInfo.streamType = chrome.cast.media.StreamType.BUFFERED;
mediaInfo.textTrackStyle = new chrome.cast.media.TextTrackStyle();
mediaInfo.tracks = tracks;
mediaInfo.metadata.metadataType = chrome.cast.media.MetadataType.GENERIC;
var activeTrackIds = [2];
var request = new chrome.cast.media.LoadRequest(mediaInfo);
request.autoplay = true;
request.currentTime = 0;
request.activeTrackIds = activeTrackIds;
session.loadMedia(request,onMediaDiscovered.bind( this, 'loadedMedia'), onMediaError);
I want to show subtitle on chromecast. When I want to set activeTracks on the request, I receive an error
Object {code: "session_error", description: "INVALID_PARAMS", details: Object}
The subtitle it doesn't show and the video doesn't play it at all, because of that error.
Am I doing something wrong?
tracks should be an array when you set
mediaInfo.tracks = tracks;
In your case, you should try
var tracks = [englishSubtitle];
and as was said earlier, use SUBTITLES instead of CAPTIONS. Finally make sure you have CORS headers present from your web server even if you are using mp4.
tracks should be stored inside an array
https://developers.google.com/cast/docs/reference/chrome/chrome.cast.media.MediaInfo#tracks
Array of non-null chrome.cast.media.Track
Array of Track objects.
mediaInfo.tracks = [englishSubtitle, frenchSubtitle, germanSubtitle]
I've created a simple javascript wrapper for the chromecast SDK:
https://github.com/Fenny/ChromecastJS
Might be worth to check out if you stumble upon more problems, good luck!

Nativescript get base64 data from native image

I try to use https://github.com/bradmartin/nativescript-drawingpad for saving a signature to my backend. But I am simply not capable to find a solution to get some "useful" data from getDrawing(), which returns a native image Object, for example UIImage on iOS.
I would love to "convert" the image data to some base64 (png, or whatever) string and send it to my server.
I tried someting like:
var ImageModule = require("ui/image");
var ImageSourceModule = require("image-source");
elements.drawingpad.getDrawing().then(function(a){
var image = ImageSourceModule.fromNativeSource( a );
api.post("sign", image.toBase64String());
});
I also tried to post simply a like seen in the demo stuff.
I would really love to see a demo of how to get my hands on the "image data" itself.
thanks!
Thanks to #bradmartin I found the solution:
var image = ImageSourceModule.fromNativeSource(a);
var base64 = image.toBase64String('png');
Actually after lots of digging with tons of error, I finally figured it out.
First you have to require the nativescript-imagepicker source module and also the nativescript image source.
var imagepicker = require("nativescript-imagepicker");
var ImageSourceModule = require("tns-core-modules/image-source");
a case where you want to update a user profile and also send a base64 string to your backend for processing
function changeProfileImage(args) {
var page = args.object;
var profile = page.getViewById("profile-avatar");
var context = imagepicker.create({ mode: "single" });
context.authorize().then(function() {
return context.present();
}).then(function(selection) {
profile.background = `url(${selection[0]._android})`;
profile.backgroundRepeat = `no-repeat`;
profile.backgroundSize = `cover`;
ImageSourceModule.fromAsset(selection[0]).then(image => {
var base64 = image.toBase64String('png');
// console.log(base64);
uploadMediaFile(base64);
});
}).catch(function (e) {
// process error
console.log(e);
});
}

Categories