Write Exif/Metadata to file

Hi,

Has anyone a good solution for writing geotag data to a image file via Node Red? I see there is many good solutions for reading exif data.

Im extracting .jpeg images from a RTSP stream using ffmpeg in a exec node, but I would also like to add metada and geotags to those images after they are created.

If you are using latest node-red, you could import piexifjs

image

Here is a demo that adds a date taken, camera model and GPS coords...

The flow...

[{"id":"5415f454ebdea80d","type":"function","z":"62a0e5a5.fc59bc","name":"","func":"\n/*\nvar filename1 = \"c:/temp/pic1.jpg\";\nvar jpeg = fs.readFileSync(filename1);\nvar data = jpeg.toString(\"binary\");\n*/\n\nvar jpegData = msg.payload;\nvar exifOrig\ntry {\n    exifOrig = piexif.load(jpegData)\n} catch (error) {\n    \n};\n\n//debugger\nvar zeroth = {};\nvar exif = {};\nvar gps = {};\nzeroth[piexif.ImageIFD.Make] = \"RPi\";\nzeroth[piexif.ImageIFD.Model] = \"3b\";\nzeroth[piexif.ImageIFD.Software] = \"node-red\";\n\nexif[piexif.ExifIFD.DateTimeOriginal] = \"2010:10:10 10:10:10\";\nexif[piexif.ExifIFD.ExifVersion] = [1]\nexif[piexif.ExifIFD.LensMake] = \"LensMake\";\nexif[piexif.ExifIFD.Sharpness] = 777;\nexif[piexif.ExifIFD.LensSpecification] = [[1, 1], [1, 1], [1, 1], [1, 1]];\n\ngps[piexif.GPSIFD.GPSVersionID] = [7, 7, 7, 7];\ngps[piexif.GPSIFD.GPSDateStamp] = \"1999:99:99 99:99:99\";\n\nvar lat = 54.998993228419344 ;\nvar lng = -1.4174938201904297;\ngps[piexif.GPSIFD.GPSLatitudeRef] = lat < 0 ? 'S' : 'N';\ngps[piexif.GPSIFD.GPSLatitude] = piexif.GPSHelper.degToDmsRational(lat);\ngps[piexif.GPSIFD.GPSLongitudeRef] = lng < 0 ? 'W' : 'E';\ngps[piexif.GPSIFD.GPSLongitude] = piexif.GPSHelper.degToDmsRational(lng);\n\nvar exifObj = Object.assign({}, exifOrig);\nexifObj[\"0th\"] = Object.assign({}, exifOrig[\"0th\"], zeroth )\nexifObj[\"Exif\"] = Object.assign({}, exifOrig[\"Exif\"], exif )\nexifObj[\"GPS\"] = Object.assign({}, exifOrig[\"GPS\"], gps )\n\n//var exifObj = { \"0th\": zeroth, \"Exif\": exif, \"GPS\": gps };\n\nvar exifStr = piexif.dump(exifObj);\n\nvar jpegDataUpdated = piexif.insert(exifStr, jpegData);\n\nmsg.payload = Buffer.from(jpegDataUpdated, \"binary\");\n\nreturn [msg, { payload: exifOrig }, { payload: exifObj }];","outputs":3,"noerr":0,"initialize":"","finalize":"","libs":[{"var":"piexif","module":"piexifjs"}],"x":780,"y":600,"wires":[["3dd297d64de8d2d2"],["e61fe407cd2de8a1"],["5c38fe17cc056387"]]},{"id":"8e75f2cc120f0e4b","type":"inject","z":"62a0e5a5.fc59bc","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":420,"y":600,"wires":[["2415a6d7db4da43d"]]},{"id":"84fa15419e139892","type":"image viewer","z":"62a0e5a5.fc59bc","name":"","width":160,"data":"payload","dataType":"msg","active":true,"x":1190,"y":580,"wires":[[]]},{"id":"3dd297d64de8d2d2","type":"file","z":"62a0e5a5.fc59bc","name":"","filename":"c:/temp/pic_exif.jpg","appendNewline":false,"createDir":false,"overwriteFile":"true","encoding":"none","x":1010,"y":580,"wires":[["84fa15419e139892"]]},{"id":"2415a6d7db4da43d","type":"file in","z":"62a0e5a5.fc59bc","name":"","filename":"c:/temp/pic1.jpg","format":"utf8","chunk":false,"sendError":false,"encoding":"binary","allProps":false,"x":600,"y":600,"wires":[["5415f454ebdea80d"]]},{"id":"e61fe407cd2de8a1","type":"debug","z":"62a0e5a5.fc59bc","name":"orig exif","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":980,"y":620,"wires":[]},{"id":"5c38fe17cc056387","type":"debug","z":"62a0e5a5.fc59bc","name":"new exif","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":980,"y":660,"wires":[]}]

Checkout the function code ↑ in the flow (use CTRL+I to import the flow)

2 Likes

This was simply spot on! Thanks for the help.

Was skratching my head for a while, but I had to remove piexifjs from the function node I imported and re-instate it, first it threw me this "TypeError: The argument 'path' must be a string or Uint8Array without null bytes".

Works like a charm now.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.