使用Python转换图片中的颜色

说明:最近在看梵高的画册,我手上的这本画册(《文森特·梵高》杨建飞 主编)书中说,梵高用的颜料里有不耐久的合成颜料,原本的紫色褪成了我们现在所看到的灰蓝色。于是我想,能不能用程序将画中的颜色还原成原本的紫色。


盛开的桃花,1888年

盛开的桃花

生成图片

首先,写一段代码,用来读取图片,生成一个副本,代码如下:

from PIL import Image, ImageDraw
import numpy as np


# 生成转换后的画
def generate_img(in_path, out_path):
    # 打开图片
    im = Image.open(in_path)
    # 生成后的图片大小,使用im.size[0],im.size[1],即原图大小
    new_im_size = np.array([im.size[0], im.size[1]]).astype(int)
    # 生成图片的背景颜色
    bg_color = "black"
    # 生成图片
    im_out = Image.new("RGB", tuple(new_im_size), bg_color)
    # 获取图片的颜色
    im_color = np.array(im)
    # 生成图片
    draw = ImageDraw.Draw(im_out)
    # 用于统计进度
    count = 0
    total_pixels = im.size[0] * im.size[1]
    # 遍历图片的每个像素点,将颜色填充到新图片中
    for i in range(im.size[0]):
        for j in range(im.size[1]):
            color = tuple(im_color[j, i])
            draw.point((i, j), fill=color)
            count += 1
        print('生成进度:%d%%' % ((count / total_pixels) * 100))
    # 保存图片
    im_out.save(out_path)

if __name__ == "__main__":
    in_path = r'C:\Users\10765\Desktop\1.jpg'
    out_path = r'C:\Users\10765\Desktop\2.jpg'
    # 读取图片,并将图片中的颜色转换
    generate_img(in_path, out_path)

运行

在这里插入图片描述

可在桌面上生成一张几乎一模一样大小的图片;

在这里插入图片描述

颜色转换

接着,我们就是对颜色进行处理,也就是上面for循环里的这行代码;

            color = tuple(im_color[j, i])

我们要写一个方法,对这里面的色值进行转换,我的思路是这样的,首先找到紫色和灰蓝色的RGB色值范围,然后对图片中的色值进行判断,如果是在灰蓝色的色值范围内,则对该RGB色值进行映射,映射到紫色的RGB色值范围内。通过问GPT,可知两种颜色的色值范围如下:

  • 紫色:128-255,0-20,128-255;

  • 灰蓝色:100-180,120-200,150-230;

代码如下:

# 色值转换,灰蓝色 => 紫色
def convert_color(gray_blue_rgb):
    # 灰蓝色范围
    gray_blue_range = [(100, 180), (120, 200), (150, 230)]
    # 紫色范围
    violet_range = [(128, 255), (0, 20), (128, 255)]
    # 检查输入的 RGB 值是否在灰蓝色范围内
    for i in range(3):
        if not (gray_blue_range[i][0] <= gray_blue_rgb[i] <= gray_blue_range[i][1]):
            return tuple(gray_blue_rgb)

    # 根据灰蓝色范围的值转换到紫色范围
    violet_color = []
    for i in range(3):
        gray_blue_min, gray_blue_max = gray_blue_range[i]
        violet_min, violet_max = violet_range[i]
        # 灰蓝色范围内的值映射到紫色范围
        violet_val = int(
            (gray_blue_rgb[i] - gray_blue_min)
            / (gray_blue_max - gray_blue_min)
            * (violet_max - violet_min)
            + violet_min
        )
        violet_color.append(violet_val)
    return tuple(violet_color)

为了方便理解,举个例子。如果一个A色值区间是 [20,100],另一个B色值区间是[100,180],现在一个A色值是80,需要转为B色值,过程如下:

  • (80 - 20)/ (100 - 20) * (180 - 100) + 100 = 160

  • (当前色值 - A色值范围的最低值) / (A色值的区间长度,即 100 - 20) * (B色值的区间长度,即 180 - 100) + B色值范围的最低值

160,就是A色值在B色值中的值;

代码写好了,在将颜色填充到图片前做一层转换即可,如下:

    # 遍历图片的每个像素点,将颜色填充到新图片中
    for i in range(im.size[0]):
        for j in range(im.size[1]):
            # 将颜色转换,然后填充到新图片中
            color = tuple(convert_color(im_color[j, i]))
            draw.point((i, j), fill=color)
            count += 1
        print('生成进度:%d%%' % ((count / total_pixels) * 100))

启动,看下效果,有点妖娆,色值范围没控制好;

在这里插入图片描述

我之前选的色值如下:

  • 紫色:80-150,100-180,120-200;

  • 灰蓝色:150-220,0-80,150-220;

转换后的效果如下:

在这里插入图片描述

完整代码

from PIL import Image, ImageDraw
import numpy as np


