使用Python转换图片中的颜色

news2024/12/23 23:10:21

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


盛开的桃花,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程序对图片中的颜色进行转换

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Javascript 插值搜索-迭代与递归(Interpolation Search)

给定一个由 n 个均匀分布值 arr[] 组成的排序数组&#xff0c;编写一个函数来搜索数组中的特定元素 x。 线性搜索需要 O(n) 时间找到元素&#xff0c;跳转搜索需要 O(? n) 时间&#xff0c;二分搜索需要 O(log n) 时间。 插值搜索是对实例二分搜索的改进&#xff0c;…

AI绘画:使用ComfyUI结合LCM进行实时绘图:开启AI艺术创作新篇章

在数字艺术的世界里&#xff0c;ComfyUI和LCM&#xff08;Latent Contextual Modulation&#xff09;的结合为艺术家和设计师们提供了一个强大的实时绘图工具。LCM是一种先进的技术&#xff0c;它能够实时地将用户的输入和反馈融入到图像生成过程中&#xff0c;从而创造出动态变…

Web3 革命:揭示区块链技术的全新应用

随着数字化时代的不断发展&#xff0c;区块链技术作为一项颠覆性的创新正在改变着我们的世界。而在这一技术的进步中&#xff0c;Web3正逐渐崭露头角&#xff0c;为区块链技术的应用带来了全新的可能性。本文将探讨Web3革命所揭示的区块链技术全新应用&#xff0c;并展望其未来…

第1讲——预备知识

一、视觉SLAM十四讲在讲些啥 SLAM&#xff1a;Simultaneous Localization and Mapping 翻译&#xff1a;同时定位与地图构建 搭载特定传感器的主体&#xff0c;在没有环境先验信息的情况下&#xff0c;于运动过程中建立环境的模型&#xff0c;同时估计自己的运动。 当特定传感…

构建开源可观测平台

企业始终面临着确保 IT 基础设施和应用程序全年可用的压力。现代架构&#xff08;容器、混合云、SOA、微服务等&#xff09;的复杂性不断增长&#xff0c;产生大量难以管理的日志。我们需要智能应用程序性能管理 (APM) 和可观察性工具来实现卓越生产并满足可用性和正常运行时间…

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

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

揭秘SCQL:隐私计算的未来之路

1.SCQL使用/集成最佳实践 隐语隐私计算中SCQL&#xff08;Secure Collaborative Query Language&#xff09;的设计旨在提供一种便捷且安全的方式来处理多方参与下的隐私敏感数据查询与分析&#xff0c;而无需暴露原始数据给任何一方。以下是基于以上所记录信息的SCQL使用和集…

Linux文件IO(3):使用文件IO进行文件的打开、关闭、读写、定位等相关操作

目录 1. 文件IO的概念 2. 文件描述符概念 3. 函数介绍 3.1 文件IO-open函数 3.2 文件IO-close函数 3.3 文件IO-read函数 3.4 文件IO-write函数 3.5 文件IO-lseek函数 4. 代码练习 4.1 要求 4.2 具体实现代码 4.3 测试结果 5. 总结 1. 文件IO的概念 posix(可移植操作系统接…

vulhub中Struts2-008 远程代码执行漏洞复现

影响版本: 2.1.0 - 2.3.1 原理 > S2-008 涉及多个漏洞&#xff0c;Cookie 拦截器错误配置可造成 OGNL 表达式执行&#xff0c;但是由于大多 Web 容器&#xff08;如 Tomcat&#xff09;对 Cookie 名称都有字符限制&#xff0c;一些关键字符无法使用使得这个点显得比较鸡肋…

深入了解 Python 中标准排序算法 Timsort

&#x1f349; CSDN 叶庭云&#xff1a;https://yetingyun.blog.csdn.net/ Timsort&#xff1a;一个非常快速的、时间复杂度为 O ( n l o g n ) O (n \ log\ n) O(n log n)、稳健&#xff08;即不改变等值元素间的相对顺序&#xff09;的排序算法&#xff0c;在处理真实世界数…

ModuleNotFoundError: No module named ‘einops‘解决办法

安装对应的库就好 pip install einops -i https://pypi.tuna.tsinghua.edu.cn/simple 拓展——在python中einops模块有什么作用 einops 是一个 Python 库&#xff0c;它提供了一种简洁、易读的方式来操作多维数组&#xff08;通常是 NumPy 数组或 PyTorch 张量&#xff09;。e…

移动端基础

移动端基础 一.了解二.视口1.视口形式2.视口标签3.viewport设置 三.二倍图1.像素比2.多倍图3.背景缩放及使用&#xff08;background-size&#xff09;4.多倍图切图 四.移动端开发选择1.单独制作2.响应式3.总结 五.移动端技术解决方案1.初始化2.盒子模型3.特殊样式 六.常见布局…

铸铁平台的平面度

铸铁平台的平面度是指平台的表面平整程度&#xff0c;即平台表面与其理论平面之间的最大偏差。平台的平面度通常使用国际标准符号GD&T中的平面度符号&#xff08;ⓨ&#xff09;表示&#xff0c;单位为毫米&#xff08;mm&#xff09;或微米&#xff08;μm&#xff09;。 …

【数据分析面试】10. 计算平均通勤时间(SQL:timestampdiff() 和datediff()区别)

题目 假设你在Uber工作。rides表包含了关于Uber用户在美国各地的行程信息。 编写一个查询&#xff0c;以获取纽约&#xff08;NY&#xff09;每位通勤者的平均通勤时间&#xff08;以分钟为单位&#xff09;&#xff0c;以及纽约所有通勤者的平均通勤时间&#xff08;以分钟为…

Codeforces Round 836 (Div. 2) D. Range = √Sum

题目 思路&#xff1a; #include <bits/stdc.h> using namespace std; #define int long long #define pb push_back #define fi first #define se second #define lson p << 1 #define rson p << 1 | 1 const int maxn 1e6 5, inf 1e18, maxm 4e4 5; c…

Phpstorm配置Xdebug

步骤 1、先去官网找到对应的php xdebug的版本 2、配置phpstorm断点调试 网址&#xff1a;https://xdebug.org/ 查看php对应的xdebug版本&#xff1a;Xdebug: Support — Tailored Installation Instructions 1.1查看对应php xdebug版本 全选&#xff0c;复制到目标网址 我…

数据恢复软件有哪些?适用于 Windows PC 的 10 款最佳免费数据恢复软件

数据已成为数字世界运作的主要来源。任何数据丢失都会对公司的日常活动产生巨大影响。它会影响过程的连续性。以下文章为您带来了各种简单且免费使用的数据恢复软件。 什么是数据恢复&#xff1f; 检索和恢复丢失、损坏、无法访问、损坏或意外删除的数据的过程称为数据恢复。这…

B3631 单向链表(结构体模拟链表)

输入格式 第一行一个整数 q表示操作次数。 接下来 q行&#xff0c;每行表示一次操作&#xff0c;操作具体间题目描述。 输出格式 对于每个操作 2&#xff0c;输出一个数字&#xff0c;用换行隔开。 #include<iostream> #include<map> #include<algorithm> …

【随笔】Git 高级篇 -- 整理提交记录(上)(十五)

&#x1f48c; 所属专栏&#xff1a;【Git】 &#x1f600; 作  者&#xff1a;我是夜阑的狗&#x1f436; &#x1f680; 个人简介&#xff1a;一个正在努力学技术的CV工程师&#xff0c;专注基础和实战分享 &#xff0c;欢迎咨询&#xff01; &#x1f496; 欢迎大…

设置Chrome打开链接在新标签页显示

Chrome版本 版本 123.0.6312.106&#xff08;正式版本&#xff09; &#xff08;64 位&#xff09; 下面这两个页面都有设置按钮&#xff1a; https://www.google.com/?pli1或者https://www.google.com/?hlzh-CN 要先退出账号&#xff0c;要不然看不到右下角的 “设置” 。…