2017-05-05 16 views
0

私は画像として全体のdivをキャプチャし、プルーフのためにローカルに保存したいと思います。私はsvgについての多くの記事を検索し、javascriptのsvgで全体のdivをキャプチャします

私はdivの画像をキャプチャしようとすると、divのコンテンツだけをキャプチャし、一部はsvgのコンテンツだけをキャプチャするthis.Butのためにいくつかのjsライブラリを試してみました。

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の中にある私のメインイメージです。ユーザーがテクスチャカラーで名前を書くことができる主なイメージです。テキストを書くために私はmain divの中でsvgを使いました。そしてテクスチャのために私はa.jpgを隠し画像として使っていました。

divを画像に変換するためにhtml2canvas jsライブラリを使用しましたが、希望の出力が得られませんでした。この問題の解決策を見つけるのを手伝ってください。事前にありがとう

+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
あなたは私の場合には画像

にファイル名と一緒にSVG要素IDを渡すためにあなたが持っているsaveSvgAsPng.jsを使用することができます

あなたの一時に画像を記憶

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

またはブラウザのダウンロード場所 (OR) あなたは、あなたのメインタグののinnerHTMLの内容を変換すなわち、SVGから/ SVGにBASE64へとconve画像に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

でrterは非常に使いやすい、これを試してみて、毎回作品:

Dom-To-Image

関連する問題