js图片变NFT风格

**

js图片变NFT风格

** index.html

<!--
 * @Description: js图片变NFT风格
 * @Date: 2022-01-14 10:48:23
 * @LastEditors: ranshaka
 * @LastEditTime: 2022-01-14 10:50:19
 * @FilePath: index.html
-->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="pragma" content="no-cache" />
    <title>the Pixel Art | js图片变NFT风格</title>
    <link rel="stylesheet" type="text/css" href="css/style.css">
</head>
<body>
    <div class="container">
        <div class="sidebar">
            <h1>the Pixel Art</h1>

            <input id="img-upload" type="file" accept="image/*" >
            <label for="img-upload" class="btn btn-upload">+ 上传图片</label>
            <div id="img-preview">未上传</div>

            <div class="threshold">
                <div class="threshold-checkbox">
                    <input type="checkbox" name="isThresholdOn" class="option" id="threshold-on" checked="checked">
                    <label for="threshold-on">阈值 (0 ~ 255)</label>
                </div>

                <div class="threshold-range" id="threshold-range">
                    <button id="subtract" class="btn-small">-</button>
                    <input type="range" min="0" max="255" step="1" name="level" value="128" id="threshold-level">
                    <button id="add" class="btn-small">+</button>
                    <span class="threshold-val">128</span>
                </div>
            </div>

            <div class="mode" id="mode-panel">
                <span class="mode">模式:</span>
                <input type="radio" name="mode" id="mode-black" class="option" checked="checked" value="1"><label for="mode-black">黑白</label>
                <input type="radio" name="mode" id="mode-color" class="option"  value="0"><label for="mode-color">彩色</label>
            </div>


            <div class="scale">
                <label for="scale">缩放值 (像素大小)</label>
                <input type="number" min="0.01" max="1" step="0.01" value="0.25" name="scale" id="scale">
            </div>

            <a href="#" id="download" class="btn btn-download">下载图片</a>
        </div>

        <div class="main">
            <canvas id="canvas"></canvas>
        </div>


    </div>

    <script type="text/javascript" src="js/pixel.js"></script>
</body>
</html>

index.js

(function(){

    var $ = function(id) {
        return id ? document.getElementById(id) : null;
    };

    // global
    var currentThreshold = 128,
        scale = 0.25,
        currentImage = '';

    var thresholdLevel = $('threshold-level'),
        thresholdVal = document.querySelector('.threshold-val'),
        mode = document.getElementsByName('mode'),
        add = $('add'),
        subtract = $('subtract'),
        scaleRatio = $('scale'),
        isThresholdOn = $('threshold-on'),
        modePanel = $('mode-panel'),
        modeBlack = $('mode-black'),
        modeColor = $('mode-color'),
        uploadBtn = $('img-upload'),
        downloadBtn = $('download');

    /**
     * [thresholdConvert 阈值处理]
     * @param  {[type]} ctx       [description]
     * @param  {[type]} imageData [description]
     * @param  {[type]} threshold [阈值]
     * @param  {[type]} mode      [模式:0:彩色,1:黑白]
     * @return {[type]}           [description]
     */
    var thresholdConvert = function(ctx, imageData, threshold, mode) {
        var data = imageData.data;
        for (var i = 0; i < data.length; i += 4) {
            var red = data[i];
            var green = data[i + 1];
            var blue = data[i + 2];
            var alpha = data[i + 3];

            // 灰度计算公式
            var gray = 0.299 * data[i] + 0.587 * data[i + 1] + 0.114 *data[i + 2];

            var color = gray >= threshold ? 255 : 0;

            data[i]     = (mode == 0 && color == 0) ? red : color;    // red
            data[i + 1] = (mode == 0 && color == 0) ? green : color;  // green
            data[i + 2] = (mode == 0 && color == 0) ? blue : color;   // blue
            data[i + 3] = alpha >= threshold ? 255 : 0;               // 去掉透明
        }
        ctx.putImageData(imageData, 0, 0);
    };

    var render = function() {

        if (!currentImage) {
            alert('请先上传图片');
            return;
        }

        var canvasTemp = document.createElement('canvas');
        var context = canvasTemp.getContext('2d');

        var image = new Image();
        image.src = currentImage;
        image.onload = function() {
            canvasTemp.width = image.width * scale;
            canvasTemp.height = image.height * scale;
            // 缩小到 25%
            context.drawImage(image, 0, 0, image.width * scale, image.height * scale);

            var imageData = context.getImageData(0, 0, image.width * scale, image.height * scale);
            // 阈值处理
            isThresholdOn.checked && thresholdConvert(context, imageData, currentThreshold, getModeValue(mode));

            var dataURL = canvasTemp.toDataURL();
            var canvas = $('canvas');
            var ctx = canvas.getContext('2d');
            var img = new Image();
            img.src = dataURL;
            img.onload = function() {
                canvas.width = img.width / scale;
                canvas.height = img.height / scale;

                // 反锯齿
                ctx.imageSmoothingEnabled = false;
                ctx.mozImageSmoothingEnabled = false;
                ctx.webkitImageSmoothingEnabled = false;
                ctx.msImageSmoothingEnabled = false;

                ctx.drawImage(img, 0, 0, img.width / scale, img.height / scale);

                download();
            };
        };
    };

    var toggleThreshold = function(checked) {
        var thresholdRange = $('threshold-range');
        if (checked) {
            thresholdLevel.disabled = false;
            add.disabled = false;
            subtract.disabled = false;
            modeBlack.disabled = false;
            modeColor.disabled = false;
            thresholdRange.classList.remove('disable');
            modePanel.classList.remove('disable');
        } else {
            thresholdLevel.disabled = true;
            add.disabled = true;
            subtract.disabled = true;
            modeBlack.disabled = true;
            modeColor.disabled = true;
            thresholdRange.classList.add('disable');
            modePanel.classList.add('disable');
        }
    };

    var getModeValue = function(ele) {
        for (var i = 0, len = ele.length; i < len; i++) {
            if (ele[i].checked) {
                return ele[i].value;
            }
        }
    };


    var download = function() {
        downloadBtn.download = 'Ranshaka.png';
        downloadBtn.href = canvas.toDataURL();
    };



    // events
    thresholdLevel.addEventListener('change', function() {
        currentThreshold = this.value;
        thresholdVal.innerHTML = currentThreshold;
        render();
    }, false);

    subtract.addEventListener('click', function() {
        currentThreshold = --thresholdLevel.value;
        thresholdVal.innerHTML = currentThreshold;
        render();
    }, false);

    add.addEventListener('click', function() {
        currentThreshold = ++thresholdLevel.value;
        thresholdVal.innerHTML = currentThreshold;
        render();
    }, false);

    scaleRatio.addEventListener('change', function() {
        scale = this.value;
        render();
    }, false);

    isThresholdOn.addEventListener('change', function() {
        toggleThreshold(this.checked);
        render();
    }, false);

    for (var i = 0, len = mode.length; i < len; i++) {
        mode[i].addEventListener('change', function() {
            render();
        }, false);
    }




    // upload
    uploadBtn.addEventListener('change', function(e) {

        var file = e.target.files[0];

        if (!file.type.match('image.*')) {
            return;
        }

        var reader = new FileReader();
        reader.readAsDataURL(file);
        reader.onload = function(arg) {
            currentImage = arg.target.result;
            var img = '<img class="preview" src="' + arg.target.result + '" alt="preview" >';
            $('img-preview').innerHTML = img;

            render();
        };
    }, false);

})();

最后放上源码

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值