国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

JavaScript中的圖片處理與合成(四)

Coding01 / 2276人閱讀

摘要:算法性能提升圖片算法處理實(shí)質(zhì)原理其實(shí)是遍歷像素點(diǎn),對(duì)像素點(diǎn)的值進(jìn)行改造。而像素點(diǎn)的數(shù)量與圖片的大小尺寸成正向指數(shù)級(jí)增長(zhǎng),因此適當(dāng)?shù)目s放圖片源后再去處理,對(duì)性能的提升十分巨大。

引言:

本系列現(xiàn)在構(gòu)思成以下4個(gè)部分:

基礎(chǔ)類型圖片處理技術(shù)之縮放、裁剪與旋轉(zhuǎn)(傳送門);

基礎(chǔ)類型圖片處理技術(shù)之圖片合成(傳送門);

基礎(chǔ)類型圖片處理技術(shù)之文字合成(傳送門);

算法類型圖片處理技術(shù)(傳送門);

通過(guò)這些積累,我封裝了幾個(gè)項(xiàng)目中常用的功能:

圖片合成 ??? 圖片裁剪 ??? 人像摳除

之前文章主要介紹了裁剪/旋轉(zhuǎn)/合成等基礎(chǔ)類型的圖片處理(文字的合成編寫中...???),我們開始來(lái)介紹算法類型的圖片處理技術(shù)!~~??????

這類型的重點(diǎn)主要在于 算法性能 層面,在前端由于js及設(shè)備性能的限制,通常表現(xiàn)并不理想。在真正的線上業(yè)務(wù)中,為了追求更好的用戶體驗(yàn),只能運(yùn)行一些相對(duì)比較輕量級(jí)的,性能好的算法。由服務(wù)端來(lái)進(jìn)行進(jìn)行,會(huì)是更好的選擇。

Tips: 由于我對(duì)算法方面并沒有很深的理解,因此本文主要是一些算法外層及基礎(chǔ)原理的講解,不涉及算法本身。希望大家諒解哈~?

我們以下面兩個(gè)?來(lái)做初步的了解:

(一) 萬(wàn)圣節(jié)小應(yīng)用

萬(wàn)圣節(jié)效果

效果圖如下:

這個(gè)小應(yīng)用是一個(gè)萬(wàn)圣節(jié)活動(dòng)。人物臉部的木偶妝容確實(shí)很炫酷,但是這里需要復(fù)雜的人臉識(shí)別,模型比對(duì)以及妝容算法,放在前端性能堪憂,因此讓服務(wù)端來(lái)處理,顯然是更好的選擇。而邊框和背景圖的模糊處理,這類型的處理就比較適合放在前端了,首先性能能接受,而且更具靈活性,能在不同入口隨時(shí)替換不同的邊框素材。

對(duì)于服務(wù)端的妝容算法,由于我對(duì)算法并沒有深入研究,在這里就不班門弄斧了,我們就直接來(lái)梳理下前端的部分:

發(fā)送原圖給服務(wù)端,接受 妝容處理 后的效果圖;

下載效果圖后,縮放成合適大小后進(jìn)行 模糊化處理 ,得到模糊后的結(jié)果圖;

將結(jié)果圖 / 模糊圖 / 邊框進(jìn)行 像素級(jí)的融合 ;

Tips: 這里使用的全是像素級(jí)別的算法融合,通過(guò)基礎(chǔ)類型的合成,同樣可以實(shí)現(xiàn)。
算法性能提升

圖片算法處理實(shí)質(zhì)原理其實(shí)是 遍歷像素點(diǎn),對(duì)像素點(diǎn)的RGBA值進(jìn)行改造。對(duì)于改造算法本身,本文就不深入了,不過(guò)可以與大家分享下相關(guān)的經(jīng)驗(yàn)。

眾所周知,一個(gè)好的算法,一個(gè)最重要的指標(biāo)便是性能,而如何提升性能呢?一種是 算法優(yōu)化 ,提高循環(huán)內(nèi)部的性能或者優(yōu)化遍歷算法,算法中的性能會(huì)由于遍歷的存在被放大無(wú)數(shù)倍。另一種則是 減少像素點(diǎn)

