图片转svg

基于html的图片转svg,效果很好,大于500k的效果不是很好,网上看到的,链接忘了,贴代码吧,直接保存成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 把图像转换成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 href="https://css-tricks.com/almanac/properties/i/image-rendering/" 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 href="https://github.com/meyerweb/px2svg" 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>

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,651评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,468评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,931评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,218评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,234评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,198评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,084评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,926评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,341评论 1 311
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,563评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,731评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,430评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,036评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,676评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,829评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,743评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,629评论 2 354

推荐阅读更多精彩内容

  • rljs by sennchi Timeline of History Part One The Cognitiv...
    sennchi阅读 7,322评论 0 10
  • 前言: 项目需求是这样的:将网页上面的外联的svg图像,变成内嵌的svg图像。从而我们可以写一些css样式控制这个...
    merrylmr阅读 4,135评论 0 1
  • 前言: 之前做svg动画的时候用到图片转svg path路径,网上找了很多相关的, 也用过几个在线转换的网址,...
    lpz0715阅读 59,470评论 1 21
  • 一、习惯的养成 1.启动按钮(为什么要养成这个习惯,内在启动和外在启动) 2.行动—执行既定的安排 3.激励计划—...
    独上兰舟_bac7阅读 258评论 0 0
  • 这几天一直在网上搜索:怎么赚到一百万?事实上我也明白不可能找到方法!老外比较务实,只会说可能赚到的行业!而国人,大...
    35岁的阿牛阅读 160评论 0 0