0

クロムのキャンバスに問題があります。これがよく言及されていることは知っていますが、自分に合った解決策を見つけることができませんでした。

基本的に、次の手順を実行する Web サイトを設計しています。
- ホスティング サーバーから SVG 画像テンプレートをオブジェクトに読み込みます。
- その SVG を操作します (カラーリング、レイヤーの非表示と表示など...)
- 次に、操作されたバージョンをサーバーに送信して、PDF ドキュメントに挿入し、電子メールで送信します。

私の問題は最後のステップにあります。私が使用していたアプローチには、次のものが含まれます。
- SVG のコンテンツ ドキュメントを取得し、その XML をシリアル化します。

 var s = new XMLSerializer();
 svg = document.getElementById('theSVG').contentDocument;
 var xmlTest = s.serializeToString(svg);
  • onLoad 関数を使用して新しいイメージを定義し、それに src を適用します。

    drawImage.src = 'data:image/svg+xml,' + escape(xmlTest);

  • キャンバス要素を作成し、その画像を描画します。

    var canvas = document.createElement('canvas'); var cont = canvas.getContext('2d'); cont.drawImage( drawImage, 0, 0, canvas.width, canvas.height);

  • 最後のステップは、キャンバス要素から dataURI を抽出することです。

var ImageDataURl = canvas.toDataURL();

その後、データ (base64) がサーバーに送信され、ビットマップに変換され、サーバー ディスクに jpeg 画像として保存され、大きな pdf ドキュメントの一部として挿入されます。

Chromeでテストするまではすべてうまくいっていましたが、次のようなセキュリティエラーが発生しました。

Uncaught SecurityError: ユーザー エージェントのセキュリティ ポリシーを突破しようとしました

このエラーについて読んだとき、これはクロス ドメイン イメージのクロム セキュリティの問題であり、何とか何とかしていることを知りました。私が知りたいのは次のことです:
- 新しいキャンバスを作成し、別のドメインからのファイルとして扱われるユーザーのブラウザに画像をロードしていますか?
-サーバー側であっても、これに対する回避策はありますか(私はC#を使用しています)、気にしません。SVG XML をアップロードして base64 文字列に変換しようとしましたが、うまくいきませんでした。

どんな助けでも大歓迎です。

4

4 に答える 4

2

Chrome では、SVG 画像をキャンバスにロードすると、キャンバスが汚染されます。つまり、キャンバスに書き込むことはできますが、そこからデータを読み取ることはできません。のような特定の SVG 要素を避ければ、Chrome で最近修正さ<foreignObject>れたようです。おそらく、まもなく Chrome リリース バージョンになるでしょう。

当面は、キャンバスを汚染しない Firefox を代わりに使用することもできます。

于 2013-09-03T08:22:33.717 に答える
1

fabric js を使用してこの問題を解決しました。素晴らしい図書館。コードは次のとおりです。

var a = document.getElementById("theSVG"); //This is the <object>
a.setAttribute('data', 'worldmap.svg'); //Setting the data attribute to the svg file


a.onload = function () {

    var svgDoc = a.contentDocument;
    var s = new XMLSerializer();
    var xml = s.serializeToString(svgDoc);


    var canvas = new fabric.Canvas('canvas');

    var svg = xml;

    fabric.loadSVGFromString(svg, function (objects, options) {
        var loadedObject = fabric.util.groupSVGElements(objects, options);
        canvas.add(loadedObject);
        canvas.calcOffset();
        canvas.renderAll();
        if (!fabric.Canvas.supports('toDataURL')) {
            alert('This browser doesn\'t provide means to serialize canvas to an image');
        }
        else {
            window.open(canvas.toDataURL('png'));
        }

    });
}

これにより .toDataURL() の問題が解決されました。しかし、SVG ファイルに問題が残っています。お役に立てれば。

于 2013-10-24T12:52:56.900 に答える
0

問題の原因の 1 つは、イメージに別の「ドメイン」を使用する場合です...

ドメインの Url から toDataUrl を試みた場合は機能しますが、それ以外の場合は機能しません。

私はこの答えを見つけました

それから私は追加しました

access-control-allow-origin: *
access-control-allow-credentials: true

私のサーバーでは、それはうまくいきませんでした...

最後にこれを試しました。img.crossOrigin = "Anonymous"; を入れただけです。そしてヘッダー

そして、それはうまくいきました。

于 2013-09-07T19:01:45.533 に答える
0

こんにちは私は以下のようにやっています。エラーは発生しませんでした。これがお役に立てば幸いです。

<script type="text/javascript">

$("#exportButton").click(function() { 

    html2canvas( [ document.getElementById("divId_for_Pdf") ], {
       onrendered: function(canvas) {
           var dataUrl = canvas.toDataURL();
         // $('#img1').attr('src',dataUrl);
           var action ='saveChartData';
            var data="dataUrl="+dataUrl;
           $.ajax({url:action, data:data, dataType:'text',type:'POST',cache:false,
               success: function(data) {
                 //alert("success..........!")
                   window.location.href = "${grailsApplication.config.grails.serverURL}/adminConfig/downloadAnalyticsChart?tenantName=${tenantInstance?.tenantName}&from=Dashboard"
               },
               error: function(request, status, error) {
                   alert('error');
               },
               complete: function(data){

               }
           });

       }
   });
});        

</script>
于 2013-09-03T09:22:40.153 に答える