像素點(diǎn)的遍歷是一個(gè)算法的重要性能消耗點(diǎn),循環(huán)次數(shù)直接決定著算法的性能。而像素點(diǎn)的數(shù)量與圖片的大小尺寸成正向指數(shù)級(jí)增長(zhǎng),因此 適當(dāng)?shù)目s放圖片源后再去處理,對(duì)性能的提升十分巨大。例如一張2000*2000的圖片,像素點(diǎn)足足有400萬(wàn)個(gè),意味著需要遍歷400萬(wàn)次,而把圖片縮小成 800*800 時(shí),循環(huán)次數(shù)為64萬(wàn),這里我做過(guò)一個(gè)測(cè)試:

let st = new Date().getTime();
let imgData = [];
for (let i = 0; i < n * 10000; i += 4) {
    let r = getRandom(0,255),
        g = getRandom(0,255),
        b = getRandom(0,255),
        a = 1;
    if (r <= 30 && g <= 30 && b<= 30) a = 0;
    imgData[i] = r;
    imgData[i + 1] = g;
    imgData[i + 2] = b;
    imgData[i + 3] = a;
}
let et = new Date().getTime();
let t = et - st;
console.log(`${n}萬(wàn)次耗時(shí):${et - st}ms`, imgData);

測(cè)試結(jié)果為(mac-chrome-20次取平均):

圖片尺寸 像素?cái)?shù)量 耗時(shí)(ms) 縮放倍數(shù) 提升
2000*2000 400萬(wàn) 168 1 0%
1600*1600 256萬(wàn) 98 0.8 42%
1200*1200 144萬(wàn) 64 0.6 62%
800*800 64萬(wàn) 32 0.4 81%
400*400 16萬(wàn) 10 0.2 94%

可以看出圖片的縮小,對(duì)性能有非常顯著的提升。這里有個(gè)特點(diǎn),性能收益會(huì)隨著縮放系數(shù)的變大而越來(lái)越低,當(dāng)縮放系數(shù)為0.8時(shí),性能已經(jīng)大大提升了42%,而繼續(xù)縮放為0.6時(shí),收益便開始大幅降低,只提升了20%。同時(shí)縮放圖片意味著質(zhì)量的下降,所以這里需要尋找一個(gè) 平衡點(diǎn) ,在不影響結(jié)果圖效果的前提下,盡可能地提升性能,這需要根據(jù)算法對(duì)圖片質(zhì)量的要求來(lái)定。

另外,對(duì) 原圖的裁剪也是個(gè)很好的辦法,裁剪掉多余的背景部分,也能達(dá)到減少遍歷次數(shù),提升性能的效果。

模糊算法

小應(yīng)用中模糊部分使用的是 StackBlur.js 的模糊算法,應(yīng)用代碼如下:

// 縮放妝容圖;
let srcImg = scaleMid(imgData);

// 創(chuàng)建模糊結(jié)果圖的容器;
let blurCvs = document.createElement("canvas"),
    blurCtx = blurCvs.getContext("2d");

// 先復(fù)制一份原圖數(shù)據(jù),;
let blurImg = blurCtx.createImageData(srcImg.width, srcImg.height);
let size = srcImg.width * srcImg.height * 4;
for (let i = 0; i < size; i++) {
    blurImg.data[i] = srcImg.data[i];
}

// 縮放成400*400的大小;
blurImg = scale(blurImg, 400);

// 進(jìn)行模糊處理;
StackBlur.imageDataRGBA(blurImg, 0, 0, blurImg.width, blurImg.height, 1);

// 處理完后再放大為800*800;
blurImg = scale(blurImg, 800);
圖像融合

我們已經(jīng)準(zhǔn)備好合成最終效果圖的所有素材了,模糊背景 / 妝容圖 / 邊框素材,最后一步便是將三者進(jìn)行融合,融合的原理是 根據(jù)最終效果圖分區(qū)域,在不同區(qū)域分別填入對(duì)應(yīng)的素材數(shù)據(jù):

