非常常用的效果哦,亲测可用
![](https://i-blog.csdnimg.cn/blog_migrate/3f34868a87134438788ebe80b9447001.gif)
**注意**
首先这里用到了uni里面的api方法(uni.getImageInfo()、uni.createCanvasContext()和uni.canvasGetImageData())
这里面有个大坑,就是success返回的值传递不了全局变量(需要定义var _this=this)
//获取图片主题色方法
getImage() {
// 获得图片信息
var _this = this
uni.getImageInfo({
// 注意图片的地址
src: this.src,
success(res) {
console.log(res.path)
let imgHeight = 100;
let imgWidth = 100;
var ctx = uni.createCanvasContext("logo") // 使用画布创建上下文 图片
ctx.drawImage(res.path, 0, 0, 100, 100) // 设置图片坐标及大小,括号里面的分别是(图片路径,x坐标,y坐标,width,height)
ctx.save(); //保存
ctx.draw(true, () => {
uni.canvasGetImageData({
canvasId: 'logo',
x: 0,
y: 0,
width: 100,
height: 100,
success: (res) => {
let data = res.data;
let arr = []
var r = 1,
g = 1,
b = 1;
// 取所有像素的平均值
for (var row = 0; row < imgHeight; row++) {
for (var col = 0; col < imgWidth; col++) {
// console.log(data[((img.width * row) + col) * 4])
if (row == 0) {
r += data[((imgWidth * row) + col)];
g += data[((imgWidth * row) + col) + 1];
b += data[((imgWidth * row) + col) + 2];
arr.push([r, g, b])
} else {
r += data[((imgWidth * row) + col) * 4];
g += data[((imgWidth * row) + col) * 4 + 1];
b += data[((imgWidth * row) + col) * 4 + 2];
arr.push([r, g, b])
}
}
}
console.log(arr[8000])
// 求取平均值
r /= (imgWidth * imgHeight);
g /= (imgWidth * imgHeight);
b /= (imgWidth * imgHeight);
// 将最终的值取整
r = Math.round(r);
g = Math.round(g);
b = Math.round(b);
let obj = {
r,
g,
b
}
console.log(obj)
let rgbaA = 'rgba(' + obj.r + ',' + obj.g + ',' + obj.b +
',' +
0.8 + ')'
let colorChange = _this.$colorChange.getHexColor(rgbaA)
console.log(colorChange, '转化后的颜色')
_this.bg = colorChange
uni.setNavigationBarTitle({
title: '首页'
})
uni.setNavigationBarColor({
frontColor: '#ffffff', // 必写项【该字体颜色仅支持 #ffffff 和 #000000 】
backgroundColor: _this
.bg, // 传递的颜色值【仅支持有效值为十六进制颜色】
// animation: { // 可选项
// duration: 100,
// timingFunc: 'easeIn'
// }
})
},
fail: (fail) => {
console.log(fail)
}
})
})
}
})
},
其次进行画布取图像的像素点 (这里需要注意画布不能隐藏或删除)
我想到的方法可以把这个画布顶出去
<view class="text-area" style=" position: fixed;top: -99999rpx;">
<canvas style="width:220rpx;height:86rpx;" canvas-id="logo"></canvas>
</view>
c.最后需要注意的一点就是,导航栏颜色必须是16进制,否则会不起作用
uni.setNavigationBarTitle({
title: '首页'
})
uni.setNavigationBarColor({
frontColor: '#ffffff', // 必写项【该字体颜色仅支持 #ffffff 和 #000000 】
backgroundColor: '#25BDCE', // 传递的颜色值【仅支持有效值为十六进制颜色】
animation: { // 可选项
duration: 4000,
timingFunc: 'easeIn'
}
})
d.取值到的rgb转换为16进制封装方法
//rgab转化为十六进制颜色
export default {
getHexColor(color) { // 传的color须为字符串
var values = color
.replace(/rgba?\(/, '') // 把 "rgba(" 去掉,变成 "194, 7, 15, 1)"
.replace(/\)/, '') // 把 ")" 去掉,变成 "194, 7, 15, 1"
.replace(/[\s+]/g, '') // 把空格去掉,变成 "194,7,15,1"
.split(',') // 变成数组 [194,7,15,1]
var a = parseFloat(values[3] || 1), // values[3]是rgba中的a值,没有的话设置a为1,a可能为小数,所以用parseFloat函数
r = Math.floor(a * parseInt(values[0]) + (1 - a) * 255), // 转换为16进制
g = Math.floor(a * parseInt(values[1]) + (1 - a) * 255),
b = Math.floor(a * parseInt(values[2]) + (1 - a) * 255)
return '#' +
('0' + r.toString(16)).slice(-2) + // 转换后的16进制可能为一位,比如 7 就转换为 7 , 15 转换为 f
('0' + g.toString(16)).slice(-2) + // 当为一位的时候就在前面加个 0,
('0' + b.toString(16)).slice(-2) // 若是为两位,加 0 后就变成了三位,所以要用 slice(-2) 截取后两位
}
}
//使用
let colorChange = _this.$colorChange.getHexColor(rgbaA)
全部代码(根据自己需求改变)
<template>
<view class="content">
<u-swiper :list="list3" indicator indicatorMode="line" circular height="160" @change="changeLb"></u-swiper>
<view class="text-area" style=" position: fixed;
top: -9999999999999rpx;">
<canvas style="width:220rpx;height:86rpx;" canvas-id="logo"></canvas>
</view>
</view>
</template>
<script>
export default {
data() {
return {
bg: 'orange',
list3: [
'https://cdn.uviewui.com/uview/swiper/swiper3.png',
'https://cdn.uviewui.com/uview/swiper/swiper2.png',
'https://cdn.uviewui.com/uview/swiper/swiper1.png',
],
src: 'https://cdn.uviewui.com/uview/swiper/swiper3.png'
}
},
onLoad: function() {
this.getImage()
this.src = this.list3[0]
},
methods: {
changeLb(e) {
console.log(e, '索引')
console.log(this.list3[e.current])
this.src = this.list3[e.current]
this.getImage()
},
//获取图片主题色
getImage() {
// 获得图片信息
var _this = this
uni.getImageInfo({
// 注意图片的地址
src: this.src,
success(res) {
console.log(res.path)
let imgHeight = 100;
let imgWidth = 100;
var ctx = uni.createCanvasContext("logo") // 使用画布创建上下文 图片
ctx.drawImage(res.path, 0, 0, 100, 100) // 设置图片坐标及大小,括号里面的分别是(图片路径,x坐标,y坐标,width,height)
ctx.save(); //保存
ctx.draw(true, () => {
uni.canvasGetImageData({
canvasId: 'logo',
x: 0,
y: 0,
width: 100,
height: 100,
success: (res) => {
let data = res.data;
let arr = []
var r = 1,
g = 1,
b = 1;
// 取所有像素的平均值
for (var row = 0; row < imgHeight; row++) {
for (var col = 0; col < imgWidth; col++) {
// console.log(data[((img.width * row) + col) * 4])
if (row == 0) {
r += data[((imgWidth * row) + col)];
g += data[((imgWidth * row) + col) + 1];
b += data[((imgWidth * row) + col) + 2];
arr.push([r, g, b])
} else {
r += data[((imgWidth * row) + col) * 4];
g += data[((imgWidth * row) + col) * 4 + 1];
b += data[((imgWidth * row) + col) * 4 + 2];
arr.push([r, g, b])
}
}
}
console.log(arr[8000])
// 求取平均值
r /= (imgWidth * imgHeight);
g /= (imgWidth * imgHeight);
b /= (imgWidth * imgHeight);
// 将最终的值取整
r = Math.round(r);
g = Math.round(g);
b = Math.round(b);
let obj = {
r,
g,
b
}
console.log(obj)
let rgbaA = 'rgba(' + obj.r + ',' + obj.g + ',' + obj.b +
',' +
0.8 + ')'
let colorChange = _this.$colorChange.getHexColor(rgbaA)
console.log(colorChange, '转化后的颜色')
_this.bg = colorChange
uni.setNavigationBarTitle({
title: '首页'
})
uni.setNavigationBarColor({
frontColor: '#ffffff', // 必写项【该字体颜色仅支持 #ffffff 和 #000000 】
backgroundColor: _this
.bg, // 传递的颜色值【仅支持有效值为十六进制颜色】
// animation: { // 可选项
// duration: 100,
// timingFunc: 'easeIn'
// }
})
},
fail: (fail) => {
console.log(fail)
}
})
})
}
})
},
}
}
</script>
<style>
.content {
width: 700rpx;
margin: 25rpx;
}
.logo {
height: 200rpx;
width: 200rpx;
margin-top: 200rpx;
margin-left: auto;
margin-right: auto;
margin-bottom: 50rpx;
}
.text-area {
display: flex;
justify-content: center;
}
.title {
font-size: 36rpx;
color: #8f8f94;
}
.demo {
width: 300rpx;
line-height: 120rpx;
height: 120rpx;
background-color: azure;
text-align: center;
margin: 0 auto;
}
</style>