无缝合并两张图片(封面右上角添加logo)-- opencv : 进行添加logo(水印)由于使用了cv2.seamlessClone
,cv2.seamlessClone
使用了泊松克隆(Poisson Cloning),会根据周围的颜色信息进行颜色调整,使得融合后的区域更加自然,但这也可能导致颜色发生变化。
logo 都花了,颜色也不对了。
为了保留原来的颜色
,可以使用简单的覆盖方法
而不是cv2.seamlessClone
。
import os
import cv2
import sys
import traceback
import numpy as np
import requests
import logging
def get_logoUrl(logoUrl, uid):
"""
Download logo image from URL and save it locally.
Args:
- logoUrl (str): URL of the logo image.
- uid (str): Unique identifier for the image.
Returns:
- str: File path where the logo image is saved.
"""
end = logoUrl.split('.')[-1]
content = requests.get(logoUrl).content
#logger.info(os.getcwd())
try:
logo_name = f'logo_images/{uid}.{end}'
#logger.info(logo_name)
print(logo_name)
#print(os.getcwd())
with open(logo_name,'wb') as f:
f.write(content)
return logo_name
except:
#logger.info(traceback.format_exc())
print(traceback.format_exc())
# return dict(code=10099, data='系统未能获得有效结果,请稍后重试')
def merge_logo2First_page(uid, logoUrl):
"""
Merge a logo onto the first page image, preserving transparency if present.
Args:
- uid (str): Unique identifier for the image.
- logoUrl (str): URL of the logo image.
Returns:
- str: File path where the merged image is saved.
"""
folder = 'imgs/'
# 获取 logo 图片
logo_name = get_logoUrl(logoUrl, uid)
obj = cv2.imread(logo_name, cv2.IMREAD_UNCHANGED)
if obj is None:
raise ValueError(f"Image at path {logo_name} could not be read.")
(h, w, z) = obj.shape
# 固定 logo 图片的大小
obj_fixed_size = cv2.resize(obj, (round(200 * (w / h)), 200))
(h, w, z) = obj_fixed_size.shape
# 检查是否存在 Alpha 通道,如果没有则创建一个全白的 Alpha 通道
if obj_fixed_size.shape[2] == 4:
alpha_channel = obj_fixed_size[:, :, 3] / 255.0
obj_rgb = obj_fixed_size[:, :, :3]
else:
alpha_channel = np.ones((obj_fixed_size.shape[0], obj_fixed_size.shape[1]), dtype=np.float32)
obj_rgb = obj_fixed_size
# 读取主图片
im = cv2.imread(folder + "auto_first_page.jpg")
(height, width, channels) = im.shape
# 计算 logo 的放置位置(右上角)
top_left_h = 100 # 距离顶部的距离
top_left_w = width - w - 222 # 距离右侧的距离
# 边界检查,确保放置位置在主图片内
if top_left_h < 0:
top_left_h = 0
if top_left_w < 0:
top_left_w = 0
if top_left_h + h > height:
top_left_h = height - h
if top_left_w + w > width:
top_left_w = width - w
# 处理透明度,将有颜色的部分覆盖到主图片上
# for c in range(0, 3):
# im[top_left_h:top_left_h + h, top_left_w:top_left_w + w, c] = (
# alpha_channel * obj_rgb[:, :, c] +
# (1 - alpha_channel) * im[top_left_h:top_left_h + h, top_left_w:top_left_w + w, c]
# )
# 矩阵计算替代显式循环:使用 NumPy 的广播功能,将显式循环转换为矩阵计算,从而提高效率。
im[top_left_h:top_left_h + h, top_left_w:top_left_w + w, :3] = (
(alpha_channel[..., np.newaxis] * obj_rgb) +
((1 - alpha_channel[..., np.newaxis]) * im[top_left_h:top_left_h + h, top_left_w:top_left_w + w, :3])
)
# 保存处理后的图片
save_path = 'first_page_merged_logo/'
if not os.path.exists(save_path):
os.makedirs(save_path)
output_path = os.path.join(save_path, f"merged_{uid}.jpg")
cv2.imwrite(output_path, im)
return output_path, logo_name