当前位置: 首页 > news >正文

动态设置图片的主题色(保留明暗关系)

github地址

PrimaryColorDemo

效果

原始图片

就是一张普通的png图片
image.png

根据选择的主题色动态渲染。

在这里插入图片描述

思考

最近在思考怎么实现动态的设置图片的主题色。不是那种渲染透明iocn。而是把图片的明暗关系保留。而改变其中的主题色。终于花了半天的时间研究出来了。和大家共享。

实现

思路很简单

  1. 将图片从RGB色彩空间转化为YUV色彩空间
  2. 使用ColorMatirx的setRotate(0, hue0);方法。将图片沿着Y轴旋转hue0的角度(角度从0到360度)
  3. 在家图片从YUV色彩空间转化RGB色彩空间

原理

YUV 空间

通俗的讲。YUV只是颜色的一种表达形式。Y中保存了图片的明暗度。UV保存了图片的色度信息。
下图所示,第一张是原图,依次是YUV分量。

image.png

setRotate方法

ColorMatirx的setRotate方法可以将颜色沿着一个轴旋转,沿着的这个轴的信息就不会变化。

/**

  • 用于色调的旋转运算

  • axis=0 表示色调围绕红色进行旋转

  • axis=1 表示色调围绕绿色进行旋转

  • axis=2 表示色调围绕蓝色进行旋转

*/

public void setRotate(int axis, float degrees)

image.png

1)围绕红色轴旋转

我们可以根据三原色来建立一个三维向量坐标系,当围绕红色旋转时,我们将红色虚化为一个点,绿色为横坐标,蓝色为纵坐标,旋转θ°。

image.png

偷梁换柱

如果我们将颜色从RGB转换为YUV 那么这个时候调用setRotate(0,degrees)那么颜色就会以Y信息为轴,进行旋转degrees的角度。
由于没有改变Y信息,所以图片的明暗度不会发生变化。
代码如下

  ColorMatrix cm = new ColorMatrix();ColorMatrix tmp = new ColorMatrix();cm.setRGB2YUV();tmp.setRotate(0, hue0);cm.postConcat(tmp);tmp.setYUV2RGB();cm.postConcat(tmp);paint.setColorFilter(new ColorMatrixColorFilter(cm));canvas.drawBitmap(bitmap,0,0,paint);

难点计算这个转动角度

其实也很简单。我们只需获取原来图片中的主题色

image.png

使用拾色器就可以搞定

然后根据目标色计算角度。

因为只转动UV信息

所以将原图中的UV信息组成一个二维向量,目标色的UV信息组成一个二维向量。

计算公式如下。

image.png

还需要注意一点
就是上面计算出来的角度是最小角度。
还要根据两个向量之间的叉积,来判断向量之间的位置关系。

叉乘公式

两个向量的叉乘,又叫向量积、外积、叉积,叉乘的运算结果是一个向量而不是一个标量。并且两个向量的叉积与这两个向量组成的坐标平面垂直。

一、二维向量叉乘公式:a(x1,y1),b(x2,y2),则a×b=(x1y2-x2y1)

根据叉乘结果的正负,可以判断两个向量的位置关系

判断点P在向量AB的左侧还是右侧,则可根据向量ABxAP 的叉乘结果r 来判断,根据右手定则:

  1. 若r > 0,则点P在向量AB的左侧;
  2. 若r = 0,则点P在向量AB上;
  3. 若r < 0,则点P在向量AB的右侧。

代码实现

注意,主题色写死在代码里面。要扩展需要自行改动。

最后的代码如下:

