需要加载图像+ SVG蒙版,选择SVG的多边形(填充颜色),然后将SVG蒙版导出到和图像。
我将最初的HTML代码基于对其他question的@Praveen答案,以便能够具有背景图像,并在其上放置一个已经具有的多多边形SVG,以定义每个颜色边缘。 / p>
目标是能够选择所需的多边形,然后仅保存蒙版。在用户选择的下面图像中,逐步进行操作将是下面的图像,例如红色和黑色,并且考虑到未选择黑色(白色选择)的多边形,将保存SVG蒙版。
我在JSFiddle上做了一个示例,以更清楚地了解其中嵌入了图像src和SVG的HTML代码,但是它们会在代码中注释后位于本地文件中。
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>TEST SVG</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!--
https://github.com/eligrey/Blob.js/
https://github.com/eligrey/FileSaver.js
-->
<script src="Blob.js"></script>
<script src="FileSaver.js"></script>
<script>
$(document).ready(function(e) {
$('img.svg').each(function(){
var $img = jQuery(this);
var imgID = $img.attr('id');
var imgClass = $img.attr('class');
var imgURL = $img.attr('src');
jQuery.get(imgURL, function(data) {
// Get the SVG tag, ignore the rest
var $svg = jQuery(data).find('svg');
// Add replaced image's ID to the new SVG
if(typeof imgID !== 'undefined') {
$svg = $svg.attr('id', imgID);
}
// Add replaced image's classes to the new SVG
if(typeof imgClass !== 'undefined') {
$svg = $svg.attr('class', imgClass+' replaced-svg');
}
// Remove any invalid XML tags as per http://validator.w3.org
$svg = $svg.removeAttr('xmlns:a');
// Replace image with new SVG
$img.replaceWith($svg);
$('path').click(function(){
if($(this).attr("class")=="selected"){
$(this).attr("class", "");
}
else{
$(this).attr("class","selected");
}
});
}, 'xml');
});
});
function writeDownloadLink(){
try {
var isFileSaverSupported = !!new Blob();
} catch (e) {
alert("blob not supported");
}
/*
var blob = new Blob([mySVG], {type: "image/svg+xml"});
saveAs(blob, "mySVG_selection.png");
*/
};
</script>
<style>
#bg div{
position:absolute;
top:0px;
left:0px;
}
#bg .path{
z-index:1;
}
#bg .bg{
z-index:0;
}
path{
fill:transparent;
}
path:hover{
fill:rgba(255,255,255,0.6);
cursor:pointer;
}
path.selected{
fill:rgba(255,255,255,0.6);
}
#savebutton {
position:absolute;
top:0px;
left:400px;
}
</style>
</head>
<body>
<div id="bg">
<div class="path">
<!--<img src="Sample_svg.svg" class="svg" />-->
<img src='data:image/svg+xml;utf8,
<svg width="1000" height="1000" xmlns="http://www.w3.org/2000/svg">
<path d="M0 0 0 200 200 200 200 0 "/>
<path d="M0 200 0 400 200 400 200 200 "/>
<path d="M200 0 200 200 400 200 400 0 "/>
<path d="M200 200 200 400 400 400 400 200 "/>
</svg>
' class="svg" />
</div>
<div class="bg">
<!--<img src="Sample_Bg.png" />-->
<img src="https://imgur.com/olRQfPy.png" />
</div>
</div>
<div id="savebutton">
<button onclick="writeDownloadLink()">Save PNG</button>
</div>
</body>
</html>
因此要解决的问题是提取/导出“ SVG掩码”并将其保存在PNG文件中。 我有一个猜测(我对Web服务,JavaScript不好,...),Blob JavaScript可以通过类似于以下代码来帮助实现这一目标:
var blob = new Blob([mySVG], {type: "image/svg+xml"});
saveAs(blob, "mySVG_selection.png");
以某种方式评论了该示例,但不知道如何仅使用“ SVG蒙版” abd将其转换为图像。
编辑
基于@enxaneta注释,我更新了工作代码,但无法取消选择选定的多边形:
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>TEST SVG</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
function myFunction()
{
let canv = document.createElement("canvas");
canv.width = svg.getAttribute("width");
canv.height = svg.getAttribute("height");
//canv.width = $('svg').attr("width");
//canv.height = $('svg').attr("height");
let ctx = canv.getContext("2d");
ctx.fillRect(0,0,canv.width,canv.height)
let selectedRy = [];
svg.addEventListener("click",(e)=>{
if(e.target.nodeName == "path"){
e.target.classList.add("selected");
selectedRy.push(e.target.getAttribute("d"));
}
})
action.addEventListener("click",()=>{
for(let i = 0; i < selectedRy.length; i++){
let thisPath = new Path2D(selectedRy[i]);
ctx.fillStyle = "white";
ctx.fill(thisPath);
}
img.setAttribute("src",canv.toDataURL("myImg.png"));
})
}
</script>
<style>
#bg div{
position:absolute;
top:30px;
left:0px;
}
#bg .path{
z-index:1;
}
#bg .bg{
z-index:0;
}
path{
fill:transparent;
}
path:hover{
fill:rgba(255,255,255,0.6);
cursor:pointer;
}
img{
border:0px solid
}
</style>
</head>
<body onload="myFunction()">
<button id="action">click</button>
<div id="bg">
<div class="path">
<!--<img src="Sample_svg.svg" class="svg" />-->
<svg id="svg" xmlns="http://www.w3.org/2000/svg" width="400" height="400" class="svg replaced-svg">
<path d="M0 0 0 200 200 200 200 0"></path>
<path d="M0 200 0 400 200 400 200 200"></path>
<path d="M200 0 200 200 400 200 400 0"></path>
<path d="M200 200 200 400 400 400 400 200 " ></path>
</svg>
<img id="img" width="400" height="400"/>
</div>
<div class="bg">
<!--<img src="Sample_Bg.png" />-->
<img src="https://imgur.com/olRQfPy.png" />
</div>
</div>
</body>
</html>
答案 0 :(得分:1)
我了解用户将单击某些svg矩形,然后需要将其保存到所选矩形在黑色背景上为白色的图像中。我就是这种情况,这是我的解决方案:
d
属性保存在selectedRy
toDataURL()
将其保存为数据uri图像。
let canv = document.createElement("canvas");
canv.width = svg.getAttribute("width");
canv.height = svg.getAttribute("height");
let ctx = canv.getContext("2d");
ctx.fillRect(0,0,canv.width,canv.height)
let selectedRy = [];
svg.addEventListener("click",(e)=>{
if(e.target.nodeName == "path"){
e.target.classList.add("selected");
selectedRy.push(e.target.getAttribute("d"));
}
})
action.addEventListener("click",()=>{
for(let i = 0; i < selectedRy.length; i++){
let thisPath = new Path2D(selectedRy[i]);
ctx.fillStyle = "white";
ctx.fill(thisPath);
}
img.setAttribute("src",canv.toDataURL());
})
path:hover{opacity:.5}
img{border:1px solid}
<button id="action">click</button>
<div class="path">
<svg id="svg" xmlns="http://www.w3.org/2000/svg" width="400" height="400" class="svg replaced-svg">
<path d="M0 0 0 200 200 200 200 0" fill="red"></path>
<path d="M0 200 0 400 200 400 200 200" fill="blue"></path>
<path d="M200 0 200 200 400 200 400 0" fill="lightgreen"></path>
<path d="M200 200 200 400 400 400 400 200 " ></path>
</svg>
<img id="img" width="400" height="400"/>
</div>
我希望这是您所需要的。
OP正在评论:
您的代码不允许进行“删除选择”操作。有什么办法可以取消选择先前选择的多边形?
此更新正在回答他们的评论的这一部分。
您可以切换该类,而不是在单击时添加类。所选的rect是具有.selected
类:sel = svg.querySelectorAll(".selected")
的所有rect。然后,当您为每个选定的路径单击按钮时,会在画布上绘制一个路径。
为了知道选择了哪些svg rect,我在CSS中添加了.selected{opacity:.25}
let canv = document.createElement("canvas");
canv.width = svg.getAttribute("width");
canv.height = svg.getAttribute("height");
let ctx = canv.getContext("2d");
let sel = [];
svg.addEventListener("click",(e)=>{
if(e.target.nodeName == "path"){
e.target.classList.toggle("selected");
sel = svg.querySelectorAll(".selected")
}
})
action.addEventListener("click",()=>{
//painting a black rect
ctx.fillStyle = "black";
ctx.fillRect(0,0,canv.width,canv.height);
//for every selected element in the SVG is painting a white rect on the canvas
for(let i = 0; i < sel.length; i++){
let thisPath = new Path2D(sel[i].getAttribute("d"));
ctx.fillStyle = "white";
ctx.fill(thisPath);
}
//paint the image
img.setAttribute("src",canv.toDataURL());
})
path:hover{opacity:.75}
img{border:1px solid}
.selected{opacity:.25}
<button id="action">click</button>
<div class="path">
<svg id="svg" xmlns="http://www.w3.org/2000/svg" width="400" height="400" class="svg replaced-svg">
<path d="M0 0 0 200 200 200 200 0" fill="red"></path>
<path d="M0 200 0 400 200 400 200 200" fill="blue"></path>
<path d="M200 0 200 200 400 200 400 0" fill="lightgreen"></path>
<path d="M200 200 200 400 400 400 400 200 " ></path>
</svg>
<img id="img" width="400" height="400"/>
</div>