2016-07-28 2 views
1

SVGフィルタで変更された画像をドロップシャドーにエクスポートしようとしています。 CSSの代わりにSVGフィルタを使用していますが、これはCSSが現在サポートしていないシャドウスプレッド機能のためです。残念ながら、キャンバスはシャドウスプレッド機能のようなフォトショップもサポートしていません。キャンバスはイメージを書きますが、SVGフィルタは含まず、キャンバス固有のシャドウフィルタのみを含みます。フィルタをHTML5キャンバスに実装したSVG

最後の目標は、フィルタを組み込んだJPEG画像を書き出すことです。したがって、SVG> Canvas> Imageになります。

私の質問は画像を描画するときにSVGフィルタを組み込むためにどのようにキャンバスをトリックするのですか?

これまで私がこれまで持っていたことは次のとおりです。

イメージ・HTML:

<img ng-src="logo.png" style="-webkit-filter: url("#logo-filter"); filter: url("#logo-filter");" /> 

SVGフィルタ設定:

<svg> 
     <defs> 
     <filter id="logo-filter" x="0" y="0" width="200%" height="200%"> 
      <feFlood result="flood" flood-color="#00FFFF" flood-opacity="1"></feFlood> 
      <feComposite in="flood" result="mask" in2="SourceGraphic" operator="in" /> 
      <feOffset in="mask" result="offset" dx="10" dy="10" /> 
      <feGaussianBlur in="offset" result="blurred" stdDeviation="3" /> 
      <feComponentTransfer> 
        <feFuncA type="gamma" exponent="0.5" amplitude="3" in="blurred" result="blurred2" /> 
      </feComponentTransfer> 
      <feMerge> 
      <feMergeNode in="blurred2"></feMergeNode> 
      <feMergeNode in="SourceGraphic"></feMergeNode> 
     </feMerge> 
     </filter> 
    </defs> 
</svg> 

キャンバスの実装:私は自分の質問への答えを考え出した

function plotLogo(img, logo, container) { 
     var canvas = document.getElementById("logo-canvas"); 
     var position = getOffset($('#'+container.id+'-logo')); 

     var logo_image = new Image(); 

     logo_image.src = img; 

     logo_image.onload = function(){ 
     canvas.width = container.width; 
     canvas.height = container.height; 
     var context = canvas.getContext('2d'); 

     /* StackOverflow Comment: Works but with no shadow spread */ 
     context.shadowOffsetX = logo.shadow.offsetX; 
     context.shadowOffsetY = logo.shadow.offsetY; 
     context.shadowColor = logo.shadow.color; 
     context.shadowBlur = logo.shadow.blur*2; //Multiplied by 2 to get closest look to webkit shadow 

     context.drawImage(logo_image, position.posX, position.posY, logo.width, logo.height); 
     }; 
    } 

答えて

1

は、ここで私が来たソリューションですと一緒に。

私はSVGを持っていなければならなかったのは、ユーザーがsvgイメージタグを使って操作するものを基本的に反映したものでした。どちらもfilter:url(#logo-filter)にリンクしています。

<svg id="svg-logo" height="175" width="600"> 
    <defs> 
     <filter id="logo-filter" x="-50%" y="-50%" width="200%" height="200%"> 
      <feFlood result="flood" flood-color="[[params.logo.shadow.color]]" flood-opacity="1"></feFlood> 
      <feComposite in="flood" result="mask" in2="SourceGraphic" operator="in" /> 
      <feOffset in="mask" result="offset" dx="[[params.logo.shadow.offsetX]]" dy="[[params.logo.shadow.offsetY]]" /> 
      <feGaussianBlur in="offset" result="blurred" ng-stddeviation="[[params.logo.shadow.blur]]" /> 
      <feComponentTransfer> 
        <feFuncA type="gamma" exponent="0.5" amplitude="[[params.logo.shadow.spread]]" in="blurred" result="blurred2" /> 
      </feComponentTransfer> 
      <feMerge> 
      <feMergeNode in="blurred2"></feMergeNode> 
      <feMergeNode in="SourceGraphic"></feMergeNode> 
     </feMerge> 
     </filter> 
    </defs> 
    <image id="svg-logo-image" xlink:href="logo.png" filter="url(#[[svg.logo.filter]])" x="0" y="0" /> 
</svg> 

SVG情報が収集され、window.btoaを使用してbase64エンコードに変換されます。 xlink:hrefもbase64のイメージコードでなければ動作しないことに注意してください!

var svg = document.getElementById('svg-'+type); 
var svgData = new XMLSerializer().serializeToString(svg); 

var encodedData = window.btoa(unescape(encodeURIComponent(svgData))); 
var newSrc = 'data:image/svg+xml;base64,'+encodedData; 

ここには私が現在持っているすべての機能があります。

function plotImage(element, container, index, img) { 

    var type = img ? 'logo' : 'address'; 
    var canvas = document.getElementById(type+'-canvas'); 
    var svg = document.getElementById('svg-'+type); 
    var svgElem = document.getElementById('svg-'+type+'-image'); 
    var position = getOffset($('#'+container.name+'-'+type), $('#'+container.name)); 


    svg.setAttribute('width', container.width); 
    svg.setAttribute('height', container.height); 

    if(typeof img !== 'undefined') { 

    svgElem.setAttribute('x', position.x); 
    svgElem.setAttribute('y', position.y); 
    svgElem.setAttribute('width', element.width); 
    svgElem.setAttribute('height', element.height); 
    svgElem.setAttribute('xlink:href', img); 

    } else { 

    svgElem.setAttribute('x', position.x); 
    svgElem.setAttribute('y', position.y+(element.size/3)); // Adjust Y via 1/3 of font-size 

    } 

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

    var encodedData = window.btoa(unescape(encodeURIComponent(svgData))); 
    var newSrc = 'data:image/svg+xml;base64,'+encodedData; 

    // Alternate Method, (slower) 
    // var svgBlob = new Blob([svgData], {type: "image/svg+xml;charset=utf-8"}); 
    // var newSrc = window.URL.createObjectURL(svgBlob); 

    var image = new Image(); 
    image.src = newSrc; 
    image.onload = drawCanvas(image, canvas, container); 

} 
関連する問題