溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

JavaScript如何實(shí)現(xiàn)簡(jiǎn)單獲取本地圖片主色調(diào)

發(fā)布時(shí)間:2023-03-07 14:10:58 來源:億速云 閱讀:192 作者:iii 欄目:開發(fā)技術(shù)

本篇內(nèi)容介紹了“JavaScript如何實(shí)現(xiàn)簡(jiǎn)單獲取本地圖片主色調(diào)”的有關(guān)知識(shí),在實(shí)際案例的操作過程中,不少人都會(huì)遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

    實(shí)現(xiàn)

    1、實(shí)現(xiàn)思路

    其實(shí)思路很簡(jiǎn)單,就是將一張大圖先縮小為一張小圖,再遍歷里面的像素,找到出現(xiàn)次數(shù)相對(duì)較高的一個(gè);當(dāng)然,先說明一下,這個(gè)也只能實(shí)現(xiàn)一個(gè)提取近似的值或者跟“人的意識(shí)”相反的值,因此,最終結(jié)果的“滿意程度”可能不是很好。

    2、實(shí)現(xiàn)代碼

    創(chuàng)建一個(gè) ThemeColor 操作對(duì)象,通過回調(diào)返回縮略圖主色調(diào) ,可進(jìn)行相關(guān)的其他操作

    //本地圖片資源
    let url = 'tree.webp'
    document.getElementById('originalImage').src = url
    let themeColor = new ThemeColor(url,(shrinkUrl,color)=>{
        //縮略圖
        let img = document.getElementById('showImage')
        if(img){
            img.setAttribute('src',shrinkUrl)
        }
        //主色
        document.getElementById('showDiv').style.backgroundColor = color
    })

    ThemeColor.js

    class ThemeColor{
        // 原圖資源
        imgUrl = ''
        // 像素集合
        originalPiexls = null
        // 縮略圖
        shrinkUrl = ''
        // 主色
        themeColor = 'white'
        // 回調(diào)
        themeColorCallBack = null
        // 提取像素出現(xiàn)最大次數(shù)操作對(duì)象
        colorCountedSet = new ColorCountedSet()
        
        constructor(imgUrl,callBack){
            this.imgUrl = imgUrl
            this.themeColorCallBack = callBack
            this.startScreeningThemeColor()
        }
        
        // 開始解析主色
        async startScreeningThemeColor(){
            try {
                await this.shrinkImage()
            } catch (error) {
                console.log('error:' + error)
            }
            this.screeningThemeColor()
        }
    
        // 圖片縮小
        async shrinkImage(){
            var image = new Image();
            image.src = this.imgUrl;
            await new Promise((resolve)=>{
                image.onload = resolve
            })
            let width = image.width
            let height = image.height
            let shrinkFactor = 10
            let shrinkWidth = width / shrinkFactor
            let shrinkHeight = height / shrinkFactor
            let canvas = document.createElement('canvas')
            canvas.setAttribute('width',`${shrinkWidth}px`)
            canvas.setAttribute('height',`${shrinkHeight}px`)
            var ctx = canvas.getContext("2d")
            ctx.drawImage(image,0,0,shrinkWidth,shrinkHeight)
            this.shrinkUrl = canvas.toDataURL('image/jpeg',1)
            try {
                //保存像素
                this.originalPiexls = ctx.getImageData(0,0,width,height)
            } catch (error) {
                console.log(error)
            }
        }
    
        // 開始篩選主題色
        screeningThemeColor(){
            if(!this.originalPiexls || !this.originalPiexls.data || this.originalPiexls.data.length == 0){
                throw('像素為空')
            }
            for(let i = 0;i < this.originalPiexls.data.length;i+=4){
                let r = this.originalPiexls.data[i]
                let g = this.originalPiexls.data[i + 1]
                let b = this.originalPiexls.data[i + 2]
                let a = this.originalPiexls.data[i + 3] / 255.0
                //添加一個(gè)色值范圍,讓它能忽略一定無效的像素值
                if(a > 0 && (r < 200 && g < 200 && b < 200) && (r > 50 && g > 50 && b > 50)){
                    this.colorCountedSet.push(r,g,b,a)
                }
            }
    
            let maxCount = 0
            // 尋找出現(xiàn)次數(shù)最多的像素定為主色調(diào)
            this.colorCountedSet.forEach((value,key)=>{
                if(maxCount <= value){
                    maxCount = value
                    this.themeColor = 'rgba(' + key + ')'
                }
            })
            //執(zhí)行回調(diào)
            if(this.themeColorCallBack){
                this.themeColorCallBack(this.shrinkUrl,this.themeColor)
            }
        }
     }
    
    // 統(tǒng)計(jì)不同像素的出現(xiàn)次數(shù)
    class ColorCountedSet{
        //像素集合
        map = new Map()
        
        //添加像素到集合
        push(r,g,b,a){
            //根據(jù)像素值生成一個(gè)map 元素 key值
            let identification = r + ',' + g + ',' + b + ',' + a
            if(!this.map.get(identification)){
                this.map.set(identification,1)
            } else {
                // 存在進(jìn)行次數(shù)自增
                let times = parseInt(this.map.get(identification)) + 1
                this.map.set(identification,times)
            }
        }
    
    // 給 ColorCountedSet 操作類添加一個(gè) forEach 方法 
    forEach(cb){
            this.map.forEach(function(value,key){
                    cb(value,key)
            });
        }
    }

    “JavaScript如何實(shí)現(xiàn)簡(jiǎn)單獲取本地圖片主色調(diào)”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!

    向AI問一下細(xì)節(jié)

    免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

    AI