马黑黑 发表于 2024-4-24 19:49

俺家的小公举(canvas画布灰度化图像)

本帖最后由 马黑黑 于 2024-4-24 20:10 编辑 <br /><br /><canvas id="canv" style="display: block; margin: auto; border: 1px solid gray; background: #333;"></canvas>
<p style="margin-top: 20px; text-align: center;">
        <button id="btnGray" type="button" value="0" disabled>灰度</button> &nbsp;
        <button id="btnRestore" type="button" value="1">还原</button>
</p>

<script>

(function () {
        let btns = ;
        let ctx = canv.getContext('2d');
        let ww, hh, imgData;

        let img = new Image();
        img.crossOrigin = 'anonymous';
        img.onload = () => {
                ww = canv.width = img.width;
                hh = canv.height = img.height;
                ctx.drawImage(img, 0, 0, ww, hh);
                imgData = ctx.getImageData(0,0,ww,hh);
                toGray(imgData);
        };

        let toGray = (data) => {
                for(let k = 0; k < data.data.length; k += 4) {
                        let average = (data.data + data.data + data.data) / 3;
                        data.data = data.data = data.data = average;
                }
                ctx.clearRect(0, 0, ww, hh);
                ctx.putImageData(data, 0, 0);
        };

        btns.forEach(btn => {
                btn.onclick = () => {
                        btn.value === '0' ?
                                (btns.disabled = true, btns.disabled = false, toGray(imgData)) :
                                (btns.disabled = true, btns.disabled = false, ctx.drawImage(img, 0, 0));
                };
        });

        img.src = 'https://638183.freep.cn/638183/t24/webp/xgj.webp';
})();

</script>

马黑黑 发表于 2024-4-24 19:50

本帖最后由 马黑黑 于 2024-4-24 20:09 编辑 <br /><br /><style>
.mum { position: relative; margin: 0; padding: 10px; font: normal 16px/20px Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; color: black; background: rgba(240, 240, 240,.95); box-shadow: 2px 2px 4px gray; border: thick groove lightblue; border-radius: 6px; }
.mum ::selection { background-color: rgba(0,100,100,.35); }
.mum div { margin: 0; padding: 0; }
.mum cl-cd { display: block; position: relative; margin: 0 0 0 50px; padding: 0 0 0 10px; white-space: pre-wrap; overflow-wrap: break-word; border-left: 1px solid silver; }
.mum cl-cd::before { position: absolute; content: attr(data-idx); width: 50px; color: gray; text-align: right; transform: translate(-70px); }
.tRed { color: red; }
.tBlue { color: blue; }
.tGreen { color: green; }
.tDarkRed { color: darkred; }
.tMagenta { color: magenta; }
</style>

