mirror of
https://github.com/node-red/node-red-nodes.git
synced 2023-10-10 13:36:58 +02:00
Adding Exif node.
This commit is contained in:
parent
067ece146b
commit
ce62e23cf2
49
utility/exif/94-exif.html
Normal file
49
utility/exif/94-exif.html
Normal 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
124
utility/exif/94-exif.js
Normal 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
23
utility/exif/package.json
Normal 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"}
|
||||
]
|
||||
}
|
Loading…
Reference in New Issue
Block a user