เมื่อเร็วๆ นี้ฉันใช้ html2canvas.js ในการเขียนโปรเจ็กต์ ซึ่งสามารถเข้าใจฟังก์ชันสกรีนช็อตของเพจได้ แต่ฉันพบข้อผิดพลาดมากมาย ดังนั้นฉันจะเขียนเรียงความเพื่อบันทึกไว้
เมื่อใช้ html2canvas คุณอาจประสบปัญหา เช่น สามารถจับภาพได้เฉพาะอินเทอร์เฟซแบบภาพ ภาพหน้าจอไม่มีสีพื้นหลัง และไม่สามารถบันทึกแท็ก svg ได้ ต่อไปนี้เป็นคำอธิบายโดยละเอียด
1. นำเข้า html2canvas.jsไม่จำเป็นต้องพูด สามารถหาได้จาก github: https://github.com/niklasvh/html2canvas
คุณยังสามารถนำเข้าลิงก์ได้โดยตรง: <script src=https://cdn.bootcss.com/html2canvas/0.5.0-beta4/html2canvas.js></script>
นอกจากนี้ยังใช้งานง่ายมาก คุณสามารถค้นหา API ที่ต้องการได้ทางออนไลน์และเพียงใช้ image/png เพื่อสร้างรูปภาพ png
ในหมู่พวกเขา $(#xxx) คือ div ที่คุณต้องการสกัดกั้น สามารถรับผ่าน jquery ได้
html2canvas($(#xxx), { onrendered: function (canvas) { var url = canvas.toDataURL(image/png); window.location.href = url; } });
สำหรับรูปภาพประเภทอื่นๆ เช่น jpg, รูปภาพ/jpeg ฯลฯ คุณสามารถค้นหา API ได้ด้วยตัวเอง
จริงๆ แล้ว ภาพหน้าจอง่ายๆ เสร็จสมบูรณ์แล้วที่นี่ หากอินเทอร์เฟซซับซ้อนกว่านี้เล็กน้อย ข้อผิดพลาดต่างๆ อาจปรากฏขึ้นมาทีละรายการ
2. ปัญหาที่ svg ไม่สามารถดักจับได้เมื่อเราดักจับ div หากมีแท็ก svg ใน div ก็ไม่สามารถดักจับได้ในสถานการณ์ปกติ ตัวอย่างเช่น ถ้าเราดักจับโฟลว์ชาร์ต เราก็จะได้สิ่งนี้:
จะเห็นได้ว่าเส้นของผังงานไม่ถูกดักจับ นั่นคือ svg ไม่ถูกดักจับ วิธีแก้ปัญหาในขณะนี้คือการแปลง svg ให้เป็น canvas แล้วจับภาพหน้าจอ แล้วอัปโหลดโค้ดโดยตรง
แต่ละลูปที่นี่คือการวนซ้ำแท็ก svg ทั้งหมดและแปลงแท็กทั้งหมดเป็นแคนวาส
if (typeof html2canvas !== 'unknown') { //ต่อไปนี้คือการประมวลผลของ svg var nodesToRecover = []; var nodesToRemove = []; (ดัชนีโหนด) { var parentNode = node.parentNode; var svg = node.outerHTML.trim(); var canvas = document.createElement('canvas'); canvas.width = 650; canvas.height = 798; canvg (แคนวาส, svg); if (node.style.position) { canvas.style.position += node.style .position; canvas.style.left += node.style.left; canvas.style.top += node.style.top; } nodesToRecover.push ({ ผู้ปกครอง: parentNode, ลูก: โหนด }); parentNode.appendChild (ผ้าใบ });
จำเป็นต้องใช้ Canvg.js และไฟล์อ้างอิง rgbcolor.js ที่นี่ ซึ่งสามารถดาวน์โหลดได้โดยตรงจากอินเทอร์เน็ตหรือนำเข้าโดยตรง
3. ปัญหาความโปร่งใสของพื้นหลังจริงๆ แล้วนี่เป็นเรื่องง่ายมาก เนื่องจากมีความโปร่งใสโดยค่าเริ่มต้น มีพื้นหลังพารามิเตอร์ใน html2canvas เพื่อเพิ่มสีพื้นหลังดังนี้:
html2canvas(cloneDom, { onrendered: function(canvas) { var url =canvas.toDataURL(image/png); }, พื้นหลัง:#fafafa});4. ปัญหาในการจับภาพเฉพาะส่วนที่มองเห็นได้เท่านั้น
หาก div ที่ต้องถูกดักจับเกินอินเทอร์เฟซ คุณอาจประสบปัญหาการสกัดกั้นที่ไม่สมบูรณ์ ดังที่แสดงในภาพด้านบน มีเพียงครึ่งหนึ่งของเนื้อหา เนื่องจากส่วนที่มองไม่เห็นถูกซ่อนไว้ และ html2canvas ไม่สามารถดักจับได้ DOM ที่ซ่อนอยู่
ดังนั้นวิธีแก้ปัญหาในเวลานี้คือการใช้การโคลนนิ่ง วางสำเนาของส่วนที่จำเป็นต้องดักไว้ที่ด้านล่างของหน้า จากนั้นใช้ html2canvas เพื่อดักจับ div ที่สมบูรณ์ หลังจากการสกัดกั้นเสร็จสิ้น ให้ลบส่วนนี้ของ เนื้อหารหัสที่สมบูรณ์มีดังนี้:
ฟังก์ชั่น showQRCode() { scrollTo(0, 0); //Clone node ค่าเริ่มต้นคือ false นั่นคือแอตทริบิวต์ของเมธอดจะไม่ถูกคัดลอก และ true คือสำเนาทั้งหมด var cloneDom = $(#d1).clone(true); //ตั้งค่าแอตทริบิวต์ z-index ของโหนดที่โคลน ตราบใดที่มันต่ำกว่าโหนดที่ถูกโคลน cloneDom.css({ สีพื้นหลัง: #fafafa ตำแหน่ง: สัมบูรณ์ ด้านบน: 0px ดัชนี z: -1 ความสูง: 798 ความกว้าง: 650 }); if (typeof html2canvas !== 'unknown') { / /ต่อไปนี้คือการประมวลผลของ svg var nodesToRecover = []; var nodesToRemove = []; cloneDom.find('svg');//divReport คือ id ของ dom ที่ต้องถูกดักจับในรูปภาพ svgElem.each(function (index, node) { var parentNode = node.parentNode; var svg = node.outerHTML .trim(); var canvas = document.createElement('canvas'); canvas.width = 650; canvas.height = 798; canvg (ผ้าใบ svg); if (node.style.position) { canvas.style.position += node.style.position; canvas.style.left += node.style.left; .style.top; } nodesToRemove.push ({ parent: parentNode, ลูก: โหนด }); canvas }); parentNode.appendChild(canvas); }); // ผนวกโหนดแบบไดนามิกเข้ากับเนื้อหา $(body).append(cloneDom); html2canvas(cloneDom, { onrendered: function(canvas) { var url =canvas.toDataURL(image/png); window.location.href = url ; cloneDom.remove(); // ล้างเนื้อหาโคลน}, พื้นหลัง:#fafafa });
ขั้นแรกให้โคลน div ที่จะดักจับและตั้งค่าดัชนี z ให้เหลือน้อยที่สุดเพื่อหลีกเลี่ยงไม่ให้อินเทอร์เฟซดูน่าเกลียด จากนั้น svg จะถูกประมวลผล ซึ่งได้รับการวิเคราะห์ข้างต้น ในที่สุด โหนดโคลนก็จะถูกผนวกเข้ากับเนื้อหา
ในการแสดงผลแบบออนเรนเดอร์ เราสามารถใช้ location.href ได้โดยตรงเพื่อข้ามเพื่อดูรูปภาพ บันทึก หรือเขียน url ลงใน src ของ img และแสดงบนอินเทอร์เฟซ เช่น $('#imgId').attr('src ' ,URL);
สุดท้าย รูปภาพที่เพิ่งถ่ายสามารถแสดงบนอินเทอร์เฟซได้:
5. อัปโหลดรูปภาพและบันทึกลงในฐานข้อมูล และรับรูปภาพเพื่อแสดงในอินเทอร์เฟซเมื่อได้รับ URL แล้ว จะต้องอัปโหลดไปยังแบ็กเอนด์ จัดเก็บไว้ในฐานข้อมูล จากนั้นโหลดลงในอินเทอร์เฟซอื่นที่แสดง โดยทั่วไปฉันคุ้นเคยกับการใช้ url เพื่อจัดเก็บเส้นทางรูปภาพแทนการจัดเก็บหยด
เนื่องจากฉันต้องการรับรูปภาพในอินเทอร์เฟซอื่น ฉันจึงจัดเก็บรูปภาพไว้ในไดเร็กทอรีทรัพยากรในระดับเดียวกับ webapp โค้ดจึงเป็นดังนี้:
//จัดเก็บรูปภาพและส่งคืนเส้นทางรูปภาพ BASE64Decoder decoder = new BASE64Decoder(); byte[] b = decoder.decodeBuffer(product.getProPic().substring(data:image/png;base64,.length())); ByteArrayInputStream bais = ByteArrayInputStream ใหม่ (b); BufferedImage bi1 = ImageIO.read (bais); url = user_resource + File.separator + img + File.separator + product_+UUID.randomUUID().toString().replace(-, )+.png; สตริง TotalUrl = System.getProperty(root) + url; ไฟล์ใหม่ (totalUrl); ImageIO.write (bi1, png, w2); product.setProPic (url); //เก็บเส้นทางสัมพัทธ์ของรูปภาพลงในฐานข้อมูล int res = productMapper.insertSelective(product); //เพิ่มลงในฐานข้อมูล
เนื่องจากตรรกะอื่นๆ เกี่ยวข้องอยู่ที่นี่ จึงรวมโค้ดเพียงบางส่วนเท่านั้น
BASE64Decoder ถูกใช้ที่นี่เพื่อจัดเก็บรูปภาพ หลังจากที่เราได้รับรูปภาพแล้ว เราจำเป็นต้องใช้สตริงย่อยเพื่อดักจับเนื้อหาของ data:image/png;base64 เนื่องจากต่อไปนี้คือ URL ของรูปภาพ url.substring(data:image/png;base64,.length())
.
สำหรับเส้นทางนั้น URL ในโค้ดด้านบนคือเนื้อหาที่ฉันเก็บไว้ในฐานข้อมูล และ TotalUrl คือเส้นทางจริงที่จัดเก็บไว้ระหว่างการดำเนินการเขียนจริงของ ImageIO ไดเร็กทอรีรากของโครงการที่ได้รับโดยเมธอด getProperty() กำหนดค่าใน web.xml เนื้อหาต่อไปนี้ จากนั้น System.getProperty(root) สามารถใช้ได้
<!-- กำหนดค่าระบบเพื่อรับไดเรกทอรีรากของโครงการ--><context-param> <param-name>webAppRootKey</param-name> <param-value>root</param-value></context-param ><ผู้ฟัง> <ผู้ฟัง-คลาส> org.springframework.web.util.WebAppRootListener </ผู้ฟัง-คลาส></ผู้ฟัง>
ตอนนี้ URL ของรูปภาพถูกเก็บไว้ในฐานข้อมูล และรูปภาพนั้นถูกเก็บไว้ในไดเร็กทอรีของโปรเจ็กต์ภายใต้ Tomcat
สุดท้ายนี้ หากต้องการรับมันจากอินเทอร์เฟซ เพียงเพิ่มชื่อโปรเจ็กต์ไว้หน้า url ปัจจุบัน < img class =depot-img src =<%=request.getContextPath()%>/`+e.proPic+` >
จากนั้นคุณจะเห็นภาพที่แสดงบนอินเทอร์เฟซ:
ข้างต้นคือเนื้อหาทั้งหมดของบทความนี้ ฉันหวังว่ามันจะเป็นประโยชน์ต่อการศึกษาของทุกคน ฉันหวังว่าทุกคนจะสนับสนุน VeVb Wulin Network