mirror of
				https://github.com/node-red/node-red-nodes.git
				synced 2025-03-01 10:37:43 +00:00 
			
		
		
		
	add worldmap features to exif node.
field of view, popup, filename, icon, etc.
This commit is contained in:
		| @@ -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" | ||||
|     }, | ||||
|   | ||||
| @@ -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" | ||||
|         } | ||||
|     ] | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user