2017-05-05 24 views
0

我想捕獲整個div作爲圖像和保存在本地proof.I已搜索並閱讀了許多關於svg圖像或div的文章圖像。在javascript中捕獲整個div與svg

我已經嘗試了一些js庫for this.But當我嘗試捕獲圖像從div然後一些只捕獲div內容和一些只捕獲svg內容。

s.jpga.jpg

html2canvas(contentDiv, { 
 
    onrendered: function(can) { 
 
     dirty.appendChild(can); 
 
    } 
 
    }); 
 
// first convert your svg to png 
 
exportInlineSVG(svg, function(data, canvas) { 
 
    svg.parentNode.replaceChild(canvas, svg); 
 
    // then call html2canvas 
 
    html2canvas(contentDiv, { 
 
    onrendered: function(can) { 
 
     can.id = 'canvas'; 
 
     clean.appendChild(can); 
 
    } 
 
    }); 
 
}) 
 

 

 
function exportInlineSVG(svg, receiver, params, quality) { 
 
    if (!svg || !svg.nodeName || svg.nodeName !== 'svg') { 
 
    console.error('Wrong arguments : should be \n exportSVG(SVGElement, function([dataURL],[canvasElement]) || IMGElement || CanvasElement [, String_toDataURL_Params, Float_Params_quality])') 
 
    return; 
 
    } 
 

 
    var xlinkNS = "http://www.w3.org/1999/xlink"; 
 
    var clone; 
 
    // This will convert an external image to a dataURL 
 
    var toDataURL = function(image) { 
 

 
    var img = new Image(); 
 
    // CORS workaround, this won't work in IE<11 
 
    // If you are sure you don't need it, remove the next line and the double onerror handler 
 
    // First try with crossorigin set, it should fire an error if not needed 
 
    img.crossOrigin = 'Anonymous'; 
 

 
    img.onload = function() { 
 
     // we should now be able to draw it without tainting the canvas 
 
     var canvas = document.createElement('canvas'); 
 
     var bbox = image.getBBox(); 
 
     canvas.width = bbox.width; 
 
     canvas.height = bbox.height; 
 
     // draw the loaded image 
 
     canvas.getContext('2d').drawImage(this, 0, 0, bbox.width, bbox.height); 
 
     // set our original <image>'s href attribute to the dataURL of our canvas 
 
     image.setAttributeNS(xlinkNS, 'href', canvas.toDataURL()); 
 
     // that was the last one 
 
     if (++encoded === total) exportDoc() 
 
    } 
 

 
    // No CORS set in the response  
 
    img.onerror = function() { 
 
     // save the src 
 
     var oldSrc = this.src; 
 
     // there is an other problem 
 
     this.onerror = function() { 
 
      console.warn('failed to load an image at : ', this.src); 
 
      if (--total === encoded && encoded > 0) exportDoc(); 
 
      } 
 
      // remove the crossorigin attribute 
 
     this.removeAttribute('crossorigin'); 
 
     // retry 
 
     this.src = ''; 
 
     this.src = oldSrc; 
 
     } 
 
     // load our external image into our img 
 
    img.src = image.getAttributeNS(xlinkNS, 'href'); 
 
    } 
 

 
    // The final function that will export our svgNode to our receiver 
 
    var exportDoc = function() { 
 
     // check if our svgNode has width and height properties set to absolute values 
 
     // otherwise, canvas won't be able to draw it 
 
     var bbox = svg.getBBox(); 
 
     // avoid modifying the original one 
 
     clone = svg.cloneNode(true); 
 
     if (svg.width.baseVal.unitType !== 1) clone.setAttribute('width', bbox.width); 
 
     if (svg.height.baseVal.unitType !== 1) clone.setAttribute('height', bbox.height); 
 

 
     parseStyles(); 
 

 
     // serialize our node 
 
     var svgData = (new XMLSerializer()).serializeToString(clone); 
 
     // remember to encode special chars 
 
     var svgURL = 'data:image/svg+xml; charset=utf8, ' + encodeURIComponent(svgData); 
 

 
     var svgImg = new Image(); 
 

 
     svgImg.onload = function() { 
 
     // if we set a canvas as receiver, then use it 
 
     // otherwise create a new one 
 
     var canvas = (receiver && receiver.nodeName === 'CANVAS') ? receiver : document.createElement('canvas'); 
 
     // IE11 doesn't set a width on svg images... 
 
     canvas.width = this.width || bbox.width; 
 
     canvas.height = this.height || bbox.height; 
 
     canvas.getContext('2d').drawImage(this, 0, 0, canvas.width, canvas.height); 
 

 
     // try to catch IE 
 
     try { 
 
      // if we set an <img> as receiver 
 
      if (receiver.nodeName === 'IMG') { 
 
      // make the img looks like the svg 
 
      receiver.setAttribute('style', getSVGStyles(receiver)); 
 
      receiver.src = canvas.toDataURL(params, quality); 
 
      } else { 
 
      // make the canvas looks like the canvas 
 
      canvas.setAttribute('style', getSVGStyles(canvas)); 
 
      // a container element 
 
      if (receiver.appendChild && receiver !== canvas) 
 
       receiver.appendChild(canvas); 
 
      // if we set a function 
 
      else if (typeof receiver === 'function') 
 
       receiver(canvas.toDataURL(params, quality), canvas); 
 
      } 
 
     } catch (ie) { 
 
      console.warn("Your ~browser~ has tainted the canvas.\n The canvas is returned"); 
 
      if (receiver.nodeName === 'IMG') receiver.parentNode.replaceChild(canvas, receiver); 
 
      else receiver(null, canvas); 
 
     } 
 
     } 
 
     svgImg.onerror = function(e) { 
 
     if (svg._cleanedNS) { 
 
      console.error("Couldn't export svg, please check that the svgElement passed is a valid svg document."); 
 
      return; 
 
     } 
 
     // Some non-standard NameSpaces can cause this issues 
 
     // This will remove them all 
 
     function cleanNS(el) { 
 
      var attr = el.attributes; 
 
      for (var i = 0; i < attr.length; i++) { 
 
      if (attr[i].name.indexOf(':') > -1) el.removeAttribute(attr[i].name) 
 
      } 
 
     } 
 
     cleanNS(svg); 
 
     for (var i = 0; i < svg.children.length; i++) 
 
      cleanNS(svg.children[i]); 
 
     svg._cleanedNS = true; 
 
     // retry the export 
 
     exportDoc(); 
 
     } 
 
     svgImg.src = svgURL; 
 
    } 
 
    // ToDo : find a way to get only usefull rules 
 
    var parseStyles = function() { 
 
    var styleS = [],i; 
 
    // transform the live StyleSheetList to an array to avoid endless loop 
 
    for (i = 0; i < document.styleSheets.length; i++) 
 
     styleS.push(document.styleSheets[i]); 
 
    // Do we have a `<defs>` element already ? 
 
    var defs = clone.querySelector('defs') || document.createElementNS('http://www.w3.org/2000/svg', 'defs'); 
 
    if (!defs.parentNode) 
 
     clone.insertBefore(defs, clone.firstElementChild); 
 

 
    // iterate through all document's stylesheets 
 
    for (i = 0; i < styleS.length; i++) { 
 
     var style = document.createElement('style'); 
 
     var rules = styleS[i].cssRules, 
 
     l = rules.length; 
 
     for (var j = 0; j < l; j++) 
 
     style.innerHTML += rules[j].cssText + '\n'; 
 

 
     defs.appendChild(style); 
 
    } 
 
    // small hack to avoid border and margins being applied inside the <img> 
 
    var s = clone.style; 
 
    s.border = s.padding = s.margin = 0; 
 
    s.transform = 'initial'; 
 
    } 
 
    var getSVGStyles = function(node) { 
 
    var dest = node.cloneNode(true); 
 
    svg.parentNode.insertBefore(dest, svg); 
 
    var dest_comp = getComputedStyle(dest); 
 
    var svg_comp = getComputedStyle(svg); 
 
    var mods = ""; 
 
    for (var i = 0; i < svg_comp.length; i++) { 
 
     if (svg_comp[svg_comp[i]] !== dest_comp[svg_comp[i]]) 
 
     mods += svg_comp[i] + ':' + svg_comp[svg_comp[i]] + ';'; 
 
    } 
 
    svg.parentNode.removeChild(dest); 
 
    return mods; 
 
    } 
 

 
    var images = svg.querySelectorAll('image'), 
 
    total = images.length, 
 
    encoded = 0; 
 
    // Loop through all our <images> elements 
 
    for (var i = 0; i < images.length; i++) { 
 
    // check if the image is external 
 
    if (images[i].getAttributeNS(xlinkNS, 'href').indexOf('data:image') < 0) 
 
     toDataURL(images[i]); 
 
    // else increment our counter 
 
    else if (++encoded === total) exportDoc() 
 
    } 
 
    // if there were no <image> element 
 
    if (total === 0) exportDoc(); 
 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/0.4.1/html2canvas.min.js"></script> 
 
<div id="contentDiv" style="width: 50%;"> 
 
    <img class="" src="s.jpg" width="75%"> 
 
    <svg xmlns="http://www.w3.org/2000/svg" id="svg" height="100%"> 
 
    <defs> 
 
     <clipPath id="my-path"> 
 
     <text id="texty" style="font-weight:bold;" x="60" y="300" font-size="60">test</text> 
 
     </clipPath> 
 
    </defs> 
 
    <image xlink:href="a.jpg" clip-path="url(#my-path)" width="100%" height="100%" id="filler" preserveAspectRatio="none"></image> 
 
    </svg> 
 
</div> 
 
<div id="clean">clean:<br></div> 
 
<div id="dirty">dirty :<br></div> 
 
<style type="text/css"> 
 
svg { 
 
    position: relative; 
 
    top: -531px; 
 
    left: 120px; 
 
} 
 
</style>

我附上三張圖片。 s.jpg圖像是我在主div裏面的主要圖像。這是用戶可以用紋理顏色寫他們的名字的主要圖像。要寫文本,我已經在主div中使用了svg,爲了紋理,我使用了a.jpg作爲隱藏圖像。

我用html2canvas js庫將div轉換成圖像,但我沒有得到我想要的輸出。請幫我找出解決這個問題的方法。 Thanx提前

+0

究竟如何,你所要的輸出是什麼樣子? – madalinivascu

+0

http://testing.devserver.co.in/demo/download.png - 查看鏈接我想要的輸出 – harleen

+0

聲明:我是['exportInlineSVG']的作者(https://stackoverflow.com/問題/ 33595847/javascript-convert-html-div-with-svg-to-image/33599357)你正在使用的函數。自從我發佈了這個答案以來,在[現已死亡的項目](https://github.com/Kaiido/SVG2Bitmap/blob/master/SVG2Bitmap.js)中有關於此功能的一些更新。但我不明白你的問題。你沒有在控制檯中的錯誤信息?另外,第一個'html2canvas'調用在沒有將svg轉換爲png的情況下得到了很好的評論,並且意在顯示這樣做的有用性。 – Kaiido

回答

0

你可以使用,你必須saveSvgAsPng.js與文件名一起傳遞SVG元素ID的圖像

在我的情況

saveSvgAsPng(document.getElementById('canvassvg'), "structure.png"); 

存儲在臨時圖像或瀏覽器下載位置 (OR),如果你想將其存儲在服務器上

轉換你的主要標籤,即的innerHTML內容,從SVG到/ SVG爲Base64和使用中的Base64圖像便利着想 [叔在後端

var svgData = new XMLSerializer().serializeToString(svgobj); 

var canvas = document.createElement("canvas"); 

var ctx = canvas.getContext("2d"); 

var img = document.createElement("img"); 

    function toSolidBytes(match, p1) { 
     return String.fromCharCode('0x' + p1); 
}))); 


svgData= btoa(encodeURIComponent(svgData).replace(/%([0-9A-F]{2})/g, 
    function toSolidBytes(match, p1) { 
     return String.fromCharCode('0x' + p1); 
})); 
img.setAttribute("src", "data:image/svg+xml;base64," + svgData); 
var canvasd=''; 
img.onload = function() { 
canvas.width = img.width; 
canvas.height = img.height; 
ctx.drawImage(img, 0, 0); 


    canvasd = canvas.toDataURL("image/svg+xml"); 

    -base64 data is in canvasd 
    -ajax call to store to backend 



}; 


return; 
0

試試這個,很容易使用和作品每次:

Dom-To-Image