Exif.js always returns "undefined" - javascript

I'm currently developing a simple WEB Application that allows users to upload a photo.
That photo's EXIF GPS data is then supposed to be extracted to a variable that will then be used in a google maps widget, with a "pin" on the location of shooting. The idea is then generate a link for users to be able to share both the photo and the google maps widget on Forums.
The issue at the moment is in the use of the EXIF.js library.
I currently have a simple html page just to test/try this such library and the code is:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>EXIF</title>
</head>
<body>
<img src="image1.jpg" id="img1" />
<h1>Localização da foto</h1>
<p id="info_model"></p>
<script src="exif.js"></script>
<script>
window.onload=getExif;
function getExif() {
var imagem = document.getElementById("img1");
var modelo = EXIF.getTag(imagem, "Model");
document.getElementById("info_model").innerHTML = modelo;
}
</script>
</body>
</html>
The expected result should be for it to say: "iPhone 6S Plus"
The actual result is: "undefined"
I can confirm the photo used to test the code does in fact have valid EXIF
New code as suggested:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>EXIF</title>
</head>
<body>
<img src="image1.jpg" id="img1" />
<h1>Modelo da câmara</h1>
<p id="info_model"></p>
<script src="exif.js"></script>
<script>
window.onload=getExif;
function getExif() {
var img1 = document.getElementById("img1");
EXIF.getData(img1, function() {
var model = EXIF.getTag(this, "Model");
var modelo = document.getElementById("info_model");
modelo.innerHTML = `${model}`;
});
}
</script>
</body>
</html>

getData works asynchronously and as such, needs to be passed a callback function, which your code does not have. You can only call getTag after you've called getData.
See the example on
https://github.com/exif-js/exif-js
Start with calling the EXIF.getData function. You pass it an image as a parameter:
either an image from a <img src="image.jpg">
OR a user selected image in a <input type="file"> element on your page.
function getExif() {
var img1 = document.getElementById("img1");
EXIF.getData(img1, function() {
var make = EXIF.getTag(this, "Make");
var model = EXIF.getTag(this, "Model");
var makeAndModel = document.getElementById("makeAndModel");
makeAndModel.innerHTML = `${make} ${model}`;
});
}
window.onload = getExif;
<script src="https://cdn.jsdelivr.net/npm/exif-js"></script>
<pre>Make and model: <span id="makeAndModel"></span></pre>
<img src="path/to/image.jpg" id="img1" />

I know this may be already solved, but I'd like to offer alternative solution using library exifr. It's new, maintained and actively developed library with focus on performance.
<img src="image1.jpg" id="img1" />
<h1>Modelo da câmara</h1>
<p id="info_model"></p>
<script src="https://unpkg.com/exifr#2.1.3/index.js"></script>
<script>
async function getExif() {
var img1 = document.getElementById("img1");
let output = await exifr.parse(img)
var model = EXIF.getTag(this, "Model");
var modelo = document.getElementById("info_model");
modelo.innerHTML = output.Model;
}
</script>
The important part here is the async/await. The image is loaded asynchronously so you need to wait until it's loaded and parsed. This is similar to above mentioned callbacks but more modern.
You can check out the library's playground and experiment with images and their output, or check out the .repository and docs

Related

How can I use JavaScript to view the source code of all websites?

