diff --git a/pic_hide_barcode-new-hcl.py b/pic_hide_barcode-new-hcl.py new file mode 100644 index 0000000..cde17cb --- /dev/null +++ b/pic_hide_barcode-new-hcl.py @@ -0,0 +1,145 @@ +from PIL import Image # 若提示No module named 'PIL',则:pip install Pillow + +# 打开两张素材图片,其中二维码背景为白色。 +# 注意:为了代码简洁,这两张图的分辨率必需要是相同的。 +imgPutong = Image.open("C:/Users/huang'chen'lu/Desktop/pic_hide_barcode-main/普通图片.jpg") +imgBarcode = Image.open("C:/Users/huang'chen'lu/Desktop/pic_hide_barcode-main/二维码.jpg") + +# 创建新图片,使用RGBA模式,方便稍后保存为png。新图的分辨率和普通图相同。 +imgMix = Image.new("RGBA", (imgPutong.width, imgPutong.height) ) + +# 新添加:计算原图片亮度阈值,用于筛选较亮区域 +def calculate_brightness(r, g, b): + """新添加:计算RGB像素的亮度值""" + return int(0.299 * r + 0.587 * g + 0.114 * b) + +# 新添加:分析原图片整体亮度分布,确定亮度阈值 +brightness_values = [] +for w in range(imgPutong.width): + for h in range(imgPutong.height): + pxl = imgPutong.getpixel((w, h)) + brightness = calculate_brightness(pxl[0], pxl[1], pxl[2]) + brightness_values.append(brightness) + +# 新添加:计算亮度阈值(取70%分位数,只对较亮区域进行二维码叠加) +brightness_threshold = sorted(brightness_values)[int(len(brightness_values) * 0.7)] +print(f"新添加:亮度阈值设置为: {brightness_threshold}") + +# 新添加:寻找二维码的边界框,确定二维码的连续区域 +def find_barcode_bounds(img_barcode): + """新添加:找到二维码的边界框,确定二维码的连续区域""" + min_x, min_y = img_barcode.width, img_barcode.height + max_x, max_y = 0, 0 + + for w in range(img_barcode.width): + for h in range(img_barcode.height): + pxl = img_barcode.getpixel((w, h)) + if pxl[0] <= 200: # 黑色像素(二维码部分) + min_x = min(min_x, w) + min_y = min(min_y, h) + max_x = max(max_x, w) + max_y = max(max_y, h) + + return min_x, min_y, max_x, max_y + +# 新添加:获取二维码边界框 +barcode_min_x, barcode_min_y, barcode_max_x, barcode_max_y = find_barcode_bounds(imgBarcode) +print(f"新添加:二维码边界框: ({barcode_min_x}, {barcode_min_y}) 到 ({barcode_max_x}, {barcode_max_y})") + +# 新添加:在原图片中寻找最适合放置二维码的连续亮区域(优化版本) +def find_best_placement_region(img_putong, barcode_width, barcode_height, brightness_threshold): + """新添加:寻找最适合放置二维码的连续亮区域""" + print(f"新添加:开始搜索最佳位置,二维码尺寸: {barcode_width}x{barcode_height}") + + # 新添加:预计算所有像素的亮度值,避免重复计算 + brightness_map = [] + for y in range(img_putong.height): + row = [] + for x in range(img_putong.width): + pxl = img_putong.getpixel((x, y)) + brightness = calculate_brightness(pxl[0], pxl[1], pxl[2]) + row.append(brightness) + brightness_map.append(row) + + print(f"新添加:亮度图计算完成,开始搜索...") + + best_score = 0 + best_x, best_y = 0, 0 + total_positions = (img_putong.width - barcode_width + 1) * (img_putong.height - barcode_height + 1) + processed = 0 + + # 新添加:使用步长优化,减少计算量 + step = max(1, min(barcode_width, barcode_height) // 4) # 动态步长 + + for start_x in range(0, img_putong.width - barcode_width + 1, step): + for start_y in range(0, img_putong.height - barcode_height + 1, step): + processed += 1 + if processed % 1000 == 0: # 每1000个位置显示一次进度 + print(f"新添加:已处理 {processed}/{total_positions} 个位置...") + + # 计算该区域的平均亮度 + total_brightness = 0 + pixel_count = 0 + + for x in range(start_x, start_x + barcode_width): + for y in range(start_y, start_y + barcode_height): + total_brightness += brightness_map[y][x] + pixel_count += 1 + + avg_brightness = total_brightness / pixel_count + + # 如果平均亮度超过阈值,记录这个位置 + if avg_brightness >= brightness_threshold: + if avg_brightness > best_score: + best_score = avg_brightness + best_x, best_y = start_x, start_y + print(f"新添加:找到更好的位置: ({start_x}, {start_y}), 亮度: {avg_brightness:.1f}") + + print(f"新添加:搜索完成,最佳位置: ({best_x}, {best_y}), 亮度: {best_score:.1f}") + return best_x, best_y, best_score + +# 新添加:计算二维码尺寸 +barcode_width = barcode_max_x - barcode_min_x + 1 +barcode_height = barcode_max_y - barcode_min_y + 1 + +# 新添加:寻找最佳放置位置 +best_x, best_y, best_score = find_best_placement_region(imgPutong, barcode_width, barcode_height, brightness_threshold) +print(f"新添加:最佳放置位置: ({best_x}, {best_y}), 平均亮度: {best_score}") + +# 新添加:首先将原图片完整复制到合成图片 +for w in range(imgMix.width): + for h in range(imgMix.height): + pxlPutong = imgPutong.getpixel((w, h)) + imgMix.putpixel((w, h), (pxlPutong[0], pxlPutong[1], pxlPutong[2], 255)) + +# 新添加:在最佳位置放置完整的二维码 +print(f"新添加:开始在位置({best_x}, {best_y})放置二维码...") +for w in range(barcode_width): + for h in range(barcode_height): + # 计算在原图片中的实际位置 + img_x = best_x + w + img_y = best_y + h + + # 计算在二维码中的位置 + barcode_x = barcode_min_x + w + barcode_y = barcode_min_y + h + + # 确保不超出边界 + if (img_x < imgMix.width and img_y < imgMix.height and + barcode_x < imgBarcode.width and barcode_y < imgBarcode.height): + + pxlPutong = imgPutong.getpixel((img_x, img_y)) + pxlBarcode = imgBarcode.getpixel((barcode_x, barcode_y)) + + if pxlBarcode[0] <= 200: # 二维码的黑色部分 + # 新添加:使用改进的合成算法,确保颜色值在有效范围内 + alpha = 150 # 半透明 + new_r = max(0, min(255, int((pxlPutong[0] - (255-alpha)) / alpha * 255))) + new_g = max(0, min(255, int((pxlPutong[1] - (255-alpha)) / alpha * 255))) + new_b = max(0, min(255, int((pxlPutong[2] - (255-alpha)) / alpha * 255))) + imgMix.putpixel((img_x, img_y), (new_r, new_g, new_b, alpha)) +# 保存图片 +imgMix.save("C:/Users/huang'chen'lu/Desktop/pic_hide_barcode-main/新合成图片.png") +print("生成完毕,快去群里浪吧") + +