// 圖片融合
function mix(src, blur, mtl) {
      // 最終結(jié)果圖為固定800*800;縱向800的數(shù)據(jù);
    for (let i = 0; i < 800; i++) {
        let offset1 = 800 * i;
        
        // 橫向800的數(shù)據(jù);
        for (let j = 0; j < 800; j++) {
            let offset = (offset1 + j) * 4;
            
            // 在特定的位置填入素材;
            if (i <= 75 || i >= 609 || j <= 126 || j >= 676) {
                let alpha = mtl.data[offset + 3] / 255.0;
                mtl.data[offset] = alpha * mtl.data[offset] + (1 - alpha) * blur.data[offset];
                mtl.data[offset + 1] = alpha * mtl.data[offset + 1] + (1 - alpha) * blur.data[offset + 1];
                mtl.data[offset + 2] = alpha * mtl.data[offset + 2] + (1 - alpha) * blur.data[offset + 2];
                mtl.data[offset + 3] = 255;
            } else {
                let alpha = mtl.data[offset + 3] / 255.0;
                let x = i - 75;
                let y = j - 126;
                let newOffset = (x * 550 + y) * 4;
                mtl.data[offset] = alpha * mtl.data[offset] + (1 - alpha) * src.data[newOffset];
                mtl.data[offset + 1] = alpha * mtl.data[offset + 1] + (1 - alpha) * src.data[newOffset + 1];
                mtl.data[offset + 2] = alpha * mtl.data[offset + 2] + (1 - alpha) * src.data[newOffset + 2];
                mtl.data[offset + 3] = 255;
            }
        }
    }
    return mtl;
}
(二) 摳除人像

這是一個(gè)基于服務(wù)端的人像mask層,在前端把人像摳出的服務(wù),這樣便可以進(jìn)一步做背景的融合和切換,現(xiàn)在已經(jīng)用在多個(gè)線上項(xiàng)目中了。

人像摳除)

這里需要基于由服務(wù)端處理后的兩張效果圖:

帶背景的結(jié)果圖和mask圖:

1、我們需要先將mask圖進(jìn)行處理:

// 繪制mask;
// mask_zoom: 既為了優(yōu)化性能所做的縮放系數(shù);
mask = document.createElement("canvas");
maskCtx = mask.getContext("2d");
mask.width = imgEl.naturalWidth * ops.mask_zoom;
mask.height = imgEl.naturalHeight * ops.mask_zoom / 2;
maskCtx.drawImage(imgEl, 0, - imgEl.naturalHeight * ops.mask_zoom / 2, imgEl.naturalWidth * ops.mask_zoom , imgEl.naturalHeight * ops.mask_zoom);

2、去除mask的黑色背景,變成透明色,這里需要用到像素操作:

// 獲取圖片數(shù)據(jù);
let maskData = maskCtx.getImageData(0, 0, mask.width, mask.height);

// 遍歷改造像素點(diǎn),將接近黑色的點(diǎn)的透明度改成0;
for (let i = 0; i < data.length; i += 4) {
    let r = data[i],
        g = data[i + 1],
        b = data[i + 2];
        
    if (r <= 30 && g <= 30 && b<= 30)data[i + 3] = 0;
}

// 將改造后的數(shù)據(jù)重新填回mask層中;
maskCtx.putImageData(maskData, 0, 0);

3、圖像融合,這里用到了一個(gè)神奇的canvas方法,相信大家聽過(guò),但并不熟悉 --- globalCompositeOperation,該值可以修改canvas的融合模式,有多種融合模式大家可以自行研究,這里使用的是source-in;

// 創(chuàng)建最終效果圖容器;
result = document.createElement("canvas");
resultCtx = result.getContext("2d");
result.width = imgEl.naturalWidth;
result.height = imgEl.naturalHeight;

// 先繪制mask圖層做為背景;
resultCtx.drawImage(mask, 0, 0, imgEl.naturalWidth, imgEl.naturalHeight);

// 修改融合模式
resultCtx.globalCompositeOperation = "source-in";

// 繪制帶背景的結(jié)果圖
resultCtx.drawImage(origin, 0, 0);

最終得到的效果圖:

最后就可以使用這種人像圖與任何背景或者素材根據(jù)業(yè)務(wù)需求再做融合了。

結(jié)語(yǔ)