I want to have JavaScript to get a user's URL and return the source code of the website. I want to have this to essentially make an iframe, but with the actual code.
E.g. :
let userUrl = prompt("What website do you want displayed?","e.g. https://www.google.com");
function getSource(url){
//some code
return pageSource;
}
document.body.innerHtml=getSource(userUrl);
I tried to scrape a view page source website and turn it into an API that I could inject into JavaScript, but I had no luck.
<html>
<head><meta charset="us-ascii">
<title></title>
<script>
let userUrl = prompt("What website do you want displayed?","e.g.
https://www.google.com");
if (userUrl){
var srcFrame=""; //complete page code to inject into your iframe or return
var fetchMe = "https://example.com?q=" + userUrl;
fetch(fetchMe).then((response) => response.text()).then((text) => {
srcFrame = text;
//if injecting into iframe
myFrame.document.open();
myFrame.document.write(srcFrame);
myFrame.document.close();
// USE THE FOLLOWING TO ADD THE ORIGINAL URL AS THE baseURI SO RELATIVE
//LINKS & SCRIPTS WILL WORK AND ACCESS THE ORIGINAL SOURCE AND NOT YOUR
//SERVER
var addOrigBase= document.createElement('base');
addOrigBase.setAttribute('href',userUrl);
document.getElementById("myFrame").contentDocument.head.appendChild(addOrigBase);
});
};
</script>
</head>
<body>
<iframe onload="myFrame.frameElement.height =
(myFrame.frameElement.contentDocument.body.clientHeight)+10" frameborder=""
height="25px" id="myFrame" name="myFrame" scrolling="no" src="about:blank"
width="100%"></iframe>
</body>
</html>

Trying to use EXIF.js to return GPS coords when a jpg image is clicked

I'm trying to add javascript functionality that will return gps coordinates from exif data when the user clicks on a jpg displayed on the page. (Will use that to open a google map). I have managed to produce a working example when the script is inline in the html file, but not when trying to use a separate script file, getCoords.js
Found a similar question here: How to pass images from server to function in JavaScript?
What I'm trying to do is pass the src attribute from the html click event into the script. The script is getting the src, I can print that to the console and launch the jpg in devtools by clicking on the link in the console. But it doesn't seem to be even trying to run
EXIF.getData(my_image, function() {...
Here's the HTML:
<html lang="en">
<head>
<title>Map Test Home</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="styles.css" rel="stylesheet">
<script src="getCoords.js"></script>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/exif-js/2.3.0/exif.min.js">
</script>
<script
src="https://maps.googleapis.com/maps/api/js?key=AIzaSyBMLVQ6kCIfX4c8vVHa0qOf8P87DxCvt2w">
</script>
</head>
<body>
<picture>
<source media="(min-width: 750px)" srcset="images/van_from_erp2_L.jpg 2x, images/van_from_erp2_m.jpg 1x" />
<source media="(min-width: 450px)" srcset="images/van_from_erp2_m.jpg" />
<img src="images/van_from_erp2_s.jpg" id="hiking_0" alt="View of Vancouver from ridge" onclick='getCoords(src)'>
</picture>
<picture>
<source media="(min-width: 750px)" srcset="images/creek_1_l.jpg 2x, images/creek_1_m.jpg 1x" />
<source media="(min-width: 450px)" srcset="images/creek_1_m.jpg" />
<img src="images/creek_1_s.jpg" id="hiking_1" alt="forest creek image" onclick='Hello(id)'>
</picture>
<!--div id="map"></div-->
</body>
</html>
and here's the script:
function getCoords(source) {
console.log(source);
//pass image to EXIF.js to return EXIF data (EXIF.js sourced from github)
let my_image = new Image();
my_image.src = source;
console.log("hello from line 7");
EXIF.getData(my_image, function() {
console.log("Hello from line 9");
myData = this;
console.log(myData.exifdata);
// get latitude from exif data and calculate latitude decimal
var latDegree = myData.exifdata.GPSLatitude[0].numerator;
var latMinute = myData.exifdata.GPSLatitude[1].numerator;
var latSecond = myData.exifdata.GPSLatitude[2].numerator;
var latDirection = myData.exifdata.GPSLatitudeRef;
var latFinal = ConvertDMSToDD(latDegree, latMinute, latSecond, latDirection);
//console.log(latFinal);
// get longitude from exif data and calculate longitude decimal
var lonDegree = myData.exifdata.GPSLongitude[0].numerator;
var lonMinute = myData.exifdata.GPSLongitude[1].numerator;
var lonSecond = myData.exifdata.GPSLongitude[2].numerator;
var lonDirection = myData.exifdata.GPSLongitudeRef;
var lonFinal = ConvertDMSToDD(lonDegree, lonMinute, lonSecond, lonDirection);
//console.log(lonFinal);
let site = [latFinal, lonFinal];
console.log(site);
return(site);
// Create Google Maps link for the location
//document.getElementById('map-link').innerHTML = 'Google Maps';
});
//};
function ConvertDMSToDD(degrees, minutes, seconds, direction) {
var dd = degrees + (minutes/60) + (seconds/360000);
if (direction == "S" || direction == "W") {
dd = dd * -1;
}
return dd;
}
}
Put EXIF.getData(my_image, function() {...} inside the image onload function:
my_image.onload = function() {
EXIF.getData(my_image, function() {...}
}
Note that you have to wait for the image to be completely loaded,
before calling getData or any other function. It will silently fail
otherwise. Docs

Calling .jSignature() on div doesn't update the div

I got this code from the GitHub:
<script src="path/to/jSignature.min.js"></script>
<script>
$(document).ready(function() {
$("#signature").jSignature()
})
</script>
<div id="signature"></div>
But it doesn't pull anything up on the actual webpage. I would think there is more code required but I don't know where to start.
Here is a minimal working example
<!DOCTYPE html>
<html lang="en">
<head>
<lang>
<title>Minimal working jSignature Example</title>
<meta charset="UTF-8">
<!-- Files from the origin -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script src="https://willowsystems.github.io/jSignature/js/libs/jSignature.min.js"></script>
<head>
<script>
$(document).ready(function() {
// Initialize jSignature
$("#signature").jSignature();
})
// ripped from the description at their the Github page
function getBase64Sig(){
// get the element where the signature have been put
var $sigdiv = $("#signature");
// get a base64 URL for a SVG picture
var data = $sigdiv.jSignature("getData", "svgbase64");
// build the image...
var i = new Image();
i.src = "data:" + data[0] + "," + data[1];
// and put it somewhere where the sun shines brightly upon it.
$(i).appendTo($("#output"));
}
</script>
<body>
Put your signature here:
<div id="signature"></div>
<button onclick="getBase64Sig()">Get Base64</button>
<div id="output"></div>
</body>
</html>
I hope you can go on from here.
It is really as simple as they describe it to be, only their description of the actual example is a bit lacking for beginners.

CamanJS image manipulation, strange error

i'm using CamanJS to do some images manipulation with javascript, and I have two similar really simple scripts, the first works well, the second not (and this is the script i need working).
This is the first working:
<!DOCTYPE html>
<html lang="en">
<head>
<title>CamanJS Testing Playground</title>
<script type="text/javascript" src="caman.full.min.js"></script>
</head>
<body>
<button onclick="filtraPhoto();">MODIFICA</button><br />
<img id="smallImage" />
<script>
var immagine;
var smallImage = document.getElementById('smallImage');
smallImage.src = "test1_600.jpg";
immagine = Caman("#smallImage", function () {});
function filtraPhoto() {
immagine.brightness(10).contrast(500).render(function () {
alert("Done!");
});
}
</script>
</body>
</html>
This is the second not working, it return in firebug the error: TypeError: this.c.pixelData is undefined
<!DOCTYPE html>
<html lang="en">
<head>
<title>CamanJS Testing Playground</title>
<script type="text/javascript" src="caman.full.min.js"></script>
<script>
var immagine;
function carica()
{
var smallImage = document.getElementById('smallImage');
smallImage.src = "test1_600.jpg";
immagine = Caman("#smallImage", function () {});
}
function filtraPhoto() {
immagine.brightness(10).contrast(500).render(function () {
alert("Done!");
});
}
</script>
</head>
<body>
<button onclick="carica();">carica immagine</button><br />
<button onclick="filtraPhoto();">MODIFICA</button><br />
<img id="smallImage" />
</body>
</html>
Any help please?
It runs just fine in both Firefox and Chrome for me. In my limited experience, this.c.pixelData typically comes when your conversion to a CamanInstance was not successfully created.
This can be because of many things, but one that isn't expected is that CamanJS won't let you use the same html identifier (class or id) for more than one object, even if you've swapped them out. So if you're running the two scripts above on the same page, it will cause errors.
Sorry, without being able to reproduce your error, it's hard to help more than that.

JS Image change won't work under other tags (should be a simple fix)

Hey guys,
basically this is my page and the JS simply changes the images if one is clicked, this works grand if the <img src='worseun.png' name='worse' border='0' /> is first beneath the <body>, but doesn't work if there is another <img src='' /> above it! I'm still learning js and this is a head wreck, can anyone suggest a fix? Heres it working with nothing above
<script type="text/javascript">
function worseChange()
{
var theImga = document.getElementsByTagName('img')[0].src;
var xa = theImga.split("/");
var ta = xa.length-1;
var ya = xa[ta];
if(ya=='worseun.png')
{
document.images.worse.src='worse.png';
document.images.cd.src='cdun.png';
}
}
function cdChange()
{
var theImgb = document.getElementsByTagName('img')[1].src;
var xb = theImgb.split("/");
var tb = xb.length-1;
var yb = xb[tb];
if(yb=='cdun.png')
{
document.images.worse.src='worseun.png';
document.images.cd.src='cd.png';
}
}
</script>
</head>
<body>
<a name=1>Uno</a>
<img src='worseun.png' name='worse' border='0' /> <br />
<img src='cd.png' name='cd' border='0' />
<a name=2>Dos</a>
<body>
Thanks guys,
James
That first line:
var theImga = document.getElementsByTagName('img')[0].src;
means, "get the very first <img> tag in the document, and then fetch its 'src' attribute value." You can instead give the "real" image an "id" value, and use document.getElementById('whatever') to get it.
<img id='worse' src='worseun.png' name='worse' border='0' />
and then
var theImga = document.getElementById('worse').src;

Categories

Resources