Dashboard: Image from msg.payload

Well, in fact it also works directly as message.payload without going over httpStatic:

[{"id":"c6754549.347f68","type":"http request","z":"7fe54cbf.cae6f4","name":"","method":"GET","ret":"bin","url":"http://192.168.178.26/api/camera/snapshot?width=640&height=480","tls":"","x":450,"y":1380,"wires":[["5f78329e.cd691c"]]},{"id":"437fc727.cdf9","type":"inject","z":"7fe54cbf.cae6f4","name":"","topic":"","payload":"","payloadType":"date","repeat":"1","crontab":"","once":true,"onceDelay":0.1,"x":250,"y":1380,"wires":[["c6754549.347f68","d6c27a92.f5bf9"]]},{"id":"d6c27a92.f5bf9","type":"function","z":"7fe54cbf.cae6f4","name":"update url with timestamp","func":"msg.payload = \"http://192.168.178.26/api/camera/snapshot?width=640&height=480\";\nmsg.payload += \"&ts=\"+Date.now();\nreturn msg;","outputs":1,"noerr":0,"x":490,"y":1460,"wires":[["6462c90a.d9c05"]]},{"id":"dd96885d.deea8","type":"ui_template","z":"7fe54cbf.cae6f4","group":"1e7ba558.772a6b","name":"Test 1","order":0,"width":"6","height":"6","format":"<img ng-src=\"{{msg.payload}}\"/>","storeOutMessages":true,"fwdInMessages":true,"templateScope":"local","x":870,"y":1380,"wires":[[]]},{"id":"5f78329e.cd691c","type":"function","z":"7fe54cbf.cae6f4","name":"jpg encode buffer","func":"var getImageResult = msg.payload;\nvar b64encoded = getImageResult.toString('base64');\nmsg.payload = \"data:image/jpg;base64,\" + b64encoded;\nreturn msg;","outputs":1,"noerr":0,"x":680,"y":1380,"wires":[["dd96885d.deea8","58e2d2d1.0e3c24"]]},{"id":"6462c90a.d9c05","type":"ui_template","z":"7fe54cbf.cae6f4","group":"a220643f.3ad73","name":"Test 3","order":0,"width":"6","height":"6","format":"\n<img ng-src={{msg.payload}} height=\"42\" width=\"42\" />","storeOutMessages":true,"fwdInMessages":true,"templateScope":"local","x":870,"y":1460,"wires":[[]]},{"id":"58e2d2d1.0e3c24","type":"ui_template","z":"7fe54cbf.cae6f4","group":"9944e55d.cbab48","name":"Test 2","order":0,"width":"6","height":"6","format":"<script>\n(function(scope) {\n scope.$watch('msg.payload', function(data) {\n imageObj.src=data;\n });\n}(scope));\n\nvar canvas = document.getElementById('myCanvas');\nvar context = canvas.getContext('2d');\ncanvas.width = window.innerWidth;\ncanvas.height = window.innerHeight;\nvar imageObj = new Image();\nimageObj.onload= function() {\n var wRatio = canvas.width / imageObj.width;\n var hRatio = canvas.height / imageObj.height;\n console.log(imageObj.height);\n var ratio = Math.min(wRatio, hRatio);\n context.drawImage(imageObj, 0, 0, canvas.width, canvas.height, 0, 0, (imageObj.width*ratio), (imageObj.height*ratio));\n};\n</script> \n\n<canvas id=\"myCanvas\"></canvas>","storeOutMessages":true,"fwdInMessages":true,"templateScope":"local","x":870,"y":1420,"wires":[[]]},{"id":"1e7ba558.772a6b","type":"ui_group","z":"","name":"Test1","tab":"ea722d0f.98c548","disp":true,"width":"6","collapse":false},{"id":"a220643f.3ad73","type":"ui_group","z":"","name":"Test3","tab":"ea722d0f.98c548","disp":true,"width":"6","collapse":false},{"id":"9944e55d.cbab48","type":"ui_group","z":"","name":"Test2","tab":"ea722d0f.98c548","disp":true,"width":"6","collapse":false},{"id":"ea722d0f.98c548","type":"ui_tab","z":"","name":"Home","icon":"dashboard","order":1}]

The only thing I'm currently still struggling with is the correct sizing of the image while retaining the aspect ratio.

Is there a way to determine height and width of a template group? I would need something like window.innerWidth for the group.