You need to sign in to do that
Don't have an account?
Tim Guibord 9
Cannot resize image using canvas in a lightning component with LockerService
We are attempting to resize a image file captured from a mobile device prior to sending to the service to eventually upload to S3. This was working prior to upgrading the component to API veriosn 40.0.
Component markup:
Lightning Controller:
Helper:
When we attempt to draw the image to the Canvas context in the helper, it fails with the message:
"Uncaught TypeError: Failed to execute 'drawImage' on 'CanvasRenderingContext2D': The provided value is not of type '(CSSImageValue or HTMLImageElement or HTMLVideoElement or HTMLCanvasElement or ImageBitmap or OffscreenCanvas)'"
I am assuming the issue is that the Context object cannot unwrap the proxied HTMLImageElement.
Component markup:
<input id="{!v.name}" type="file" accept="image/*" style="display:none" onchange="{!c.setPhoto}" capture="'environment"/>
Lightning Controller:
setPhoto: function (cmp, evt, hlp) { if (evt.currentTarget.files) { var file = evt.currentTarget.files[0]; hlp.callImageSelected(cmp, file); } }
Helper:
callImageSelected: function (cmp, file) { var canvas = document.createElement('canvas'); var ctx = canvas.getContext('2d'); var image = document.createElement('img'); image.onload = function () { var max_size = 600; var width = image.width; var height = image.height; if ((width > height) && (width > max_size)) { height *= max_size / width; width = max_size; } else if (height > max_size) { width *= max_size / height; height = max_size; } canvas.width = width; canvas.height = height; ctx.drawImage(image, 0, 0, width, height); var dataUrl = canvas.toDataURL('image/jpeg'); var imageData = self.dataURLToBlob(dataUrl); var imageSelected = cmp.getEvent('imageSelected'); imageSelected.setParams({ imageData: imageData, imageType: cmp.get('v.imageType') }); imageSelected.fire(); }; image.src = URL.createObjectURL(file); }, dataURLToBlob: function (dataURL) { var BASE64_MARKER = ';base64,'; var parts, contentType, raw; if (dataURL.indexOf(BASE64_MARKER) == -1) { parts = dataURL.split(','); contentType = parts[0].split(':')[1]; raw = parts[1]; return new Blob([raw], {type: contentType}); } parts = dataURL.split(BASE64_MARKER); contentType = parts[0].split(':')[1]; raw = window.atob(parts[1]); var rawLength = raw.length; var uInt8Array = new Uint8Array(rawLength); _.times(rawLength, function (i) { uInt8Array[i] = raw.charCodeAt(i) }); return new Blob([uInt8Array], {type: contentType}); }
When we attempt to draw the image to the Canvas context in the helper, it fails with the message:
"Uncaught TypeError: Failed to execute 'drawImage' on 'CanvasRenderingContext2D': The provided value is not of type '(CSSImageValue or HTMLImageElement or HTMLVideoElement or HTMLCanvasElement or ImageBitmap or OffscreenCanvas)'"
I am assuming the issue is that the Context object cannot unwrap the proxied HTMLImageElement.
solution taken from here: https://developer.salesforce.com/forums/?id=9060G000000UVVfQAO
http://documentation.auraframework.org/lockerApiTest/secureDocument.app?aura.mode=DEV
Both lines 2 and 4 in the helper create a SecureElement (HTMLCanvasElement and HTMLImageElement respectively). I updated the code to log out what is being created:
The resulting log messages: