成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

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

hersion / 601人閱讀

摘要:通過這套流程,我們便能添加任意的圖片圖層并合成圖片。下篇文章,我們會繼續(xù)介紹下文字的合成和幾何圖片的合成,敬請期待

JavaScript中的圖片處理與合成(二) 引言

本系列分成以下4個部分:

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

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

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

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

上篇文章,我們介紹了圖片的裁剪/旋轉(zhuǎn)與縮放,接下來本文主要介紹 圖片的合成 ,這是基礎(chǔ)類圖片處理中比較實用且復(fù)雜的一部分,可以算第一篇文章內(nèi)容的實踐。

通過這些積累,我封裝了幾個項目中常用的功能:

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

圖片的合成在實際項目中運用也是十分的廣泛,大家可以試試這個demo(僅支持移動端): ???

小狗貼紙

圖片的合成原理其實類似于photoshop的理念,通過 圖層的疊加 ,最后合成并導(dǎo)出,相比于裁剪和縮放,其實基本原理是一致的,但是它涉及了更多的計算和比較復(fù)雜的流程,我們先一起來梳理下合成的整個邏輯。

相信大家對 photoshop都是較為了解的,我們可以借鑒它的思維方式:

新建 psd 文件, 設(shè)置寬高;

設(shè)置背景圖;

從底部到頂部一層層添加所需要的圖層;

最后直接將整個文件導(dǎo)出成一張圖片;

以需要合成下圖為?:

1、首先我們需要創(chuàng)建一個與原圖一樣大小的畫布;

2、加載背景圖并 添加背景圖層 ,也就是這個美女啦~

3、加載貓耳朵圖并添加美女頭上的 貓耳朵圖層 ( 2/3順序不可逆,否則耳朵會被美女蓋在下面哦。因此圖片的加載控制十分重要 );

4、將整個畫布 導(dǎo)出圖片 ;

合成部分,主要以封裝的插件為栗子哈。這樣能盡可能的完整,避免遺漏點。在開始之前,為了確保圖片異步繪制的順序,我們需要先來構(gòu)建一套隊列系統(tǒng)。

隊列系統(tǒng);

圖片的加載時間是 異步且未知 的,而圖片的合成需要嚴格保證繪制 順序 ,越后繪制的圖片會置于越頂層,因此我們需要一套嚴格機制來控制圖片的加載與繪制,否則我們將無法避免的寫出 回調(diào)地獄 ,這里我使用到了簡單的隊列系統(tǒng);

隊列系統(tǒng)的原理其實也很簡單,主要是為了我們能確保圖層從底到頂一層一層的繪制。我設(shè)計的使用方式如下, 隊列方式主要來確保add函數(shù)的按順序繪制:

// 創(chuàng)建畫布;
let mc = new MCanvas();

// 添加圖層;
mc.add(image-1).add(image-2);

// 繪制并導(dǎo)出圖片;
mc.draw();

這樣我們就明白了,這個隊列系統(tǒng)需要下面幾個點:

queue隊列: 用于存放圖層繪制函數(shù);

next函數(shù): 用于表示當前圖層已繪制完畢,執(zhí)行下一圖層的繪制;

add函數(shù): 作為統(tǒng)一添加圖層的方法,將繪制邏輯存入函數(shù)棧quene,并包裹next函數(shù);

draw函數(shù): 作為繪制啟動函數(shù),表示所有圖層素材已經(jīng)準備完畢,可以按順序開始繪制;

MCanvas.queue = [];

MCanvas.prototype.add = function(){
    this.queue.push(()=>{
        // 繪制邏輯,之后詳解;
        ...
        
        // 執(zhí)行下個圖層繪制;
        this.next();
    });
}

MCanvas.prototype.next = function(){
    if(this.queue.length > 0){
            // 當隊列中還有繪制任務(wù)時,則推出并執(zhí)行;
        this.queue.shift()();
    }else{
            // 當繪制完成后,調(diào)用成功事件,并傳出結(jié)果圖;
        this.fn.success();
    }
};

MCanvas.prototype.draw = function(){
    // 導(dǎo)出邏輯;
    ...
    
    // 設(shè)置成功事件,用于導(dǎo)出結(jié)果圖;    
    this.fn.success = () => {
         // 使用 setTimeout 能略微提升性能表現(xiàn);
         // 且隊列函數(shù)中都為真正的異步,因此此處不會影響邏輯;
        setTimeout(()=>{
            b64 = this.canvas.toDataURL(`image/jpeg}`, 0.9);
            
            ...
        },0);
   };
   
   // 啟動隊列執(zhí)行;
    this.next();
}

此時,queueadd、nextdraw便組成了一整套隊列系統(tǒng),可確保圖片的順序加載和繪制,準備好素材和隊列后,我們便可以開始真正的合成圖片咯~~

創(chuàng)建畫布
MCanvas.prototype._init = function(){
    this.canvas = document.createElement("canvas");
    this.ctx = this.canvas.getContext("2d");
};
繪制背景圖

設(shè)置畫布大小并繪制美女背景圖。

通過調(diào)整背景圖的dx,dy,dw,dh參數(shù),可以繪制出多種模式,類似于css中的background-sizecontain/cover等效果。

這里主要以上面使用到的場景為例子,既原圖模式。

// 原圖/效果圖尺寸保持一致;
MCanvas.prototype.background = function(image, bgOps){
    // 推入隊列系統(tǒng);
    this.queue.push(() => {
    let { iw, ih } = this._getSize(img);
        
    // 圖片與canvas的長寬比;
    let iRatio = iw / ih;
        
    // 背景繪制參數(shù);
    let dx,dy,dwidth,dheight;
        
    // 設(shè)置畫布與背景圖尺寸一致;
    this.canvas.width = iw;
    this.canvas.height = ih;
    dx = dy = 0;
    dwidth = this.canvas.width;
    dheight = this.canvas.height;
        
    // 繪制背景圖;
    this.ctx.drawImage(img,dx,dy,dwidth,dheight);
        
    this._next(); 
    });
    return this;
};
繪制貓耳朵貼紙

相信大家都玩過貼紙,其最大的特點,就是貼紙與背景圖的匹配。也就是用戶可以修改貼紙的 大小,位置,旋轉(zhuǎn)角度,通過手勢操作將貓耳朵完美地貼在照片人物的頭上。因此也就是說add這個方法,需要設(shè)置縮放,旋轉(zhuǎn)與位置等參數(shù)。

這里先模擬出一份使用參數(shù), 實際真實情況會根據(jù)不同的背景圖,用戶會調(diào)整出不同的位置參數(shù)。

{
    // 圖片路徑;
    image:"./images/ear.png",
    options:{
        // 貼紙寬度;
        width:482,
        pos:{
            // 貼紙左上點坐標;
            x:150,
            y:58,
            // 貼紙放大系數(shù);
            scale:1,
            // 貼紙旋轉(zhuǎn)系數(shù);
            rotate:35,
        },
    },
}
add函數(shù)

接下里我們便來在add函數(shù)中解析下各個參數(shù)的使用姿勢:

繪制小畫布來處理旋轉(zhuǎn):

// 創(chuàng)建小畫布;
let lcvs = document.createElement("canvas"),
    lctx = lcvs.getContext("2d");

// 貼紙圖原始大小;
let { iw, ih } = this._getSize(img);
// 繪制參數(shù);
let ldx, ldy, ldw, ldh;

// 貼紙原始尺寸;
ldw = iw;
ldh = ih;

// 繪制起始點;
ldx = - Math.round(ldw / 2);
ldy = - Math.round(ldh / 2);

// 上篇文章我們說過旋轉(zhuǎn)裁剪的問題,這里就需要用到;
// 需要擴大小畫布的容器,以避免旋轉(zhuǎn)造成的裁剪;最大值為放大5倍;
let _ratio = iw > ih ? iw / ih : ih / iw;
let lctxScale = _ratio * 1.4 > 5 ? 5 : _ratio * 1.4;

lcvs.width =  ldw * lctxScale;
lcvs.height = ldh * lctxScale;

// 調(diào)整繪制基點;
lctx.translate(lcvs.width/2,lcvs.height/2);

// 旋轉(zhuǎn)畫板;
lctx.rotate(ops.pos.rotate);

// 繪制貼紙; 
lctx.drawImage(img,ldx,ldy,ldw,ldh);

此時我們會得到一個小畫布,中心繪制這貓耳朵貼紙:

接下來我們便是將貼紙繪制到背景圖上,需要注意的點就是,放大會增加貼紙畫布的空白區(qū)域,需要考慮到這部分區(qū)域,才能計算出最后真實的dx,dy值:

// 繪制參數(shù);
let cratio = iw / ih;
let cdx, cdy, cdw, cdh;

// ops.width 為最終畫到大畫布上時的寬度;
// 由于小畫布進行了放大,因此最終寬度也需要等倍放大;
// 并乘以配置中還需要縮放的系數(shù);
cdw = ops.width * lctxScale * ops.pos.scale;
cdh = cdw / cratio * ops.pos.scale;

// 放大后增加的空白區(qū)域;
spaceX = (lctxScale - 1) * ops.width / 2;
spaceY = spaceX / cratio;

// 獲取素材的最終位置;
// 配置的位置 - 配置放大系數(shù)的影響 - 小畫布放大倍數(shù)的影響;
cdx = ops.pos.x + cdw * ( 1 - ops.pos.scale )/2 - spaceX;
cdy = ops.pos.y + cdh * ( 1 - ops.pos.scale )/2 - spaceY;

this.ctx.drawImage(lcvs,cdx,cdy,cdw,cdh);

lcvs = lctx = null;

這樣便能得到合成后的結(jié)果圖了,紅色邊框代表小畫布,黑色邊框代表大畫布:

MCanvas.prototype.add = function(img, options){
    this.queue.push(()=>{
        // 繪制貼紙小畫布;
        ...
        
        // 繪制貼紙到大畫布上;
        ...
        
        this._next();
    });
    
    return this;
}

這樣我們便完成了一系列方法,構(gòu)建了一套完整的合成流程。通過這套流程,我們便能添加任意的圖片圖層并合成圖片。

結(jié)語

本文主要講解了圖片合成上的方法原理和一些需要填的坑,這整套流程也是經(jīng)過了很長一段時間的打磨,填了許多坑后總結(jié)出來的,算比較成熟的方案,已經(jīng)work在多個線上項目中,期望能對大家有所幫助!?。
下篇文章,我們會繼續(xù)介紹下文字的合成和幾何圖片的合成,敬請期待~~??

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

轉(zhuǎn)載請注明本文地址:http://m.hztianpu.com/yun/93183.html

相關(guān)文章

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

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

    Charles 評論0 收藏0
  • JavaScript中的圖片處理合成(四)

    摘要:算法性能提升圖片算法處理實質(zhì)原理其實是遍歷像素點,對像素點的值進行改造。而像素點的數(shù)量與圖片的大小尺寸成正向指數(shù)級增長,因此適當?shù)目s放圖片源后再去處理,對性能的提升十分巨大。 引言: 本系列現(xiàn)在構(gòu)思成以下4個部分: 基礎(chǔ)類型圖片處理技術(shù)之縮放、裁剪與旋轉(zhuǎn)(傳送門); 基礎(chǔ)類型圖片處理技術(shù)之圖片合成(傳送門); 基礎(chǔ)類型圖片處理技術(shù)之文字合成(傳送門); 算法類型圖片處理技術(shù)(傳送門)...

    Coding01 評論0 收藏0
  • Webkit 渲染基礎(chǔ)硬件加速

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

    ivan_qhz 評論0 收藏0

發(fā)表評論

0條評論

閱讀需要支付1元查看
<