mirror of
				https://github.com/node-red/node-red-nodes.git
				synced 2025-03-01 10:37:43 +00:00 
			
		
		
		
	Adding Exif node.
This commit is contained in:
		
							
								
								
									
										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"}
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user