<h2>一楼完整代码</h2>
<div class='mum'>
<cl-cd data-idx="1">&lt;<span class="tDarkRed">canvas</span> <span class="tRed">id</span>=<span class="tMagenta">"canv"</span> style=<span class="tMagenta">"<span class="tBlue">display:</span> block; <span class="tBlue">margin:</span> auto; <span class="tBlue">border:</span> 1px solid gray; <span class="tBlue">background:</span> #333;"</span>&gt;&lt;<span class="tDarkRed">/canvas</span>&gt;</cl-cd>
<cl-cd data-idx="2">&lt;<span class="tDarkRed">p</span> style=<span class="tMagenta">"<span class="tBlue">margin-top:</span> 20px; <span class="tBlue">text-align:</span> center;"</span>&gt;</cl-cd>
<cl-cd data-idx="3">&nbsp; &nbsp; &lt;<span class="tDarkRed">button</span> <span class="tRed">id</span>=<span class="tMagenta">"btnGray"</span> type=<span class="tMagenta">"button"</span> value=<span class="tMagenta">"0"</span> disabled&gt;灰度&lt;<span class="tDarkRed">/button</span>&gt; &nbsp;</cl-cd>
<cl-cd data-idx="4">&nbsp; &nbsp; &lt;<span class="tDarkRed">button</span> <span class="tRed">id</span>=<span class="tMagenta">"btnRestore"</span> type=<span class="tMagenta">"button"</span> value=<span class="tMagenta">"1"</span>&gt;还原&lt;<span class="tDarkRed">/button</span>&gt;</cl-cd>
<cl-cd data-idx="5">&lt;<span class="tDarkRed">/p</span>&gt;</cl-cd>
<cl-cd data-idx="6">&nbsp;</cl-cd>
<cl-cd data-idx="7">&lt;<span class="tDarkRed">script</span>&gt;</cl-cd>
<cl-cd data-idx="8">(<span class="tBlue">function</span> () {</cl-cd>
<cl-cd data-idx="9">&nbsp; &nbsp; <span class="tBlue">var</span> btns = ;</cl-cd>
<cl-cd data-idx="10">&nbsp; &nbsp; <span class="tBlue"var</span> ctx = canv.getContext(<span class="tMagenta">'2d'</span>);</cl-cd>
<cl-cd data-idx="11">&nbsp; &nbsp; <span class="tBlue">var</span> ww, hh, imgData;</cl-cd>
<cl-cd data-idx="12">&nbsp;</cl-cd>
<cl-cd data-idx="13">&nbsp; &nbsp; <span class="tBlue">var</span> img = <span class="tBlue">new</span> Image();</cl-cd>
<cl-cd data-idx="14">&nbsp; &nbsp; img.crossOrigin = <span class="tMagenta">'anonymous'</span>;</cl-cd>
<cl-cd data-idx="15">&nbsp; &nbsp; img.onload = () =&gt; {</cl-cd>
<cl-cd data-idx="16">&nbsp; &nbsp; &nbsp; &nbsp; ww = canv.width = img.width;</cl-cd>
<cl-cd data-idx="17">&nbsp; &nbsp; &nbsp; &nbsp; hh = canv.height = img.height;</cl-cd>
<cl-cd data-idx="18">&nbsp; &nbsp; &nbsp; &nbsp; ctx.drawImage(img, 0, 0, ww, hh);</cl-cd>
<cl-cd data-idx="19">&nbsp; &nbsp; &nbsp; &nbsp; imgData = ctx.getImageData(0,0,ww,hh);</cl-cd>
<cl-cd data-idx="20">&nbsp; &nbsp; &nbsp; &nbsp; toGray(imgData);</cl-cd>
<cl-cd data-idx="21">&nbsp; &nbsp; };</cl-cd>
<cl-cd data-idx="22">&nbsp;</cl-cd>
<cl-cd data-idx="23">&nbsp; &nbsp; <span class="tBlue">var</span> toGray = (data) =&gt; {</cl-cd>
<cl-cd data-idx="24">&nbsp; &nbsp; &nbsp; &nbsp; <span class="tBlue">for</span>(<span class="tBlue">var</span> k = 0; k &lt; data.data.length; k += 4) {</cl-cd>
<cl-cd data-idx="25">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="tBlue">var</span> average = (data.data + data.data + data.data) / 3;</cl-cd>
<cl-cd data-idx="26">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; data.data = data.data = data.data = average;</cl-cd>
<cl-cd data-idx="27">&nbsp; &nbsp; &nbsp; &nbsp; }</cl-cd>
<cl-cd data-idx="28">&nbsp; &nbsp; &nbsp; &nbsp; ctx.clearRect(0, 0, ww, hh);</cl-cd>
<cl-cd data-idx="29">&nbsp; &nbsp; &nbsp; &nbsp; ctx.putImageData(data, 0, 0);</cl-cd>
<cl-cd data-idx="30">&nbsp; &nbsp; };</cl-cd>
<cl-cd data-idx="31">&nbsp;</cl-cd>
<cl-cd data-idx="32">&nbsp; &nbsp; btns.forEach(btn =&gt; {</cl-cd>
<cl-cd data-idx="33">&nbsp; &nbsp; &nbsp; &nbsp; btn.onclick = () =&gt; {</cl-cd>
<cl-cd data-idx="34">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; btn.value === <span class="tMagenta">'0'</span> ?</cl-cd>
<cl-cd data-idx="35">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (btns.disabled = true, btns.disabled = false, toGray(imgData)) :</cl-cd>
<cl-cd data-idx="36">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (btns.disabled = true, btns.disabled = false, ctx.drawImage(img, 0, 0));</cl-cd>
<cl-cd data-idx="37">&nbsp; &nbsp; &nbsp; &nbsp; };</cl-cd>
<cl-cd data-idx="38">&nbsp; &nbsp; });</cl-cd>
<cl-cd data-idx="39">&nbsp;</cl-cd>
<cl-cd data-idx="40">&nbsp; &nbsp; img.src = <span class="tMagenta">'https://638183.freep.cn/638183/t24/webp/xgj.webp'</span>;</cl-cd>
<cl-cd data-idx="41">})();</cl-cd>
<cl-cd data-idx="42">&lt;<span class="tDarkRed">/script</span>&gt;</cl-cd>
</div>