# 生成转换后的画
def generate_img(in_path, out_path):
    # 打开图片
    im = Image.open(in_path)
    # 生成后的图片大小,使用im.size[0],im.size[1],即原图大小
    new_im_size = np.array([im.size[0], im.size[1]]).astype(int)
    # 生成图片的背景颜色
    bg_color = "black"
    # 生成图片
    im_out = Image.new("RGB", tuple(new_im_size), bg_color)
    # 获取图片的颜色
    im_color = np.array(im)
    # 生成图片
    draw = ImageDraw.Draw(im_out)
    # 用于统计进度
    count = 0
    total_pixels = im.size[0] * im.size[1]
    # 遍历图片的每个像素点,将颜色填充到新图片中
    for i in range(im.size[0]):
        for j in range(im.size[1]):
            # 将颜色转换,然后填充到新图片中
            color = tuple(convert_color(im_color[j, i]))
            draw.point((i, j), fill=color)
            count += 1
        print('生成进度:%d%%' % ((count / total_pixels) * 100))
    # 保存图片
    im_out.save(out_path)


# 色值转换,灰蓝色 => 紫色
def convert_color(gray_blue_rgb):
    # 灰蓝色范围
    gray_blue_range = [(100, 180), (120, 200), (150, 230)]
    # 紫色范围
    violet_range = [(128, 255), (0, 20), (128, 255)]
    # 检查输入的 RGB 值是否在灰蓝色范围内
    for i in range(3):
        if not (gray_blue_range[i][0] <= gray_blue_rgb[i] <= gray_blue_range[i][1]):
            return tuple(gray_blue_rgb)

    # 根据灰蓝色范围的值转换到紫色范围
    violet_color = []
    for i in range(3):
        gray_blue_min, gray_blue_max = gray_blue_range[i]
        violet_min, violet_max = violet_range[i]
        # 灰蓝色范围内的值映射到紫色范围
        violet_val = int(
            (gray_blue_rgb[i] - gray_blue_min)
            / (gray_blue_max - gray_blue_min)
            * (violet_max - violet_min)
            + violet_min
        )
        violet_color.append(violet_val)
    return tuple(violet_color)


if __name__ == "__main__":
    # 输入图片路径
    in_path = r'C:\Users\10765\Desktop\1.png'
    # 输出图片路径
    out_path = r'C:\Users\10765\Desktop\2.png'
    # 读取图片,并将图片中的颜色转换
    generate_img(in_path, out_path)

总结

本文介绍了如何使用Python程序对图片中的颜色进行转换

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/519145.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

备战蓝桥杯---贡献法刷题

话不多说&#xff0c;直接看题&#xff1a; 什么是贡献法&#xff1f;这是一种数学思想&#xff0c;就是看每一个元素对总和的贡献。 1. 我们可以先枚举区间再统计次数&#xff0c;但这显然TLE。我们可以发现&#xff0c;每一个孤独的区间对应一个孤独的牛&#xff0c;因此我…

计组第三版书例题

基础知识过一下 存储器与CPU的连接主要通过数据总线、地址总线和控制总线实现。CPU首先向存储器发送地址信号&#xff0c;然后发出读写控制信号&#xff0c;最后在数据总线上进行数据的读写操作 。这种连接方式确保了CPU能够正确地访问和控制存储器中的数据。 https://blog.cs…

2024免费Mac电脑用户的系统清理和优化软件CleanMyMac

作为产品营销专家&#xff0c;对于各类产品的特性与优势有着深入的了解。CleanMyMac是一款针对Mac电脑用户的系统清理和优化软件&#xff0c;旨在帮助用户轻松管理、优化和保护Mac电脑。以下是关于CleanMyMac的详细介绍&#xff1a; CleanMyMac X2024全新版下载如下: https://…

蓝桥-时间显示

目录 题目链接 代码 题目链接 1.时间显示 - 蓝桥云课 (lanqiao.cn) 代码 #include <bits/stdc.h> using namespace std;int main() {long long x;cin>>x;int h,m,s;x x / 1000 % (3600*24); // 毫秒化秒&#xff0c;并且保留最后一天的时间h x / 3600; //求得…

使用pip install替代conda install将packet下载到anaconda虚拟环境

问题描述 使用conda install 下载 stable_baseline3出现问题 一番搜索下是Anaconda.org缺少源 解决方法 首先使用管理员权限打开 anaconda prompt 然后激活目标环境&#xff1a;conda activate env_name 接着使用&#xff1a;conda env list查看目标env的位置 如D:\anacon…

C语言进阶课程学习记录-第23课 - #error 和 #line 使用分析

C语言进阶课程学习记录-第23课 - #error 和 #line 使用分析 实验-#errer的使用演示cmd窗口实验-缺少#error实验-#line 1的使用实验-#line 1用于标记代码小结 本文学习自狄泰软件学院 唐佐林老师的 C语言进阶课程&#xff0c;图片全部来源于课程PPT&#xff0c;仅用于个人学习记…

MySQL介绍和安装

