iconfinder 图标去水印

创建:xiaozi · 最后修改:xiaozi 2019-12-13 19:40 ·

目标

去除 iconfinder 上 icon 的水印

原理

利用水印像素点和原图像素点颜色合并的原理,如果拥有加过水印的图片和水印图片,就可以反向推出原图原像素点的颜色;前提是你得拥有他的水印图片

1、制作水印图片

1554316z7qpBfpfwwj7YeT 256x256 155431FRGl4FiOKv3lCMeW 256x256

我们先从iconfinder上找两张图片(保证纯水印的区域互补,可以合成一个完整的水印图),用这两张图片的两个部分,合成一张完整的水印图片,最终 256x256的水印是长这个样子的

155935BA5u2M5IlFG3KhW8 256x256

2、减去水印

2.1、水印是怎么加上去的

两个透明色的合并,颜色我们使用 rgba 来表示,看一下透明度的推导过程

125800N5BhsbPBGe99vt1a 1920x1080

第一块玻璃透明度是0.2,第二块玻璃透明度是0.5, 一束光通过两块玻璃后通过的光是多少

\$(1 - 0.2) \times (1 - 0.5)\$

按照上面的推理,可以得到下面的公式

两个透明色的合并

\$\alpha_t = 1 - (1 - \alpha_o)(1 - \alpha_w) \alpha_t = \alpha_o + \alpha_w - \alpha_o\alpha_w\$

反推一下,已知α_t和α_w的情况下求α_o

\$\alpha_o = \frac{\alpha_t - \alpha_w}{1 - \alpha_w}\$

从公式能看出来,如果水印是完全不透明的,那原来的透明度是求不出来的

125911gV1Zvi11Dtkr98FP 1920x1080

rbg 3个通道的颜色计算方式,用上面求出的α_o 值代入,求得R_o

\$R_t\alpha_t = R_o\alpha_o(1 - \alpha_w) + R_w\alpha_w\$

\$R_o = \frac{R_t\alpha_t - R_w\alpha_w}{\alpha_o(1 - \alpha_w)}\$

从公式能看出来,如果水印是完全不透明的,那原来的颜色是求不出来的

把加过水印的图和水印对应位置的像素进行逐个对比,如果水印位置是全透明的,则像素点的颜色不变,否则根据上面的公式反向计算出原来图片该像素点的颜色;

3、代码实现

# 安装依赖包
pip install pillow
from PIL import Image
import argparse
import os


def calc_pixel(input_rgba, watermark_rgba):
    watermark_red, watermark_green, watermark_blue, watermark_alpha = watermark_rgba
    if watermark_alpha == 255:
        return watermark_rgba
    input_red, input_green, input_blue, input_alpha = input_rgba
    output_alpha = 255 * (input_alpha - watermark_alpha) / (255 - watermark_alpha)
    if output_alpha == 0:
        return 0, 0, 0, 0
    output_red = 255 * (input_red * input_alpha - watermark_red * watermark_alpha) / \
                 ((255 - watermark_alpha) * output_alpha)
    output_green = 255 * (input_green * input_alpha - watermark_green * watermark_alpha) / \
                   ((255 - watermark_alpha) * output_alpha)
    output_blue = 255 * (input_blue * input_alpha - watermark_blue * watermark_alpha) / \
                  ((255 - watermark_alpha) * output_alpha)
    return round(output_red), round(output_green), round(output_blue), round(output_alpha)


def remove_watermark(input_name, watermark_name, output_name):
    if not os.path.exists(input_name):
        print("图片不存在")
        return
    input_image = Image.open(input_name)
    watermark_image = Image.open(watermark_name)
    output_image = Image.new(input_image.mode, input_image.size)
    w, h = input_image.size
    for x in range(w):
        for y in range(h):
            watermark_rgba = watermark_image.getpixel((x, y))
            input_rgba = input_image.getpixel((x, y))
            output_rgba = calc_pixel(input_rgba, watermark_rgba)
            output_image.putpixel((x, y), output_rgba)
    output_image.save(output_name)

def output_path_or_default(input_path, output_path):
    if output_path:
        return output_path
    root, ext = os.path.splitext(input_path)
    return root + ".unmark" + ext

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description = "watermark remover for iconfiner")
    parser.add_argument("--output", dest = "output", help = "output image")
    parser.add_argument("input", help = "input image")
    args = parser.parse_args()

    output = output_path_or_default(args.input, args.output)
    remove_watermark(args.input, "watermark.png", output)

浏览 30808 次

Home - Wiki
Copyright © 2011-2024 iteam. Current version is 2.139.0. UTC+08:00, 2024-12-22 23:46
浙ICP备14020137号-1 $Map of visitor$