58

任意のHTML要素をキャンバスにレンダリングする(そしてそのバッファにアクセスする...)方法はありますか?

4

6 に答える 6

39

キャンバスコンテキストにはHTML要素をレンダリングする関数がないため、現在、実際のHTMLレンダリング<canvas>自体を取得することはできません。

いくつかのエミュレーションがあります:

html2canvasプロジェクトhttp://html2canvas.hertzen.com/index.html(基本的にはJavascript +キャンバス上に構築されたHTMLレンダラーの試み)

ユースケースによっては、 HTMLからSVGへの<canvas>変換が可能な場合があります。

https://github.com/miohtama/Krusovice/blob/master/src/tools/html2svg2canvas.js

また、Firefoxを使用している場合は、拡張アクセス許可をハックして、DOMウィンドウを次のようにレンダリングできます。<canvas>

https://developer.mozilla.org/en-US/docs/HTML/Canvas/Drawing_Graphics_with_Canvas?redirectlocale=en-US&redirectslug=Drawing_Graphics_with_Canvas#Rendering_Web_Content_Into_A_Canvas

于 2012-09-30T11:24:10.950 に答える
29

MDN(アーカイブ)を見てください

SVG画像の作成を使用してhtml要素をレンダリングします。

例:<em>I</em> like <span style="color:white; text-shadow:0 0 2px blue;">cheese</span> HTML要素 があります。<canvas id="canvas" style="border:2px solid black;" width="200" height="200"></canvas>そして、それをCanvasElementに追加したいと思います。

これは、HTML要素をcanvasに追加するためのJavascriptコードです。

var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');

var data = '<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200">' +
  '<foreignObject width="100%" height="100%">' +
  '<div xmlns="http://www.w3.org/1999/xhtml" style="font-size:40px">' +
  '<em>I</em> like <span style="color:white; text-shadow:0 0 2px blue;">cheese</span>' +
  '</div>' +
  '</foreignObject>' +
  '</svg>';

var DOMURL = window.URL || window.webkitURL || window;

var img = new Image();
var svg = new Blob([data], {
  type: 'image/svg+xml;charset=utf-8'
});
var url = DOMURL.createObjectURL(svg);

img.onload = function() {
  ctx.drawImage(img, 0, 0);
  DOMURL.revokeObjectURL(url);
}

img.src = url;
<canvas id="canvas" style="border:2px solid black;" width="200" height="200"></canvas>

于 2014-09-10T08:40:51.363 に答える
20

任意のHTMLをキャンバスにレンダリングするコードは次のとおりです。

function render_html_to_canvas(html, ctx, x, y, width, height) {
    var xml = html_to_xml(html);
    xml = xml.replace(/\#/g, '%23');
    var data = "data:image/svg+xml;charset=utf-8,"+'<svg xmlns="http://www.w3.org/2000/svg" width="'+width+'" height="'+height+'">' +
                        '<foreignObject width="100%" height="100%">' +
                        xml+
                        '</foreignObject>' +
                        '</svg>';

    var img = new Image();
    img.onload = function () {
        ctx.drawImage(img, x, y);
    }
    img.src = data;
}

function html_to_xml(html) {
    var doc = document.implementation.createHTMLDocument('');
    doc.write(html);

    // You must manually set the xmlns if you intend to immediately serialize     
    // the HTML document to a string as opposed to appending it to a
    // <foreignObject> in the DOM
    doc.documentElement.setAttribute('xmlns', doc.documentElement.namespaceURI);

    // Get well-formed markup
    html = (new XMLSerializer).serializeToString(doc.body);
    return html;
}

例:

const ctx = document.querySelector('canvas').getContext('2d');
const html = `
<p>this
<p>is <span style="color:red; font-weight: bold;">not</span>
<p><i>xml</i>!
<p><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABWElEQVQ4jZ2Tu07DQBBFz9jjvEAQqAlQ0CHxERQ0/AItBV9Ew8dQUNBQIho6qCFE4Nhex4u85OHdWAKxzfWsx0d3HpazdGITA4kROjl0ckFrnYJmQlJrKsQZxFOIMyEqIMpADGhSZpikB1hAGsovdxABGuepC/4L0U7xRTG/riG3J8fuvdifPKnmasXp5c2TB1HNPl24gNTnpeqsgmj1eFgayoHvRDWbLBOKJbn9WLGYflCCpmM/2a4Au6/PTjdH+z9lCJQ9vyeq0w/ve2kA3vaOnI6k4Pz+0Y24yP3Gapy+Bw6qdfsCRZfWSWgclCCVXTZu5LZFXKJJ2sepW2KYNCENB3U5pw93zLoDjNK6E7rTFcgbkGYJtiLckxCiw4W1OURsxUE5BokQiQj3JIToVtKwlhsurq+YDYbMBjuU/W3KtT3xIbrpAD7E60lwQohuaMtP8ldI0uMbGfC1r1zyWPUAAAAASUVORK5CYII=">`;
render_html_to_canvas(html, ctx, 0, 0, 300, 150);


function render_html_to_canvas(html, ctx, x, y, width, height) {
  var data = "data:image/svg+xml;charset=utf-8," + '<svg xmlns="http://www.w3.org/2000/svg" width="' + width + '" height="' + height + '">' +
    '<foreignObject width="100%" height="100%">' +
    html_to_xml(html) +
    '</foreignObject>' +
    '</svg>';

  var img = new Image();
  img.onload = function() {
    ctx.drawImage(img, x, y);
  }
  img.src = data;
}

function html_to_xml(html) {
  var doc = document.implementation.createHTMLDocument('');
  doc.write(html);

  // You must manually set the xmlns if you intend to immediately serialize     
  // the HTML document to a string as opposed to appending it to a
  // <foreignObject> in the DOM
  doc.documentElement.setAttribute('xmlns', doc.documentElement.namespaceURI);

  // Get well-formed markup
  html = (new XMLSerializer).serializeToString(doc.body);
  return html;
}
<canvas></canvas>

于 2017-05-01T18:12:24.180 に答える
4

CSSelement()関数は、質問に対する直接の答えではありませんが、最終的にはここの一部の人々に役立つ可能性があります。url(...)要素(およびビデオ、クロスドメインiframeなどを含むすべての子)を背景画像(およびCSSコードで通常使用する他の場所)として使用できます。これがあなたがそれで何ができるかを示すブログ投稿です。

これは2011年からFirefoxに実装されており、Chromium / Chromeで検討されています(この機能に関心がある場合は、問題にスターを付けることを忘れないでください)。

于 2019-02-24T08:00:57.027 に答える
3

RasterizeHTMLは非常に優れたプロジェクトですが、キャンバスにアクセスする必要がある場合は、Chromeでは機能しません。の使用による<foreignObject>

キャンバスにアクセスする必要がある場合は、html2canvasを使用できます

html2canvasのパフォーマンスが非常に遅いため、別のプロジェクトを見つけようとしています

于 2014-12-02T11:21:19.647 に答える
0

HTML仕様によると、Canvasの要素にアクセスすることはできません。あなたはその文脈を手に入れ、それを描くことでそれを操作することができますが、それだけです。

ただし、Canvas要素とhtml要素の両方をaaposition: relativeを使用して同じdivに配置し、canvasと他の要素をに設定することができposition: absoluteます。このようにして、それらは互いの上になります。次に、leftおよびrightCSSプロパティを使用してhtml要素を配置できます。

要素が表示されない場合は、キャンバスがその前にある可能性があるため、z-indexCSSプロパティを使用して要素をキャンバスの前に移動します。

于 2012-09-29T13:57:24.363 に答える