package com.example.orderlayoutdemo;import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.Paint;
import android.util.Log;/*** <pre>* Created by zhuguohui* Date: 2023/4/21* Time: 17:24* Desc:* </pre>*/
public class ImageUtils {public static Bitmap handleImageEffect(Bitmap bitmap,int targetColor){//由于不能直接在原图上修改,所以创建一个图片,设定宽度高度与原图相同。为32位ARGB图片Bitmap currentBitmap = Bitmap.createBitmap(bitmap.getWidth(),bitmap.getHeight(), Bitmap.Config.ARGB_8888);//创建一个和原图相同大小的画布Canvas canvas = new Canvas(currentBitmap);//创建笔刷并设置抗锯齿Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);float hue0=getHub(Color.parseColor("#61BCF8"),targetColor);ColorMatrix cm = new ColorMatrix();ColorMatrix tmp = new ColorMatrix();cm.setRGB2YUV();tmp.setRotate(0, hue0);cm.postConcat(tmp);tmp.setYUV2RGB();cm.postConcat(tmp);paint.setColorFilter(new ColorMatrixColorFilter(cm));canvas.drawBitmap(bitmap,0,0,paint);return currentBitmap;}public static float getHub(int fromColor,int targetColor){int[] yuv1 = convertRGB2YUV(fromColor);int[] yuv2 = convertRGB2YUV(targetColor);//计算两个颜色的uv分量组成的向量之间的夹角return getDegreeBetweenVectors(new int[]{yuv1[1], yuv1[2]}, new int[]{yuv2[1], yuv2[2]});}/*** 计算向量1,顺时针旋转多少度可以得到向量2* 返回的度数为0到360度* @param vs1* @param vs2* @return*/private static float getDegreeBetweenVectors(int[] vs1,int[] vs2 ){double cosDegree=0;//向量的内积int nj = vs1[0] * vs2[0] + vs1[1] * vs2[1];//叉积int cj=vs1[0]*vs2[1]-vs1[1]*vs2[0];double bl = Math.sqrt(vs1[0] * vs1[0] + vs1[1] * vs1[1]) *Math.sqrt(vs2[0] * vs2[0] + vs2[1] * vs2[1]);cosDegree= (nj/bl);double degree = Math.acos(cosDegree) / Math.PI * 180;//叉积大于0,表示向量2 在向量1的左边degree = (float) (cj > 0 ? 360- degree : degree);return (float) degree;}private static int[] convertRGB2YUV(int color) {ColorMatrix cm = new ColorMatrix();cm.setRGB2YUV();final float[] yuvArray = cm.getArray();int r = Color.red(color);int g = Color.green(color);int b = Color.blue(color);int[] result = new int[3];result[0] = floatToByte(yuvArray[0] * r + yuvArray[1] * g + yuvArray[2] * b);result[1] = floatToByte(yuvArray[5] * r + yuvArray[6] * g + yuvArray[7] * b) ;result[2] = floatToByte(yuvArray[10] * r + yuvArray[11] * g + yuvArray[12] * b) ;return result;}private static int floatToByte(float x) {int n = java.lang.Math.round(x);return n;}}

相关文章:

动态设置图片的主题色(保留明暗关系)

github地址 PrimaryColorDemo 效果 原始图片 就是一张普通的png图片 根据选择的主题色动态渲染。 思考 最近在思考怎么实现动态的设置图片的主题色。不是那种渲染透明iocn。而是把图片的明暗关系保留。而改变其中的主题色。终于花了半天的时间研究出来了。和大家共享。 …...

mybatis中#与$的区别

文章目录 区别详细讲解${}sql注入案例 区别 #会进行预编译&#xff0c;安全&#xff0c;通过#{}传入的参数 mybatis会认为是一个字符串&#xff0c;自动加上引号“” $ 不会进行预编译&#xff0c;通过$ 传入的参数会直接取出来使用&#xff0c;可能会产生sql注入风险&#xff…...

CVPR2023论文整理

文章目录 CVPR2023一. Vision and Language / Multimodal CVPR2023 根据官方信息统计&#xff0c;今年共收到 9155 份提交&#xff0c;比去年增加了 12%&#xff0c;创下新纪录&#xff0c;今年接收了 2360 篇论文&#xff0c;接收率为 25.78%。作为对比&#xff0c;去年有 81…...

RK3399平台开发系列讲解(中断篇)掌握信号处理

🚀返回专栏总目录 文章目录 一、信号的基本概念二、信号处理流程三、如何通过 API 注册一个信号处理函数四、可重入与异步信号安全3.1、可重入函数3.2、异步信号安全沉淀、分享、成长,让自己和他人都能有所收获!😄 📢信号在操作系统中有悠久的历史,信号的概念和使用方…...

业余爱好者想入门编程,一定远离那些只会说No的家伙,尤其程序员

视频&#xff1a;https://haokan.baidu.com/v?pdwisenatural&vid3050207991292418741 自媒体上的程序员群体有一个非常有意思的特点&#xff0c;就是特别愿意否定别人&#xff0c;特别喜欢说no&#xff0c;还有一个特点&#xff0c;特别不爱分享一些有用的技术和知识&…...

DHCP及中继(UOS)

DHCP服务器 中继器 客户端 服务器 安装DHCP apt install isc-dhcp-server -y 编辑配置文件 vim /etc/dhcp/dhcpd.conf 重启服务 systemctl restart isc-dhcp-server 配置监听网卡 vim /etc/default/isc-dhcp-server 中继器 安装dhcp yum install dhcp -y nmtui 修改…...

【Linux】进程的概念

文章目录 &#x1f4d6; 前言1. 冯诺依曼体系结构1.1 内存存在的意义&#xff1a;1.2 程序加载到内存的意义&#xff1a;1.3 程序的预加载&#xff1a; 2. 认识进程2.1 如何理解管理&#xff1a;2.2 什么叫是进程&#xff1a;&#xff08;初步理解&#xff09; 3. 简单认识操作…...

奇舞周刊第490期:WebAssembly 多语言/宿主环境中的使用

记得点击文章末尾的“ 阅读原文 ”查看哟~ 下面先一起看下本期周刊 摘要 吧~ 奇舞精选 ■ ■ ■ WebAssembly 多语言/宿主环境中的使用 WebAssembly (WASM) 的一个优势就是能够支持将不同语言编译成 WASM 代码&#xff0c;然后在不同的宿主环境中运行。这样就可以在不同的宿主环…...

【css】使用css实现提示框各种弹出效果。

简言 最近工作编写页面时&#xff0c;需要有一个提示框从下到上弹出的效果。 冥想了一下&#xff0c;实现了出来。 记录下实现思路。 实现思路 实现步骤如下&#xff1a; 编写样式。 首页要有承载内容的容器&#xff08;box)。外层在套一个包装盒子&#xff08;用来进行定位…...

1685_Excel的几种脚本处理方式

全部学习汇总&#xff1a; GreyZhang/python_basic: My learning notes about python. (github.com) 做个小结&#xff0c;实际上是写的我自己学习的过程。 关于Excel的处理方式很多&#xff0c;我也不会那么多&#xff0c;在这里我只想写一下我自己接触过的。大致是三种方式&a…...

Unity中使用struct和class来存储数据的注意事项

在 Unity 中&#xff0c;struct 和 class 都是用来定义自定义类型的关键字。它们的主要区别在于如何存储和传递它们的实例。 特点structclass存储方式值类型引用类型默认构造函数自动有性能快慢可空性不可空可空继承单继承单继承或多重继承 一、相似之处 1、都是用来定义自定…...

共阳(共阴)LED数码管编码交互演示

LED数码管原理 LED数码管有两大类&#xff0c;一类是共阴极接法&#xff0c;另一类是共阳极接法&#xff0c;共阴极就是各段的显示字码共用一个电源的负极&#xff0c;是高电平点亮&#xff0c;共阳极就是各段的显示字码共用一个电源的正极&#xff0c;是低电平点亮。只要控制…...

如何在 TensorFlow 中使用 GPU 加速深度学习计算?

一、前言 TensorFlow 是由 Google 开源的深度学习框架,它具有易用、高效、灵活等特点,被广泛应用于学术界和工业界中。而 GPU 是一种高性能的计算设备,可以加速深度学习的计算过程。本文将介绍如何在 TensorFlow 中使用 GPU 加速深度学习计算。 二、安装 TensorFlow 安装…...

RK3568平台开发系列讲解(Linux系统篇)线程 pthread 详解

🚀返回专栏总目录 文章目录 一、POSIX 线程模型二、pthread_create()创建线程三、线程属性3.1、初始化线程对象属性3.2、销毁一个线程属性对象3.3、线程的分离状态3.4、线程的调度策略3.5、线程的优先级3.6、线程栈四、线程退出五、回收已终止线程的资源沉淀、分享、成长,让…...

hspJAVA

循序渐进学Java 零基础 -韩顺平 第 1 章 内容介绍 1 1.1 本套 JAVA 课程内容 1 1.1.1 课程的三个阶段 1 1.1.2 关于课程的说明 1 1.1.3 课程特色 2 1.2 JAVA 就业方向 2 1.3 JAVA 开发场景举例 1-SSM 3 1.4 JAVA 开发场景举例 2&#xff1a;ANDROID 核心代码 3 1.5 JAVA 开发场…...

OpenAI-ChatGPT最新官方接口《嵌入向量式文本转换》全网最详细中英文实用指南和教程,助你零基础快速轻松掌握全新技术(五)(附源码)

Embeddings 嵌入向量式文本转换 前言Overview 概述What are embeddings? 什么是嵌入&#xff1f;How to get embeddings 如何获取嵌入python代码示例cURL代码示例 Embedding models 嵌入模型Second-generation models 第二代模型First-generation models (not recommended) 第…...

1042. 不邻接植花

有 n 个花园&#xff0c;按从 1 到 n 标记。另有数组 paths &#xff0c;其中 paths[i] [xi, yi] 描述了花园 xi 到花园 yi 的双向路径。在每个花园中&#xff0c;你打算种下四种花之一。 另外&#xff0c;所有花园 最多 有 3 条路径可以进入或离开. 你需要为每个花园选择一…...

Linux FTP服务

FTP服务 作用 传输文件 端口 FTP服务器默认使用TCP协议的20、21端口与客户端进行通信 20端口用于建立数据连接&#xff0c;并传输文件数据 21端口用于建立控制连接&#xff0c;并传输FTP控制命令 模式 FTP数据连接分为主动模式和被动模式 主动模式&#xff1a;客户端告诉服务端…...

JavaScript基础入门全解析(下)

数据类型&#xff08;重点&#xff09; ●是指我们存储在内存中的数据的分类&#xff0c;为了方便数据的管理&#xff0c;将数据分成了不同的类型 ●我们通常分为两大类 基本数据类型 和 复杂数据类型&#xff08;引用数据类型&#xff09; 基本数据类型 ●在js中基本数据类…...

【C++初阶】(入门)输入输出

#include< iostream> std是C标准库的命名空间名&#xff0c;C将标准库的定义实现都放到这个命名空间中 文章目录 ✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨&#x1f47b;一、iostream库介绍&#x1f47b;二、使用总结 ✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨ &#x1f4…...

初识Linux+Linux基本指令(一)

目录 一.&#x1f606;计算机与操作系统&#x1f606; 计算机与操作系统发展史简介: 计算机与操作系统的关系: 二.&#x1f604;Linux操作系统&#x1f604; 开源软件的代名词:Linux 非图形化界面的Liunx 三.&#x1f606;Linux基本指令之文件管理篇&#x1f606; 1.操…...

部署架构 因为单体架构痛点 升级到微服务架构

如图为单体部署 痛点 多人协作可能产生很多的回归测试 代码管理复杂度提升 软件包升级会导致增加测试次数 举例 单体电商 1增加功能(增加小程序平台) 2 并发增加 出现 1 代码复用 2 系统间相互调用 3 接口不仅要对外服务&#xff0c;也得对内提供接口 4 数据分析功…...

mapreduce打包提交执行wordcount案例

文章目录 一、源代码1. WordCountMapper类2. WordCountReducer类3. WordCountDriver类4. pom.xml 二、相关操作和配置1. 项目打包2. 带参测试3. 上传打包后的jar包和测试文档4. 增大虚拟内存5.启动集群6.在hdfs上创建输入文件夹和上传测试文档Hello.txt7. 利用jar包在hdfs实现文…...

MyBatis(十六)MyBatis使用PageHelper

一、limit分页 mysql的limit后面两个数字&#xff1a; 第一个数字&#xff1a;startIndex&#xff08;起始下标。下标从0开始。&#xff09; 第二个数字&#xff1a;pageSize&#xff08;每页显示的记录条数&#xff09; 假设已知页码pageNum&#xff0c;还有每页显示的记录…...

铁路轨道不平顺数据分析与预测

铁路轨道不平顺数据分析与预测 1.引言 铁路轨道作为铁行车的基础设施&#xff0c;是铁路线路的重要组成部分。随着经济和交通运输业的发展&#xff0c;我国的铁路运输正朝着高速和重载方向迅速发展&#xff0c;与此同时&#xff0c;轨道结构承受来自列车荷载、运行速度的冲击…...

好家伙,9:00面试,9:06就出来了,问的实在是太...

从外包出来&#xff0c;没想到死在另一家厂子 自从加入这家公司&#xff0c;每天都在加班&#xff0c;钱倒是给的不少&#xff0c;所以也就忍了。没想到2月一纸通知&#xff0c;所有人不许加班&#xff0c;薪资直降30%&#xff0c;顿时有吃不起饭的赶脚。 好在有个兄弟内推我去…...

【MySQL】数据库约束和聚合函数的使用

目录 上篇在这里喔~ 1.数据库约束 1.NULL约束 2.UNIQUE唯一约束 3.DEFAULT默认值约束 4.PRIMARY KEY主键约束 5.FOREIGN KEY外键约束 2.表的设计 1.设计思路​编辑 2.固定套路​编辑 2.1一对一关系 2.2一对多关系 ​编辑 2.3多对多关系 ​编辑​编辑​编辑 3.插入…...

SpringMvcFoundation

SpringMvcFoundation 一. SpringMVC简介1.1 优点二.Spring入门案例2.1 导入坐标2.2 编写SpringBoot启动类2.3 编写controller2.4 入门案例工作流程分析2.4.1 启动服务器初始化过程2.4.2 单次请求过程2.5 PostMan简介2.5.1 PostMan基本使用2.6 请求与相应2.6.1 请求映射路径2.6.…...

从零学习SDK(7)如何打包SDK

打包SDK的目的是为了方便将SDK提供给其他开发者或用户使用&#xff0c;以及保证SDK的兼容性和安全性。打包SDK可以有以下几个好处&#xff1a; 减少依赖&#xff1a;打包SDK可以将SDK所需的库、资源、文档等打包成一个文件或者一个目录&#xff0c;这样就不需要用户再去安装或…...

Python OpenCV 3.x 示例:1~5

原文&#xff1a;OpenCV 3.x with Python By Example 协议&#xff1a;CC BY-NC-SA 4.0 译者&#xff1a;飞龙 本文来自【ApacheCN 计算机视觉 译文集】&#xff0c;采用译后编辑&#xff08;MTPE&#xff09;流程来尽可能提升效率。 当别人说你没有底线的时候&#xff0c;你最…...