算法部分由于本人才疏學(xué)淺,沒辦法深入闡述,只能分享一些比較粗淺的經(jīng)驗(yàn),期望能在未來(lái)往更底層的領(lǐng)域發(fā)展。

不過(guò)還是期望能對(duì)大家有所啟發(fā)。~~有圖片處理興趣的童鞋,可以隨時(shí)與我探討哈,期望得到大神的指導(dǎo),也希望js能在圖片處理領(lǐng)域有更快的發(fā)展。

感謝大家的閱讀。~~~????。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/93209.html

相關(guān)文章

  • JavaScript中的圖片處理合成(一)

    摘要:中的圖片處理與合成一引言圖片處理現(xiàn)在已經(jīng)成為了我們生活中的剛需,想必大家也經(jīng)常有這方面的需求。實(shí)際前端業(yè)務(wù)中,也經(jīng)常會(huì)有很多的項(xiàng)目需要用到圖片加工和處理。 JavaScript中的圖片處理與合成(一) 引言: 圖片處理現(xiàn)在已經(jīng)成為了我們生活中的剛需,想必大家也經(jīng)常有這方面的需求。實(shí)際前端業(yè)務(wù)中,也經(jīng)常會(huì)有很多的項(xiàng)目需要用到圖片加工和處理。由于過(guò)去一段時(shí)間公司的業(yè)務(wù)需求,讓我在這方面積累...

    Charles 評(píng)論0 收藏0
  • JavaScript中的圖片處理合成(二)

    摘要:通過(guò)這套流程,我們便能添加任意的圖片圖層并合成圖片。下篇文章,我們會(huì)繼續(xù)介紹下文字的合成和幾何圖片的合成,敬請(qǐng)期待 JavaScript中的圖片處理與合成(二) 引言 本系列分成以下4個(gè)部分: 基礎(chǔ)類型圖片處理技術(shù)之縮放、裁剪與旋轉(zhuǎn)(傳送門); 基礎(chǔ)類型圖片處理技術(shù)之圖片合成; 基礎(chǔ)類型圖片處理技術(shù)之文字合成; 算法類型圖片處理技術(shù); 上篇文章,我們介紹了圖片的裁剪/旋轉(zhuǎn)與縮放,接...

    hersion 評(píng)論0 收藏0
  • Webkit 渲染基礎(chǔ)硬件加速

    摘要:網(wǎng)頁(yè)的渲染方式主要有兩種軟件渲染和硬件加速渲染。而使用合成化的渲染技術(shù),以使用軟件繪圖的合成化渲染為例,對(duì)于使用繪制的層,其結(jié)果保存在內(nèi)存中,之后傳輸?shù)街羞M(jìn)行合成。 Webkit 渲染基礎(chǔ)與硬件加速 當(dāng)瀏覽器加載一個(gè) html 文件并對(duì)它進(jìn)行解析完畢后,內(nèi)核就會(huì)生成一個(gè)極為重要的數(shù)據(jù)結(jié)構(gòu)即 DOM 樹,樹上每一個(gè)節(jié)點(diǎn)都對(duì)應(yīng)著網(wǎng)頁(yè)里面的某一個(gè)元素,并且開發(fā)人員也可以通過(guò) JavaScri...

    ivan_qhz 評(píng)論0 收藏0
  • 重學(xué)前端學(xué)習(xí)筆記(十五)--瀏覽器工作解析(五)

    摘要:五繪制把任何位圖合成到最終位圖的操作稱為繪制。個(gè)人總結(jié)這一節(jié)主要講解了瀏覽器中的位圖操作部分,包括渲染合成和繪制三個(gè)部分。作業(yè)用實(shí)現(xiàn)一個(gè)玩具瀏覽器。。。。 筆記說(shuō)明 重學(xué)前端是程劭非(winter)【前手機(jī)淘寶前端負(fù)責(zé)人】在極客時(shí)間開的一個(gè)專欄,每天10分鐘,重構(gòu)你的前端知識(shí)體系,筆者主要整理學(xué)習(xí)過(guò)程的一些要點(diǎn)筆記以及感悟,完整的可以加入winter的專欄學(xué)習(xí)【原文有winter的語(yǔ)音...

    iliyaku 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<