基于html的圖片轉(zhuǎn)svg秋忙,效果很好彩掐,大于500k的效果不是很好,網(wǎng)上看到的灰追,鏈接忘了堵幽,貼代碼吧狗超,直接保存成html文件就可以運行
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>HTML5 把圖像轉(zhuǎn)換成SVG文件</title>
<style>
body {
padding: 1em;
padding-bottom: 2em;
max-width: 35em;
margin: auto;
font-size: 14px;
line-height: 1.4;
}
h1 {
display: block;
margin: 0 0 0.5em;
}
h1 svg {
margin: 0;
}
p {
margin: 0 0 1em;
}
a {
color: #f05555;
}
img {
vertical-align: middle;
}
button {
background: #ddd;
border: none;
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
}
button,
input[type=file] {
padding: 0.5em;
cursor: pointer;
}
svg,
label,
input[type=file] {
display: block;
margin: 1em auto;
text-align: center;
}
label small {
display: block;
}
svg {
max-width: 100%;
}
.choices {
background: #eee;
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-box-align: stretch;
-webkit-align-items: stretch;
-ms-flex-align: stretch;
align-items: stretch;
}
.choices > * {
-webkit-box-flex: 1;
-webkit-flex: 1 1 50%;
-ms-flex: 1 1 50%;
flex: 1 1 50%;
}
.download,
.outputSize {
display: inline-block;
text-align: center;
margin: 1em auto 0;
padding: 0.25em 0.5em;
font-size: 0.8em;
}
.download {
background-color: #f05555;
color: #fff;
}
#output {
text-align: center;
}
#outputRaw {
display: block;
background: #eee;
white-space: pre-wrap;
padding: 0.5em;
font-size: 0.75em;
}
.inspired {
position: fixed;
bottom: 0;
left: 0;
right: 0;
padding: 0.5em;
width: 100%;
background: #fff;
background: rgba(255, 255, 255, 0.8);
text-align: center;
}
</style>
</head>
<body>
<h1>
<svg xmlns="https://www.w3.org/2000/svg" viewbox="0 -0.5 61 11.5" shape-rendering="crispEdges">
<title>Pixels to SVG</title>
<path stroke="#f05555" d="M0 0h61M0 1h61M0 2h2M5 2h2M8 2h1M10 2h3M14 2h1M19 2h1M21 2h5M29 2h2M41 2h3M47 2h1M49 2h3M53 2h2M58 2h3M0 3h2M3 3h2M6 3h1M8 3h1M10 3h3M14 3h1M16 3h4M21 3h4M26 3h5M33 3h1M41 3h2M44 3h4M49 3h3M53 3h1M55 3h6M0 4h2M3 4h2M6 4h1M8 4h2M11 4h1M13 4h2M18 4h2M21 4h4M26 4h5M32 4h3M37 4h2M41 4h2M44 4h4M49 4h3M53 4h1M55 4h6M0 5h2M5 5h2M8 5h3M12 5h3M16 5h4M21 5h5M28 5h3M33 5h1M36 5h1M39 5h1M41 5h3M46 5h2M49 5h3M53 5h1M55 5h1M58 5h3M0 6h2M3 6h4M8 6h2M11 6h1M13 6h2M16 6h4M21 6h7M29 6h2M33 6h1M36 6h1M39 6h1M41 6h5M47 6h2M50 6h1M52 6h2M55 6h3M59 6h2M0 7h2M3 7h4M8 7h1M10 7h3M14 7h1M16 7h4M21 7h7M29 7h2M34 7h1M37 7h2M41 7h5M47 7h2M50 7h1M52 7h2M55 7h3M59 7h2M0 8h2M3 8h4M8 8h1M10 8h3M14 8h1M19 8h1M24 8h1M28 8h3M41 8h2M46 8h4M51 8h4M58 8h3M0 9h61M0 10h61" />
<path stroke="#ffffff" d="M2 2h3M7 2h1M9 2h1M13 2h1M15 2h4M20 2h1M26 2h3M31 2h10M44 2h3M48 2h1M52 2h1M55 2h3M2 3h1M5 3h1M7 3h1M9 3h1M13 3h1M15 3h1M20 3h1M25 3h1M31 3h2M34 3h7M43 3h1M48 3h1M52 3h1M54 3h1M2 4h1M5 4h1M7 4h1M10 4h1M12 4h1M15 4h3M20 4h1M25 4h1M31 4h1M35 4h2M39 4h2M43 4h1M48 4h1M52 4h1M54 4h1M2 5h3M7 5h1M11 5h1M15 5h1M20 5h1M26 5h2M31 5h2M34 5h2M37 5h2M40 5h1M44 5h2M48 5h1M52 5h1M54 5h1M56 5h2M2 6h1M7 6h1M10 6h1M12 6h1M15 6h1M20 6h1M28 6h1M31 6h2M34 6h2M37 6h2M40 6h1M46 6h1M49 6h1M51 6h1M54 6h1M58 6h1M2 7h1M7 7h1M9 7h1M13 7h1M15 7h1M20 7h1M28 7h1M31 7h3M35 7h2M39 7h2M46 7h1M49 7h1M51 7h1M54 7h1M58 7h1M2 8h1M7 8h1M9 8h1M13 8h1M15 8h4M20 8h4M25 8h3M31 8h10M43 8h3M50 8h1M55 8h3" />
</svg>
</h1>
<p>
Need a pixel-perfect scalable image, but all you have is a low-res GIF? You could use <a target="_blank"><code>image-rendering: pixelated</code></a> and hope the browser will scale it
right, or you could use this tool to convert a raster image to SVG.
</p>
<p>
Each color is merged into one <code>path</code>, optimized for combining horizontal runs where possible to keep file size down. Works best with 8-bit images, or graphics where colors are limited and the dimensions are relatively small. Large or complex
images may lock the browser.
</p>
<div class="choices">
<input type="file" id="upload" />
<button id="test">
or try with a test image:
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAASCAMAAABcgh8DAAAADFBMVEUAAAD/MRjGYwD/lFpY2Im6AAAAAXRSTlMAQObYZgAAAExJREFUeNptzgkKwCAQQ1Enuf+dm8wYbIsfF56CuC6VO0pDACS4tij1DN8WLLUmTltA+Spq5gSmwphEsTRANgXHphXnz7Pk5e929l8Pl0sBHu8kwiYAAAAASUVORK5CYII="
id="testImage" />
</button>
</div>
<!--<label><input type="checkbox" id="includeDimensions" /> Include width/height on SVG? <small>viewBox will always be included, but omitting the width/height allows the SVG to scale</small></label>-->
<div id="output"></div>
<pre contenteditable="true" id="outputRaw"></pre>
<div class="inspired">
<em>Inspired by <a target="_blank">px2svg</a></em>
</div>
<script>
console.clear();
function each(obj, callback) {
var length = obj.length,
likeArray = (length === 0 || (length > 0 && (length - 1) in obj)),
i = 0;
if (likeArray) {
for (; i < length; i++) {
if (callback.call(obj[i], i, obj[i]) === false) {
break;
}
}
} else {
for (i in obj) {
if (callback.call(obj[i], i, obj[i]) === false) {
break;
}
}
}
}
function byteCount(s) {
return encodeURI(s).split(/%..|./).length - 1;
}
function componentToHex(c) {
var hex = c.toString(16);
return hex.length == 1 ? "0" + hex : hex;
}
function getColor(r, g, b, a) {
if (a === undefined || a === 255) {
return "#" + componentToHex(r) + componentToHex(g) + componentToHex(b);
}
if (a === 0) {
return false;
}
return 'rgba(' + r + ',' + g + ',' + b + ',' + (a / 255) + ')';
}
// Optimized for horizontal lines
function makePathData(x, y, w) {
return ('M' + x + ' ' + y + 'h' + w + '');
}
function path(color, data) {
return '<path stroke="' + color + '" d="' + data + '" />\n';
}
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
var uploader = document.getElementById('upload');
var outputDiv = document.getElementById('output');
var outputRaw = document.getElementById('outputRaw');
function processImage(src) {
var img = new Image();
img.onload = function () {
var width = img.width;
var height = img.height;
canvas.width = width;
canvas.height = height;
ctx.drawImage(img, 0, 0);
// viewBox starts at -0.5 to accomodate stroke's middle-origin to prevent having to include 0.5 on each path move
var output = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -0.5 ' + width + ' ' + height + '" shape-rendering="crispEdges">\n';
var colors = {},
x = 0,
y = 0,
p, color;
for (y = 0; y < height; y++) {
for (x = 0; x < width; x++) {
p = ctx.getImageData(x, y, 1, 1).data;
color = getColor(p[0], p[1], p[2], p[3]);
if (color) {
colors[color] = colors[color] || [];
colors[color].push([x, y]);
}
}
}
// Loop through each color
each(colors, function (i, value) {
if (i === false) {
return;
}
var paths = [];
var curPath;
var w = 1;
// Loops through each color's pixels to optimize paths
each(value, function () {
if (curPath && this[1] === curPath[1] && this[0] === (curPath[0] + w)) {
w++;
} else {
if (curPath) {
paths.push(makePathData(curPath[0], curPath[1], w));
w = 1;
}
curPath = this;
}
});
paths.push(makePathData(curPath[0], curPath[1], w)); // Finish last path
output += path(i, paths.join(''));
});
output += '</svg>';
outputDiv.innerHTML = '<em class="outputSize">Output size (bytes): ' + byteCount(output) + '</em>' + '<a href="data:Application/octet-stream,' + encodeURIComponent(output) + '" download="pixels.svg"><span class="download">Download SVG</span>' + output + '</a>';
outputRaw.innerHTML = output.replace(/</g, '<').replace(/>/g, '>');
}
img.src = (src.target ? src.target.result : src);
}
function loadImage(e) {
var reader = new FileReader();
reader.onload = processImage;
file = (e.target.files || uploader.files)[0];
if (file) {
reader.readAsDataURL(file);
}
}
uploader.onclick = uploader.onchange = loadImage;
var test = document.getElementById('test');
var testImage = document.getElementById('testImage');
test.onclick = function () {
processImage(testImage.src);
}
</script>
</body>
</html>