Adding Exif node.

This commit is contained in:
zobalogh 2014-11-04 15:07:32 +00:00
parent 067ece146b
commit ce62e23cf2
3 changed files with 196 additions and 0 deletions

49
utility/exif/94-exif.html Normal file
View File

@ -0,0 +1,49 @@
<!--
Copyright 2014 IBM Corp.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<script type="text/x-red" data-template-name="exif">
<div class="form-row">
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
<input type="text" id="node-input-name" placeholder="Name">
</div>
</script>
<script type="text/x-red" data-help-name="exif">
<p>Extract <a href="http://en.wikipedia.org/wiki/Exchangeable_image_file_format">Exif</a> information from JPEG images.</p>
<p>This node expects an incoming JPEG image buffer. If Exif data is present,
it extracts the data into the <b>msg.exif</b> object.</p>
<p>The node then adds location data as <b>msg.location</b>, should the Exif data carry this information.
<b>msg.payload</b> remains the original, unmodified image buffer. </p>
</script>
<script type="text/javascript">
RED.nodes.registerType('exif',{
category: 'utility',
color:"#f1c2f0",
defaults: {
name: {value:""}
},
inputs:1,
outputs:1,
icon: "watch.png",
label: function() {
return this.name||"exif";
},
labelStyle: function() {
return this.name?"node_label_italic":"";
}
});
</script>

124
utility/exif/94-exif.js Normal file
View File

@ -0,0 +1,124 @@
/**
* Copyright 2014 IBM Corp.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
module.exports = function(RED) {
"use strict";
var ExifImage = require('exif').ExifImage;
function convertDegreesMinutesSecondsToDecimals(degrees, minutes, seconds) {
var result;
result = degrees + (minutes / 60) + (seconds / 3600);
return result;
}
/***
* Extracts GPS location information from Exif data. If enough information is
* provided, convert the Exif data into a pair of single floating point number
* latitude/longitude data pairs. Populates msg.location with these.
* Assumes that the msg object will always have exifData available as msg.exif.
* Assume that the GPS data saved into Exif provides a valid value
*/
function addMsgLocationDataFromExifGPSData(msg) {
if(msg.exif.gps) {
var gpsData = msg.exif.gps; // declaring variable purely to make checks more readable
if(gpsData.GPSAltitude) {
if(!msg.location) {
msg.location = {};
}
msg.location.alt = gpsData.GPSAltitude;
}
if(gpsData.GPSLatitudeRef && gpsData.GPSLatitude && gpsData.GPSLongitudeRef && gpsData.GPSLongitude) { // location can be determined, OK
// The data provided in Exif is in degrees, minutes, seconds, this is to be converted into a single floating point degree
if(gpsData.GPSLatitude.length === 3) { // OK to convert latitude
if(gpsData.GPSLongitude.length === 3) { // OK to convert longitude
var latitude = convertDegreesMinutesSecondsToDecimals(gpsData.GPSLatitude[0], gpsData.GPSLatitude[1], gpsData.GPSLatitude[2]);
latitude = Math.round(latitude * 100000)/100000;
// (N)orth means positive latitude
// (S)outh means negative latitude
// (E)ast means positive longitude
// (W)est means negative longitude
if(gpsData.GPSLatitudeRef.toString() === 'S' || gpsData.GPSLatitudeRef.toString() === 's') {
latitude = latitude * -1;
}
var longitude = convertDegreesMinutesSecondsToDecimals(gpsData.GPSLongitude[0], gpsData.GPSLongitude[1], gpsData.GPSLongitude[2]);
longitude = Math.round(longitude * 100000)/100000;
if(gpsData.GPSLongitudeRef.toString() === 'W' || gpsData.GPSLongitudeRef.toString() === 'w') {
longitude = longitude * -1;
}
if(!msg.location) {
msg.location = {};
}
msg.location.lat = latitude;
msg.location.lon = longitude;
return;
} else {
node.log("Invalid longitude data, no location information has been added to the message.");
}
} else {
node.log("Invalid latitude data, no location information has been added to the message.");
}
} else {
node.log("The location of this image cannot be determined safely so no location information has been added to the message.");
}
} else {
node.log("No location info found in this image.");
}
}
function ExifNode(n) {
RED.nodes.createNode(this,n);
var node = this;
this.on("input", function(msg) {
try {
if(msg.payload) {
var isBuffer = Buffer.isBuffer(msg.payload);
if(isBuffer === true) {
new ExifImage({ image : msg.payload }, function (error, exifData) {
if (error) {
node.error('Failed to extract Exif data from image.');
node.log('Failed to extract Exif data from image. '+ error);
} else {
//msg.payload remains the same buffer
if(exifData) {
msg.exif = exifData;
addMsgLocationDataFromExifGPSData(msg);
} else {
node.warn("The incoming buffer did not contain Exif data, nothing to do. ");
}
}
node.send(msg);
});
} else {
node.error("Invalid payload received, the Exif node cannot proceed, no messages sent.");
return;
}
} else {
node.error("No payload received, the Exif node cannot proceed, no messages sent.");
return;
}
} catch (error) {
node.error("An error occurred while extracting Exif information. Please check the log for details.");
node.log('Error: '+error.message);
return;
}
});
}
RED.nodes.registerType("exif",ExifNode);
}

23
utility/exif/package.json Normal file
View File

@ -0,0 +1,23 @@
{
"name" : "node-red-node-exif",
"version" : "0.0.1",
"description" : "A Node-RED node that extracts Exif information from JPEG image buffers.",
"dependencies" : {
"exif": "0.4.0"
},
"repository" : {
"type":"git",
"url":"https://github.com/node-red/node-red-nodes/tree/master/utility/exif"
},
"license": "Apache-v2.0",
"keywords": [ "node-red", "exif"],
"node-red" : {
"nodes" : {
"exif": "94-exif.js"
}
},
"contributors": [
{"name": "Dave Conway-Jones"},
{"name": "Zoltan Balogh"}
]
}