mirror of
https://github.com/node-red/node-red-nodes.git
synced 2023-10-10 13:36:58 +02:00
add worldmap features to exif node.
field of view, popup, filename, icon, etc.
This commit is contained in:
parent
9e948b9fdf
commit
466b1c3deb
@ -40,22 +40,22 @@
|
||||
"grunt-lint-inline": "^1.0.0",
|
||||
"grunt-simple-mocha": "^0.4.1",
|
||||
"imap": "^0.8.19",
|
||||
"mailparser": "^3.0.0",
|
||||
"mailparser": "~3.0.1",
|
||||
"markdown-it": "^11.0.0",
|
||||
"mocha": "~6.2.3",
|
||||
"msgpack-lite": "^0.1.26",
|
||||
"multilang-sentiment": "^1.2.0",
|
||||
"ngeohash": "^0.6.3",
|
||||
"node-red": "^1.1.3",
|
||||
"node-red": "~1.2.6",
|
||||
"node-red-node-test-helper": "~0.2.5",
|
||||
"nodemailer": "^6.4.10",
|
||||
"nodemailer": "~6.4.16",
|
||||
"poplib": "^0.1.7",
|
||||
"proxyquire": "^2.1.3",
|
||||
"pushbullet": "^2.4.0",
|
||||
"sentiment": "^2.1.0",
|
||||
"should": "^13.2.3",
|
||||
"sinon": "~7.5.0",
|
||||
"smtp-server": "^3.7.0",
|
||||
"smtp-server": "~3.8.0",
|
||||
"supertest": "^4.0.2",
|
||||
"when": "^3.7.8"
|
||||
},
|
||||
|
@ -26,7 +26,7 @@ describe('exif node', function() {
|
||||
//var data = fs.readFileSync("test/utility/exif/exif_test_image.jpg", null); // extracting genuine exif data to be fed back as the result of the stubbed ExifImage constructor
|
||||
//var data = fs.readFileSync("exif_test_image.jpg", null); // extracting genuine exif data to be fed back as the result of the stubbed ExifImage constructor
|
||||
var flow = [{id:"exifNode1", type:"exif", wires:[["helperNode1"]]},
|
||||
{id:"helperNode1", type:"helper"}];
|
||||
{id:"helperNode1", type:"helper"}];
|
||||
|
||||
var gpsmsg = { gps: { GPSLatitudeRef: 'N',
|
||||
GPSLatitude: [ 50, 57, 22.4697 ],
|
||||
@ -65,7 +65,7 @@ describe('exif node', function() {
|
||||
//var data = fs.readFileSync("test/utility/exif/exif_test_image.jpg", null); // extracting genuine exif data to be fed back as the result of the stubbed ExifImage constructor
|
||||
//var data = fs.readFileSync("exif_test_image.jpg", null); // extracting genuine exif data to be fed back as the result of the stubbed ExifImage constructor
|
||||
var flow = [{id:"exifNode1", type:"exif", wires:[["helperNode1"]]},
|
||||
{id:"helperNode1", type:"helper"}];
|
||||
{id:"helperNode1", type:"helper"}];
|
||||
|
||||
var gpsmsg = { gps: { GPSLatitudeRef: 'S',
|
||||
GPSLatitude: [ 50, 57, 22.4697 ],
|
||||
@ -101,7 +101,7 @@ describe('exif node', function() {
|
||||
var data = new Buffer.from("hello");
|
||||
var eD;
|
||||
var flow = [{id:"exifNode1", type:"exif", wires:[["helperNode1"]]},
|
||||
{id:"helperNode1", type:"helper"}];
|
||||
{id:"helperNode1", type:"helper"}];
|
||||
|
||||
helper.load(exifNode, flow, function() {
|
||||
var exifNode1 = helper.getNode("exifNode1");
|
||||
@ -127,7 +127,7 @@ describe('exif node', function() {
|
||||
var data = "hello";
|
||||
var eD;
|
||||
var flow = [{id:"exifNode1", type:"exif", wires:[["helperNode1"]]},
|
||||
{id:"helperNode1", type:"helper"}];
|
||||
{id:"helperNode1", type:"helper"}];
|
||||
|
||||
helper.load(exifNode, flow, function() {
|
||||
var exifNode1 = helper.getNode("exifNode1");
|
||||
@ -153,7 +153,7 @@ describe('exif node', function() {
|
||||
var data = new Buffer.from("hello");
|
||||
var eD;
|
||||
var flow = [{id:"exifNode1", type:"exif", wires:[["helperNode1"]]},
|
||||
{id:"helperNode1", type:"helper"}];
|
||||
{id:"helperNode1", type:"helper"}];
|
||||
|
||||
helper.load(exifNode, flow, function() {
|
||||
var exifNode1 = helper.getNode("exifNode1");
|
||||
@ -179,7 +179,7 @@ describe('exif node', function() {
|
||||
var data = new Buffer.from("hello");
|
||||
var eD;
|
||||
var flow = [{id:"exifNode1", type:"exif", wires:[["helperNode1"]]},
|
||||
{id:"helperNode1", type:"helper"}];
|
||||
{id:"helperNode1", type:"helper"}];
|
||||
|
||||
var gpsmsg = { gps: { GPSLatitudeRef: 'N',
|
||||
GPSLatitude: [ 50, 57 ],
|
||||
@ -219,7 +219,7 @@ describe('exif node', function() {
|
||||
var data = new Buffer.from("hello");
|
||||
var eD;
|
||||
var flow = [{id:"exifNode1", type:"exif", wires:[["helperNode1"]]},
|
||||
{id:"helperNode1", type:"helper"}];
|
||||
{id:"helperNode1", type:"helper"}];
|
||||
|
||||
var gpsmsg = { gps: { GPSLatitudeRef: 'N',
|
||||
GPSLatitude: [ 50, 57, 1.3 ],
|
||||
@ -259,7 +259,7 @@ describe('exif node', function() {
|
||||
var data = new Buffer.from("hello");
|
||||
var eD;
|
||||
var flow = [{id:"exifNode1", type:"exif", wires:[["helperNode1"]]},
|
||||
{id:"helperNode1", type:"helper"}];
|
||||
{id:"helperNode1", type:"helper"}];
|
||||
|
||||
var gpsmsg = { gps: { GPSLatitudeRef: 'N',
|
||||
GPSLatitude: [ 50, 57, 1.3 ],
|
||||
@ -291,6 +291,4 @@ describe('exif node', function() {
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
||||
});
|
||||
|
@ -1,17 +1,22 @@
|
||||
|
||||
<script type="text/x-red" data-template-name="exif">
|
||||
<script type="text/html" data-template-name="exif">
|
||||
<div class="form-row">
|
||||
<label for="node-input-property"><i class="fa fa-ellipsis-h"></i> <span data-i18n="node-red:common.label.property"></span></label>
|
||||
<input type="text" id="node-input-property" style="width:70%;"/>
|
||||
</div>
|
||||
<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">
|
||||
<script type="text/html" 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,
|
||||
<p>This node expects an incoming JPEG image buffer in the selected property. If Exif data is present,
|
||||
it extracts the data into the <code>msg.exif</code> object.</p>
|
||||
<p>The node then adds location data as <code>msg.location</code>, should the Exif data carry this information.
|
||||
<code>msg.payload</code> remains the original, unmodified image buffer. </p>
|
||||
This also includes an icon, bearing and field of view arc suitable for use in the worldmap node.
|
||||
The selected input property retains the original, unmodified image buffer.</p>
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
@ -19,7 +24,8 @@
|
||||
category: 'utility',
|
||||
color:"#f1c2f0",
|
||||
defaults: {
|
||||
name: {value:""}
|
||||
name: {value:""},
|
||||
property: {value:"payload",required:true}
|
||||
},
|
||||
inputs:1,
|
||||
outputs:1,
|
||||
@ -29,6 +35,10 @@
|
||||
},
|
||||
labelStyle: function() {
|
||||
return this.name?"node_label_italic":"";
|
||||
},
|
||||
oneditprepare: function() {
|
||||
if (this.property === undefined) { $("#node-input-property").val("payload"); }
|
||||
$("#node-input-property").typedInput({default:'msg',types:['msg']});
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
@ -11,6 +11,7 @@ module.exports = function(RED) {
|
||||
|
||||
function ExifNode(n) {
|
||||
RED.nodes.createNode(this,n);
|
||||
this.property = n.property || "payload";
|
||||
var node = this;
|
||||
|
||||
/***
|
||||
@ -20,7 +21,7 @@ module.exports = function(RED) {
|
||||
* 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) {
|
||||
function addMsgLocationDataFromExifGPSData(msg,val) {
|
||||
var gpsData = msg.exif.gps; // declaring variable purely to make checks more readable
|
||||
if (gpsData.GPSAltitude) {
|
||||
/* istanbul ignore else */
|
||||
@ -31,14 +32,12 @@ module.exports = function(RED) {
|
||||
// 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; // 5dp is approx 1m resolution...
|
||||
// (N)orth means positive latitude, (S)outh means negative latitude
|
||||
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; // 5dp is approx 1m resolution...
|
||||
// (E)ast means positive longitude, (W)est means negative longitude
|
||||
@ -49,7 +48,6 @@ module.exports = function(RED) {
|
||||
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.");
|
||||
@ -62,13 +60,32 @@ module.exports = function(RED) {
|
||||
else {
|
||||
node.log("The location of this image cannot be determined safely so no location information has been added to the message.");
|
||||
}
|
||||
msg.location.arc = {
|
||||
ranges: [500,1000,2000],
|
||||
pan: gpsData.GPSImgDirection,
|
||||
fov: (2 * Math.atan(36 / (2 * msg.exif.exif.FocalLengthIn35mmFormat)) * 180 / Math.PI),
|
||||
color: '#910000'
|
||||
}
|
||||
msg.location.icon = "fa-camera";
|
||||
var na;
|
||||
if (val.hasOwnProperty("name")) { na = val.name; }
|
||||
else if (msg.hasOwnProperty("filename")) { na = msg.filename.split('/').pop(); }
|
||||
else { na = msg.exif.image.Make+"_"+msg.exif.image.ModifyDate; }
|
||||
msg.location.name = na;
|
||||
msg.location.popup = '<img width="280" src="data:image/jpeg;base64,'+val.toString("base64")+'"/>'
|
||||
}
|
||||
|
||||
this.on("input", function(msg) {
|
||||
try {
|
||||
if (msg.payload) {
|
||||
if (Buffer.isBuffer(msg.payload)) {
|
||||
new ExifImage({ image : msg.payload }, function (error, exifData) {
|
||||
var value = RED.util.getMessageProperty(msg,node.property);
|
||||
if (value !== undefined) {
|
||||
if (typeof value === "string") { // it must be a base64 encoded inline image type
|
||||
if (value.indexOf('data:image') !== -1) {
|
||||
value = new Buffer.from(value.replace(/^data:image\/[a-z]+;base64,/, ""), 'base64');
|
||||
}
|
||||
}
|
||||
if (Buffer.isBuffer(value)) { // or a proper jpg buffer
|
||||
new ExifImage({ image:value }, function (error, exifData) {
|
||||
if (error) {
|
||||
node.log(error.toString());
|
||||
}
|
||||
@ -76,7 +93,7 @@ module.exports = function(RED) {
|
||||
if (exifData) {
|
||||
msg.exif = exifData;
|
||||
if ((exifData.hasOwnProperty("gps")) && (Object.keys(exifData.gps).length !== 0)) {
|
||||
addMsgLocationDataFromExifGPSData(msg);
|
||||
addMsgLocationDataFromExifGPSData(msg,value);
|
||||
}
|
||||
//else { node.log("The incoming image did not contain Exif GPS data."); }
|
||||
}
|
||||
@ -93,7 +110,7 @@ module.exports = function(RED) {
|
||||
}
|
||||
}
|
||||
else {
|
||||
node.error("No payload received, the Exif node cannot proceed, no messages sent.",msg);
|
||||
node.warn("No input received, the Exif node cannot proceed, no messages sent.",msg);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -1,23 +1,30 @@
|
||||
{
|
||||
"name" : "node-red-node-exif",
|
||||
"version" : "0.0.7",
|
||||
"description" : "A Node-RED node that extracts Exif information from JPEG image buffers.",
|
||||
"dependencies" : {
|
||||
"exif": "0.4.0"
|
||||
"name": "node-red-node-exif",
|
||||
"version": "0.1.0",
|
||||
"description": "A Node-RED node that extracts Exif information from JPEG image buffers.",
|
||||
"dependencies": {
|
||||
"exif": "^0.6.0"
|
||||
},
|
||||
"repository" : {
|
||||
"type":"git",
|
||||
"url":"https://github.com/node-red/node-red-nodes/tree/master/utility/exif"
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/node-red/node-red-nodes/tree/master/utility/exif"
|
||||
},
|
||||
"license": "Apache-2.0",
|
||||
"keywords": [ "node-red", "exif"],
|
||||
"node-red" : {
|
||||
"nodes" : {
|
||||
"keywords": [
|
||||
"node-red",
|
||||
"exif"
|
||||
],
|
||||
"node-red": {
|
||||
"nodes": {
|
||||
"exif": "94-exif.js"
|
||||
}
|
||||
},
|
||||
"contributors": [
|
||||
{"name": "Dave Conway-Jones"},
|
||||
{"name": "Zoltan Balogh"}
|
||||
{
|
||||
"name": "Dave Conway-Jones"
|
||||
},
|
||||
{
|
||||
"name": "Zoltan Balogh"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user