MySQL介绍和安装 文章目录 MySQL介绍和安装1.MySQL介绍2.MySQL安装2.1 主机初始化2.1.1 设置网卡名和ip地址2.1.2 配置镜像源2.1.3 关闭防火墙2.1.4 禁用SELinux2.1.5 设置时区 2.2 包安装2.2.1 Rocky和CentOS 安装 MySQL2.2.2 Ubuntu 安装 MySQL 2.3 二进制安装安装MySQL2.3.1…

基于SpringBoot+微信小程序的防诈骗平台

一、项目背景介绍&#xff1a; 社会背景随着互联网的高速发展&#xff0c;网络和手机的普及率也大大提高&#xff0c;这也衍生出一系列问题&#xff1a;用户信息泄露、不法分子电话诈骗等…现越来越多的老年人甚至年轻人经历过电信诈骗并被骗了大量金额。该产品正是基于这样的社…

CMOS漏极开路门

线与 通常CMOS门电路都有反相器作为输出缓冲电路。在实际工程中&#xff0c;为了方便常将两个门的输入端直接并联来实现与逻辑功能&#xff08;称为线与&#xff09;。如下图所示&#xff1a; 线与的弊端&#xff1a;当与电源VDD直接相连的PMOS管导通时&#xff0c;由于MOS管导…

arm开发板移植工具mkfs.ext4

文章目录 一、前言二、手动安装e2fsprogs1、下载源码包2、解压源码3、配置4、编译5、安装 三、移植四、验证五、总结 一、前言 在buildroot菜单中&#xff0c;可以通过勾选e2fsprogs工具来安装mkfs.ext4工具&#xff1a; Target packages -> Filesystem and flash utilit…

发布自己的github项目

git下载 git关网&#xff1a;https://git-scm.com/ 下载后是exe文件 git安装 除了选安装地址&#xff0c;其他都是下一步下一步傻瓜式安装 安装好之后随便一个地方右键多了两个东西 git gui here 和git bash here git测试配置及创建github项目 右键git bash here 测试…

C语言操作SQL数据库

1.打开/创建数据库的C语言接口 int sqlite3_open(const char *filename, sqlite3 **ppDb) 该例程打开一个指向 SQLite 数据库文件的连接&#xff0c;返回一个用于其他 SQLite 程序的数据库连接对象。 int sqlite3_close(sqlite3*) 该例程关闭之前调用 sqlite3_open() 打开的数据…

java(7)之跳转语句

1、break跳转语句 说到break其实也不是跳转&#xff0c;它更像是一个终结语句&#xff0c;常用于在循环语句需要停止出现例如 while&#xff08;&#xff09;{ if&#xff08;&#xff09;{ break&#xff1b; }} 这样的形式或者 switch&#xff08;&#xff09;{ case…

水离子雾化壁炉如何实现火焰的虚实变化?

水离子雾化壁炉通过调节水雾的密度和电子控制器的设置来实现火焰的虚实变化。具体实现方法如下&#xff1a; 调节水雾密度&#xff1a; 超声波振动器可以调节水分子的雾化效果&#xff0c;从而控制水雾的密度。增加水雾的密度会使火焰看起来更实&#xff0c;而减少水雾的密度则…

Pytoch安装记录

使用pycharm 1、CUDA的安装 官网&#xff1a;CUDA Toolkit Archive | NVIDIA Developer 选择对应的版本 选择对应的版本进行下载&#xff1a; 有3个多G cuda的安装需要注意&#xff0c;如果没有安装vs&#xff0c;则需要选择自定义安装&#xff0c;在自定义的安装中取消 安…

HTML常用标签-最基础的标签

从本篇开始&#xff0c;我们围绕HTML原生标签开始&#xff0c;围绕整个前端三剑客进行&#xff0c;将进行一个大致的介绍和案例展示&#xff0c;没有啥技术含量&#xff0c;只是把学习前端的时候&#xff0c;案例全部展示出来&#xff0c;作为一个实时记录&#xff0c;或者说回…

《QT实用小工具·十三》FlatUI辅助类之各种炫酷的控件集合

1、概述 源码放在文章末尾 FlatUI辅助类之各种炫酷的控件集合 按钮样式设置。文本框样式设置。进度条样式。滑块条样式。单选框样式。滚动条样式。可自由设置对象的高度宽度大小等。自带默认参数值。 下面是demo演示&#xff1a; 项目部分代码如下所示&#xff1a; #ifnd…

c/c++ | socket tcp client server

突然想着&#xff0c;花一个socket tcp 客户-服务通信 这应该是很经典的流程了吧 感觉还是要训练这种随手画图的能力&#xff0c;毕竟文字的描述还是不及图片强烈 参考01

c# wpf style 简单试验

1.概要 wpf style 用来控制控件的样式 2.代码 <Window x:Class"WpfApp2.Window5"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x"http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d"http://schemas.…

CKA 基础操作教程(二)

Kubernetes Deployment 理论学习 Kubernetes Deployment &#xff08;部署&#xff09;是一种 Kubernetes 资源对象&#xff0c;用于定义和管理容器化应用程序的部署和更新。Deployment 提供了一种声明性的方式来定义应用程序的期望状态&#xff0c;并负责确保所需数量的 Pod…