RLRE
2 years agoOccasional Contributor
How can I get the whole image of a canvas object?
Hello all,
In the web app I am testing, there is a <canvas/> object that displays as image only. The app only displays part of the image because this image is almost always way too big to display. ...
- 2 years ago
First of all: Thanks to rraghvani for the hints that put me on the right track.
Here is commented code with solution:
// File names const fileNameRoot = "C:\\Temp\\Canvas"; const fileNameHtml = fileNameRoot + ".html"; const fileNamePng = fileNameRoot + ".png"; const fileNameJpeg = fileNameRoot + ".jpeg"; const fileNameWebp = fileNameRoot + ".webp"; // get the page objekt - adapt parameters as needed... var pageObj = Sys.Browser(Project.Variables.Browser).Page(Project.Variables.HomePage + "*"); // get the canvas object - we use here a xpath expression. var xPath = "//canvas[contains(@class, 'shapes')]"; // adapt as needed var canvasObj = pageObj.FindChildByXPath(xPath); // following fails to get hidden canvas picture partitions // var pictureCanvas = canvasObj.Picture(0,0,-1,-1,false); ///////// // Get canvas picture using canva native method toDataURL(). See: // https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toDataURL // The return value of toDataURL() is ready to embed in a html page and // contains 'data:image/png;base64' image at the begining var imagePNGAsBase64WithPrefix = canvasObj.toDataURL("image/png", 1.0); // 1.0 not needed // JPEG Contains 'data:image/jpeg;base64,' and so on. var imageJPGAsBase64WithPrefix = canvasObj.toDataURL("image/jpeg", 1.0); // 1.0 == no compression var imageWEBPsBase64WithPrefix = canvasObj.toDataURL("image/webp", 1.0); // we need to dropp prefixes for image file creation const prefixHTML_imagePng = "data:image/png;base64,"; const prefixHTML_imageJpg = "data:image/jpeg;base64,"; const prefixHTML_imageWbp = "data:image/webp;base64,"; // dropp the prefixes var imagePNGAsBase64NoPrefix = aqString.Replace(imagePNGAsBase64WithPrefix, prefixHTML_imagePng, "", false); var imageJPGAsBase64NoPrefix = aqString.Replace(imageJPGAsBase64WithPrefix, prefixHTML_imageJpg, "", false); var imageWEBPsBase64NoPrefix = aqString.Replace(imageWEBPsBase64WithPrefix, prefixHTML_imageWbp, "", false); // Create html file showing the images var oFile = aqFile.OpenTextFile(fileNameHtml, aqFile.faWrite, aqFile.ctANSI, true); oFile.Write("<!DOCTYPE html><html><head><title>Canvas picture as PNG, JPEG and WebPage-Image</title></head><body>"); oFile.Write("<img style='width:100%; height:100%;' src='" + imagePNGAsBase64WithPrefix + "'/>"); oFile.Write("<img style='width:100%; height:100%;' src='" + imageJPGAsBase64WithPrefix + "'/>"); oFile.Write("<img style='width:100%; height:100%;' src='" + imageWEBPsBase64WithPrefix + "'/>"); oFile.Write("</body></html>"); oFile.Close(); // Attach the html file to log Log.Link(fileNameHtml, "HTML-File containing image from canvas only."); ////////////////////////////// // Image file creation // Create png-File directly var ps = dotNET.System_Management_Automation.PowerShell.Create(); var psCmd = "[IO.File]::WriteAllBytes('" + fileNamePng + "',[Convert]::FromBase64String('" + imagePNGAsBase64NoPrefix + "'))"; // log the actual command for fun. Log.Message("Power-Shell command", psCmd); ps.AddScript(psCmd); // 'type' it to PowerShell var results = ps.Invoke(); // Run. // Attach picture file to Log Log.File(fileNamePng, "Canvas picture as PNG."); // Create JPEG-File directly psCmd = "[IO.File]::WriteAllBytes('" + fileNameJpeg + "',[Convert]::FromBase64String('" + imageJPGAsBase64NoPrefix + "'))"; ps.AddScript(psCmd); results = ps.Invoke(); Log.File(fileNameJpeg, "Canvas picture as JPEG"); // Create WEBP-File directly psCmd = "[IO.File]::WriteAllBytes('" + fileNameWebp + "',[Convert]::FromBase64String('" + imageWEBPsBase64NoPrefix + "'))"; ps.AddScript(psCmd); results = ps.Invoke(); Log.File(fileNameWebp, "Canvas picture as WEBP"); /////////////////////////////// // Compare with file from Disk var pictActual = Utils.Picture; pictActual.LoadFromFile(fileNameJpeg); // pictExpected is the name of expected result file (created by first run, for example). var pictExpected = Utils.Picture; pictExpected.LoadFromFile(fileNameRoot + "_Expected.jpeg"); // the comparisson var bRes = pictActual.Compare(pictExpected) if (bRes) { Log.Checkpoint("Canvas picture as expected!"); } else { Log.Error("Canvas picture don't meet expected result"); }
A last remark on the files created: Perhaps we may use toBlob() method instead of toDataUrl() to avoid conversions. (I haven't try it yet.)
Good luck!