马黑黑 发表于 2024-4-24 19:52

第 14 行代码:跨域操作

如果图片与网页同源,请将改行代码去掉。需要注意的是,来自第三方网站的图片,不一定支持跨域操作,若此,请更换图片地址。

马黑黑 发表于 2024-4-24 19:58

canvas画布灰度化图像原理解释:

很简单,将图像每一个像素点的 rgb 值平均化(代码25、26行),然后重绘画布(代码27、28行)。

实现代码为什么偏多:

实现代码实际上不多,真正的灰度化图像代码也就在 toGray(data) 函数,不足十行。一楼考虑到交互问题,影响了代码总行数。



梦油 发表于 2024-4-24 19:59

小公主真漂亮哎!

马黑黑 发表于 2024-4-24 20:00

关键俺家小公举:这是一个美丽的梦想,俺家小公举没辣么漂酿{:4_170:}

马黑黑 发表于 2024-4-24 20:00

梦油 发表于 2024-4-24 19:59
小公主真漂亮哎!

看 6 楼{:4_173:}

朵拉 发表于 2024-4-24 20:17

马黑黑 发表于 2024-4-24 20:00
关键俺家小公举:这是一个美丽的梦想,俺家小公举没辣么漂酿

这位小公举 是夏天吧~~

马黑黑 发表于 2024-4-24 20:33

朵拉 发表于 2024-4-24 20:17
这位小公举 是夏天吧~~

没有呀。不姓夏,也不叫天,姓马名黑妞。

朵拉 发表于 2024-4-24 20:35

马黑黑 发表于 2024-4-24 20:33
没有呀。不姓夏,也不叫天,姓马名黑妞。

小公举不黑黑,老师您调皮{:4_189:}

马黑黑 发表于 2024-4-24 20:39

朵拉 发表于 2024-4-24 20:35
小公举不黑黑,老师您调皮

长大了会黑的

愤怒的葡萄 发表于 2024-4-24 20:58

这个真的是马版家的小公主?

南无月 发表于 2024-4-24 20:58

马黑黑 发表于 2024-4-24 19:52
第 14 行代码:跨域操作

如果图片与网页同源,请将改行代码去掉。需要注意的是,来自第三方网站的图片, ...

常用的能支持 就行。。一般不用别地方的

南无月 发表于 2024-4-24 21:01

马黑黑 发表于 2024-4-24 19:58
canvas画布灰度化图像原理解释:

很简单,将图像每一个像素点的 rgb 值平均化(代码25、26行),然后重 ...

{:4_170:}懂不懂的先看原理再说。
这个RGB值平均化,还不是很明白,所以呢,色彩课还要继续补

南无月 发表于 2024-4-24 21:02

马黑黑 发表于 2024-4-24 20:00
关键俺家小公举:这是一个美丽的梦想,俺家小公举没辣么漂酿

{:4_170:}一如既往的谦虚低调

醉美水芙蓉 发表于 2024-4-24 21:23

醉美水芙蓉 发表于 2024-4-24 21:24

红影 发表于 2024-4-24 21:29

“将图像每一个像素点的 rgb 值平均化”,原来灰度还能这样玩{:4_187:}

红影 发表于 2024-4-24 21:31

黑黑带来的很多东西之前都是闻所未闻呢{:4_187:}

马黑黑 发表于 2024-4-24 22:00

红影 发表于 2024-4-24 21:31
黑黑带来的很多东西之前都是闻所未闻呢

不会吧?这种效果很常见的
页: [1] 2 3 4 5 6 7
查看完整版本: 俺家的小公举(canvas画布灰度化图像)