如何在 svg 中为图像标签创建边框?

How to create border for image tag in svg?

我试过像这样在 svg 中为图像创建边框:

<svg id="svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 1054 670" xml:space="preserve">
<defs>
    <filter id="f3" x="0" y="0" width="200%" height="200%">
      <feOffset result="offOut" in="SourceAlpha" dx="0" dy="1"></feOffset>
      <feGaussianBlur result="blurOut" in="offOut" stdDeviation="0.5"></feGaussianBlur>
      <feBlend in="SourceGraphic" in2="blurOut" mode="normal"></feBlend>
    </filter>
  </defs>

<image overflow="visible" x="5" width="200" height="300" filter="url(#f3)" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://upload.wikimedia.org/wikipedia/commons/9/9e/Flag_of_Japan.svg" >
    </image>    
</svg>

但它只是一个边框底部。我怎样才能在右上角和左上角添加边框。谢谢你

2 个选项:

1- 调整 SVG 元素的大小以匹配图像并使用 CSS 边框

2- 在您的图片周围画一个矩形

option2 jsfiddle demo:

jsfiddle

更新: 使用 javascript 以编程方式添加矩形作为图像的边框,具有调整大小和边框颜色更改功能:

function addBorders(image){
    var x = image.getAttribute("x");
    x = x ? x : 0;
    var y = image.getAttribute("y");
    y = y ? y : 0;    
    var w = image.getAttribute("width");
    var h = image.getAttribute("height");

    var g = document.createElementNS("http://www.w3.org/2000/svg", "g");    

    var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect");    
    rect.setAttribute("style","fill:white; fill-opacity:0;stroke:black; stroke-width:2px;");

    rect.id = image.id + "rect";
    console.log(rect.id);
    rect.setAttribute("x",x);
    rect.setAttribute("y",y);
    rect.setAttribute("width",w);
    rect.setAttribute("height",h);


    var parent = image.parentNode;
    parent.insertBefore(g,image);
    g.appendChild(image);
    g.insertBefore(rect,image.nextSibling);

}

function redrawBorder(rect,w,h){
    rect.setAttribute("width",w);
    rect.setAttribute("height",h);    
}

window.updatePosition = function(image,x,y){

    document.getElementById(image.id + "rect")
    image.setAttribute("x",x);
    image.setAttribute("y",y);
    moveBorder(image.nextSibling,x,y);

}

function moveBorder(rect,x,y){
    rect.setAttribute("x",x);
    rect.setAttribute("y",y);    
}

window.updateSize = function(image,w,h){

    document.getElementById(image.id + "rect")
    image.setAttribute("width",w);
    image.setAttribute("height",h);
    redrawBorder(image.nextSibling,w,h);

}

window.updateColor = function(image,color){

     document.getElementById(image.id + "rect").style.stroke=color;
}


var image = document.getElementById("image1");
addBorders(image);

演示: jsfiddle

您得到的只是底部边框,因为您的过滤器中只有一个 <feOffset> 用于下移 SourceAlpha。因此只有底部边框。

如果你想坚持使用过滤器,那么你可以只使用四个 <feOffset> 元素,这样你就可以获得所有四个边框。在下面的例子中,我实际上是在每个角的方向上移动偏移量,这样你就不会丢失角像素。

<svg id="svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 1054 670" xml:space="preserve">
<defs>
    <filter id="f3">
      <feOffset result="nw" in="SourceAlpha" dx="-3" dy="-3"></feOffset>
      <feOffset result="ne" in="SourceAlpha" dx="3" dy="-3"></feOffset>
      <feOffset result="se" in="SourceAlpha" dx="3" dy="3"></feOffset>
      <feOffset result="sw" in="SourceAlpha" dx="-3" dy="3"></feOffset>
      <feMerge>
          <feMergeNode in="nw"/>
          <feMergeNode in="ne"/>
          <feMergeNode in="se"/>
          <feMergeNode in="sw"/>
          <feMergeNode in="SourceGraphic"/>
        </feMerge>
    </filter>
  </defs>

<image overflow="visible" x="5" width="200" height="300" filter="url(#f3)" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://upload.wikimedia.org/wikipedia/commons/9/9e/Flag_of_Japan.svg" >
    </image>    
</svg>

四个角偏移的 SourceAlphas 提供黑色边框。然后我们在上面合并原始图像。

更新:如何更改边框颜色

要使边框颜色不是黑色,我们必须向过滤器添加更多操作。最简单的方法是用新的边框颜色填充过滤区域,然后将其遮盖在黑色边框矩形上。完成后,我们可以像以前一样在顶部合并标志图像。

<svg id="svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 1054 670" xml:space="preserve">
<defs>
    <filter id="f3">
        <!-- Make four copies of the image alpha, each moved to a different corner -->
        <feOffset result="nw" in="SourceAlpha" dx="-3" dy="-3"></feOffset>
        <feOffset result="ne" in="SourceAlpha" dx="3" dy="-3"></feOffset>
        <feOffset result="se" in="SourceAlpha" dx="3" dy="3"></feOffset>
        <feOffset result="sw" in="SourceAlpha" dx="-3" dy="3"></feOffset>
        <!-- Merge those four copies together -->
        <feMerge result="blackborder">
            <feMergeNode in="nw"/>
            <feMergeNode in="ne"/>
            <feMergeNode in="se"/>
            <feMergeNode in="sw"/>
        </feMerge>
        <!-- Create a filter primitive that is just a solid block of what will be
             the new border colour (in this case orange) -->
        <feFlood flood-color="orange"/>
        <!-- Use the "in" operator to merge the blackborder with the orange fill.
             Any parts of the orange fill that are "in"-side the back shape will remain.
             The rest will me masked out. -->
        <feComposite in2="blackborder" operator="in" />
        <!-- Finally, merge the new orange border with the original image -->
        <feMerge>
            <feMergeNode/>
            <feMergeNode in="SourceGraphic"/>
        </feMerge>
    </filter>
</defs>

<image overflow="visible" x="5" y="5" width="200" height="300" filter="url(#f3)" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://upload.wikimedia.org/wikipedia/commons/9/9e/Flag_of_Japan.svg" >
    </image>    
</svg>