python对图片的颜色操作相关
1.更换图片的颜色,包括 jpg png gif svg
#--------------jpg,png替换-------------- from PIL import Image , ImageSequence import numpy as np from scipy.ndimage import binary_erosion, binary_dilation #--------------svg替换-------------- import re from xml.dom import minidom import cssutils #---------------------------------------------jpg,png替换--------------------------------------------- def change_color_jpg_png(image_path, output_path,target_color, new_color): """ 高精度颜色替换,保持边缘清晰 参数: image_path: 输入图片路径 target_color: 要替换的目标颜色 (R,G,B) new_color: 新的颜色 (R,G,B) tolerance: 颜色匹配容差 (0-100) output_path: 输出图片路径 """ # 打开图片并确保是RGBA模式 img = Image.open(image_path) if img.mode != 'RGBA': img = img.convert('RGBA') img_array = np.array(img) target = np.array(target_color) newc = np.array(new_color) for element in img_array: for colorItem in element: if(((255 - colorItem[0]) < 3) and colorItem[1] == target[1] and colorItem[2] == target[2]): colorItem[0] = newc[0] colorItem[1] = newc[1] colorItem[2] = newc[2] else: a = abs(255 - colorItem[0]) b = abs(255 - colorItem[1]) c = abs(255 - colorItem[2]) if((a < 5) and (b > 50) and (c > 50)): colorItem[0] = newc[0] colorItem[1] = newc[1] colorItem[2] = newc[2] # 保存结果 result_img = Image.fromarray(img_array) result_img.save(output_path, quality=100) print(f"处理完成,结果保存到: {output_path}") #---------------------------------------------svg替换--------------------------------------------- def replace_in_svg(image_path, output_path,o_color,n_color): """ 替换 SVG 文件中的内容 参数: image_path: 输入的 SVG 文件路径 output_file: 输出的 SVG 文件路径 """ replacements = { 'colors': { f'{o_color}': f'{n_color}', # 红色替换为绿色 # 'rgb(254,36,67)': 'rgb(119,230,28)', }, } # 读取 SVG 文件 with open(image_path, 'r', encoding='utf-8') as f: svg_content = f.read() # 解析 XML doc = minidom.parseString(svg_content) # 颜色替换 if 'colors' in replacements: for old_color, new_color in replacements['colors'].items(): svg_content = replace_colors(svg_content, old_color, new_color) # 保存修改后的 SVG with open(output_path, 'w', encoding='utf-8') as f: f.write(svg_content) print(f"SVG 内容已替换并保存到 {output_path}") def replace_colors(svg_content, old_color, new_color): """替换 SVG 中的颜色值""" # 支持 hex, rgb(), rgba(), 颜色名称等多种格式 color_patterns = [ (re.compile(f'fill="{old_color}"'), f'fill="{new_color}"'), (re.compile(f'stroke="{old_color}"'), f'stroke="{new_color}"'), (re.compile(f'fill:{old_color}(;|!important)'), f'fill:{new_color}\\1'), (re.compile(f'stroke:{old_color}(;|!important)'), f'stroke:{new_color}\\1'), (re.compile(f'stop-color="{old_color}"'), f'stop-color="{new_color}"'), (re.compile(f'flood-color="{old_color}"'), f'flood-color="{new_color}"'), ] for pattern, replacement in color_patterns: svg_content = pattern.sub(replacement, svg_content) return svg_content #---------------------------------------------gif替换--------------------------------------------- def replace_gif_color(image_path, output_path, target_color, new_color): """ 替换 GIF 文件中的颜色 参数: image_path: 输入 GIF 文件路径 output_path: 输出 GIF 文件路径 color_mapping: 颜色映射字典 {旧颜色: 新颜色},颜色格式为 (R,G,B) 或 (R,G,B,A) """ # 打开 GIF 文件 gif = Image.open(image_path) # 获取 GIF 的调色板模式信息 palette = gif.getpalette() # 处理每一帧 frames = [] durations = [] for frame in ImageSequence.Iterator(gif): # 转换为 RGBA 以处理透明度 frame_rgba = frame.convert('RGBA') frame_array = np.array(frame_rgba) target = np.array(target_color) newc = np.array(new_color) for element in frame_array: for colorItem in element: if(((255 - colorItem[0]) < 3) and colorItem[1] == target[1] and colorItem[2] == target[2]): colorItem[0] = newc[0] colorItem[1] = newc[1] colorItem[2] = newc[2] else: a = abs(255 - colorItem[0]) b = abs(255 - colorItem[1]) c = abs(255 - colorItem[2]) if((a < 5) and (b > 50) and (c > 50)): colorItem[0] = newc[0] colorItem[1] = newc[1] colorItem[2] = newc[2] # 转换回 PIL 图像 new_frame = Image.fromarray(frame_array) frames.append(new_frame) durations.append(frame.info.get('duration', 100)) # 默认 100ms # 保存 GIF frames[0].save( output_path, save_all=True, append_images=frames[1:], duration=durations, loop=0, # 无限循环 disposal=2, # 恢复背景 optimize=True ) print(f"GIF 颜色已替换并保存到 {output_path}") #---------------------------------------------jpg,png替换 ,渐变--------------------------------------------- def change_color_jpg_png_slowly(image_path, output_path,target_color, new_color): """ 高精度颜色替换,保持边缘清晰 参数: image_path: 输入图片路径 target_color: 要替换的目标颜色 (R,G,B) new_color: 新的颜色 (R,G,B) tolerance: 颜色匹配容差 (0-100) output_path: 输出图片路径 """ # 打开图片并确保是RGBA模式 img = Image.open(image_path) if img.mode != 'RGBA': img = img.convert('RGBA') img_array = np.array(img) target = np.array(target_color) newc = np.array(new_color) for element in img_array: for colorItem in element: if(colorItem[0] > 250 and colorItem[1] > 250 and colorItem[2] > 250): continue if(colorItem[0] < target[0]): colorItem[0] = max(min(int(newc[0] + (colorItem[0] - target[0])),255),0) else: colorItem[0] = max(min(int(newc[0] + (colorItem[0] - target[0])),255),0) if(colorItem[1] < target[1]): colorItem[1] = max(min(int(newc[1] + (colorItem[1] - target[1])),255),0) else: colorItem[1] = max(min(int(newc[1] + (colorItem[1] - target[1])),255),0) # 保存结果 result_img = Image.fromarray(img_array) result_img.save(output_path, quality=100) print(f"处理完成,结果保存到: {output_path}")
2.获取图片颜色
from PIL import Image import numpy as np from collections import Counter def get_all_argb_values(image_path, output_mode='unique', top_colors=10): """ 获取图片中所有像素的ARGB值 参数: image_path: 图片路径 output_mode: 输出模式 ('all'所有像素/'unique'唯一值/'top'最常见颜色) top_colors: 当output_mode='top'时,指定显示的最常见颜色数量 返回: 根据output_mode返回不同的ARGB值集合 """ # 打开图片并转换为RGBA模式 try: img = Image.open(image_path).convert('RGBA') except Exception as e: print(f"无法打开图片: {e}") return None # 将图像数据转换为numpy数组 img_array = np.array(img) # 获取所有像素的ARGB值 (形状: [height, width, 4]) argb_values = img_array.reshape(-1, 4) # 展平为二维数组 [pixel_count, 4] # 根据输出模式返回不同结果 if output_mode == 'all': return argb_values.tolist() # 返回所有像素的ARGB值 elif output_mode == 'unique': # 返回唯一的ARGB值 unique_colors = np.unique(argb_values, axis=0) return unique_colors.tolist() elif output_mode == 'top': # 返回最常见的top_colors种颜色及其出现次数 # 将ARGB元组作为字典键 color_counts = Counter(tuple(color) for color in argb_values) return color_counts.most_common(top_colors) else: raise ValueError("output_mode参数必须是'all'、'unique'或'top'") def save_argb_values_to_file(argb_data, output_file): """将ARGB数据保存到文本文件""" with open(output_file, 'w') as f: if isinstance(argb_data[0], tuple): # top模式数据 for color, count in argb_data: f.write(f"ARGB{color}: {count}次\n") else: # all或unique模式数据 for color in argb_data: f.write(f"ARGB{tuple(color)}\n") print(f"ARGB值已保存到 {output_file}") def display_color_palette(argb_data, palette_size=400): """显示颜色调色板""" from PIL import ImageDraw if isinstance(argb_data[0], tuple): # top模式数据 colors = [color for color, _ in argb_data] else: # all或unique模式数据 colors = [tuple(color) for color in argb_data] # 创建调色板图像 cols = 10 rows = (len(colors) // cols) + 1 swatch_size = palette_size // cols palette = Image.new('RGBA', (cols*swatch_size, rows*swatch_size)) draw = ImageDraw.Draw(palette) for i, color in enumerate(colors): x = (i % cols) * swatch_size y = (i // cols) * swatch_size draw.rectangle([x, y, x+swatch_size, y+swatch_size], fill=color) palette.show() return palette # 使用示例 if __name__ == "__main__": # 配置参数 image_path = '/Users/veepai005/Documents/personal_bg_light.png' # 替换为你的图片路径 output_mode = 'top' # 'all'、'unique'或'top' top_colors = 20 # 当output_mode='top'时有效 output_file = '/Users/veepai005/Documents/buy_flow.txt' # 获取ARGB值 argb_data = get_all_argb_values(image_path, output_mode, top_colors) if argb_data: # 打印部分结果 print(f"找到 {len(argb_data)} 个ARGB值(模式: {output_mode})") if output_mode == 'top': for i, (color, count) in enumerate(argb_data[:10], 1): print(f"{i}. ARGB{color}: {count}次") else: print("前5个ARGB值:", argb_data[:10]) # 保存到文件 save_argb_values_to_file(argb_data, output_file) # 显示颜色调色板(仅当颜色数量<=100时) if len(argb_data) <= 100: display_color_palette(argb_data) else: print("颜色过多,不显示调色板")

浙公网安备 33010602011771号