JavaScript實現(xiàn)簡單獲取本地圖片主色調(diào)
一、實現(xiàn)效果
鮮花

大海

森林

二、實現(xiàn)
1、實現(xiàn)思路
其實思路很簡單,就是將一張大圖先縮小為一張小圖,再遍歷里面的像素,找到出現(xiàn)次數(shù)相對較高的一個;當然,先說明一下,這個也只能實現(xiàn)一個提取近似的值或者跟“人的意識”相反的值,因此,最終結果的“滿意程度”可能不是很好。
2、實現(xiàn)代碼
創(chuàng)建一個 ThemeColor 操作對象,通過回調(diào)返回縮略圖、主色調(diào) ,可進行相關的其他操作
//本地圖片資源
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ù)操作對象
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
//添加一個色值范圍,讓它能忽略一定無效的像素值
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)計不同像素的出現(xiàn)次數(shù)
class ColorCountedSet{
//像素集合
map = new Map()
//添加像素到集合
push(r,g,b,a){
//根據(jù)像素值生成一個map 元素 key值
let identification = r + ',' + g + ',' + b + ',' + a
if(!this.map.get(identification)){
this.map.set(identification,1)
} else {
// 存在進行次數(shù)自增
let times = parseInt(this.map.get(identification)) + 1
this.map.set(identification,times)
}
}
// 給 ColorCountedSet 操作類添加一個 forEach 方法
forEach(cb){
this.map.forEach(function(value,key){
cb(value,key)
});
}
}三、總結與思考
內(nèi)容沒什么特別復雜的,之前做移動端的時候有這么一個需求,其實實現(xiàn)的思路都是一樣的,這里就是一個拋磚引玉的作用,希望能給需要的人提供一個思路,如果能幫助大家,深感欣慰,代碼拙劣,大神勿笑[抱拳][抱拳][抱拳]
以上就是JavaScript實現(xiàn)簡單獲取本地圖片主色調(diào)的詳細內(nèi)容,更多關于JavaScript獲取圖片主色調(diào)的資料請關注腳本之家其它相關文章!
相關文章
js監(jiān)聽滾動條滾動事件使得某個標簽內(nèi)容始終位于同一位置
js如何監(jiān)聽滾動條滾動事件,使得某個標簽內(nèi)容始終位于同一位置,下面有個不錯的示例,大家可以參考下2014-01-01
在iframe中使bootstrap的模態(tài)框在父頁面彈出問題
這篇文章主要介紹了在iframe中使bootstrap的模態(tài)框在父頁面彈出問題,解決方法非常不錯,具有參考借鑒價值,需要的朋友可以參考下2017-08-08
js中常見的4種創(chuàng)建對象方式與優(yōu)缺點
不管是哪門語言,千變?nèi)f化不離其宗,深入理解其本質(zhì),方能應用自如,下面這篇文章主要給大家介紹了關于js中常見的4種創(chuàng)建對象方式與優(yōu)缺點,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下2022-01-01
javascript Array.remove() 數(shù)組刪除
下面的代碼主要是實現(xiàn)了,刪除數(shù)組中指定的值。2009-08-08
Cropper.js進階之實現(xiàn)圓形頭像裁剪功能示例
這篇文章主要為大家介紹了Cropper.js進階之實現(xiàn)圓形頭像裁剪功能示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-05-05

