V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
爱意满满的作品展示区。
kkocdko
V2EX  ›  分享创造

Realpha - 精确地恢复图片透明通道

  •  1
     
  •   kkocdko ·
    kkocdko · 2021-07-24 03:06:09 +08:00 · 2033 次点击
    这是一个创建于 979 天前的主题,其中的信息可能已经有所发展或是发生改变。

    首先,这名字读作“re-alpha”,而不是“real-pha”,谢谢配合。

    Screenshot

    给个链接瞅瞅?

    这是个 PWA:https://kkocdko.site/toy/realpha/

    附带一篇破文章:https://kkocdko.site/post/202107231958/。本人英文水平极低,各位看到狗屁不通的地方可以喷我。

    为什么需要这东西?

    想象这样一个场景:你看中了某个 App 里头的一枚图标,然而这枚图标是用代码动态绘制出的,无法从安装包中提取。所以你选择截图。

    然而这枚图标有半透明的部分,截图会导致透明通道丢失!怎么办?

    让我们看看给半透明图片增加背景的算法:

    var fgR, fgG, fgB, alpha;
    var bgR, bgG, bgB;
    var outR = fgR * aplha + bgR * (1 - aplha);
    

    可以看出这是个二元一次方程,要想解出原图的颜色和透明通道值,需要两个式子联立。

    于是,用调试工具强制更换 App 的背景颜色,截下两张图,输入到这个工具里头,你就能得到拥有准确透明通道的图片了。

    还有什么特别的玩法?

    你可以给手机换不同的纯色壁纸,得到不同背景色的截图之后,用此工具提取出透明的图片,再丢进 Photoshop 操作一番,做出不错的效果图(我的手机是透明的诶)。

    用 Photoshop 不行么?

    不行(说实话我不太确定,如果真能实现还请各位拍醒)。你当然可以抠图,然而这是不精确的,你永远无法凭空准确地还原出透明通道。

    13 条回复    2021-07-26 22:51:12 +08:00
    wdhwg001
        1
    wdhwg001  
       2021-07-24 03:41:38 +08:00 via iPhone   ❤️ 4
    其实,PS 的混合模式就是普通地进行数学运算。

    已知:减去就是相减,划分就是除法,正片叠底就是乘法。
    out1=fg*α+bg1*(1-α)
    out2=fg*α+bg2*(1-α)
    那么两式相减,视α为未知数,得:
    1-α=(out1-out2)/(bg1-bg2)

    α=1-(out1-out2)/(bg1-bg2)
    所以得 PS 步骤:
    ① 将 out1 图与 out2 图以“减去”混合,得 doc1
    ② 将 bg1 图与 bg2 图以“减去”混合,得 doc2
    ③ 将 doc1 与 doc2 图以“划分”混合,得 doc3
    ④ 将纯白色图与 doc3 图以“减去”混合,得 doc4
    doc4 即为还原后的 alpha
    回到式 1
    out1=fg*α+bg1*(1-α)
    将 fg 视为未知数,得
    fg=(out1-bg1*(1-α))/α
    所以得 PS 步骤:
    ① 将 bg1 图与 doc3 图以“正片叠底”混合,得 doc5
    ② 将 out1 图与 doc5 图以“减去”混合,得 doc6
    ③ 将 doc6 图与 doc4 图以“划分”混合,得 doc7
    最后,我们把 doc7 套用 doc4 作为蒙版,就得到了最终结果。

    未实际操作过,不对结果负责,深夜可能解错方程,结果也可能因 0-1 标准化而不可靠,并且多步骤会造成精度丢失,建议在 16 位模式下搞。
    kkocdko
        2
    kkocdko  
    OP
       2021-07-24 03:49:17 +08:00 via Android   ❤️ 1
    @wdhwg001 我的天还真的可以。。。我当时也改了半天混合模式,没倒腾出来,所以才写了这个工具。你这个方法应该是可行的,而且 PS 录制个动作,大量使用也不会麻烦,谢谢咯
    wdhwg001
        3
    wdhwg001  
       2021-07-24 03:51:26 +08:00 via iPhone
    PS 的问题还包括它其实每一步都做一遍 clamp,把负数和大于 1 的都 clamp 掉,所以实际操作的时候如果遇到不准确的情况可以用一个低于 255 的灰色图去提前正片叠底(乘法)或者线性减淡(加法),把颜色范围弄得小一点,尽量避免被 clamp 。
    wdhwg001
        4
    wdhwg001  
       2021-07-24 04:06:17 +08:00 via iPhone
    另外比较好用的还有:
    变暗是 min
    变亮是 max
    实色混合是 A+B>=1?1:0
    差值是|A-B|

    非常不好用但唯一包括 SQRT 的是:
    柔光:A<=0.5 ? 2*A*B+B*B*(1-2A) : 2*B*(1-A)+SQRT(B)*(2*A-1)

    会玩不嫌麻烦的话甚至可以在 PS 里写 Shader
    ericgui
        5
    ericgui  
       2021-07-24 05:05:33 +08:00 via iPhone   ❤️ 4
    ReAlpha,自然就知道是 re-alpha
    secondwtq
        6
    secondwtq  
       2021-07-24 09:03:51 +08:00
    PostgreSQL
    maplerecall
        7
    maplerecall  
       2021-07-24 09:54:38 +08:00 via Android   ❤️ 1
    这个其实就是 chroma key,如果图片本身颜色比较丰富,可能很难找到一个合适的色,因为和背景色接近的颜色会被当做透明被扣掉。
    no1xsyzy
        8
    no1xsyzy  
       2021-07-24 16:52:03 +08:00
    (可以搞个 GIMP 插件,然后宣称 GIMP 比 PS 牛逼(
    no1xsyzy
        9
    no1xsyzy  
       2021-07-24 16:55:05 +08:00
    @maplerecall 不是的,这是用两个纯色背景作差分。
    wdhwg001
        10
    wdhwg001  
       2021-07-26 14:26:56 +08:00
    做了一个 Photoshop 录制动作出来,看实际的效果发现,颜色比较鲜艳的话会被弄浅一点,并且需要切换至 16 位颜色以避免色带。
    https://user-images.githubusercontent.com/8943519/126942318-f032f5e3-6108-46f2-a461-6a06a2c50646.png
    将扩展名改为 zip 后打开,然后将 ReAlpha.atn 导入。
    执行时,需要提前准备好 out1 、out2 、bg1 、bg2 四个图层(名字不要错),并且四个图层的混合效果均需为“正常”。
    wdhwg001
        11
    wdhwg001  
       2021-07-26 14:39:04 +08:00   ❤️ 1
    进行了一下色阶对比:
    原始:
    https://user-images.githubusercontent.com/8943519/126943582-73583cef-1554-4266-918a-e3e7964ac022.png

    8-bit 色彩模式:
    https://user-images.githubusercontent.com/8943519/126943596-24a2bb4d-fc71-4af5-b30e-c9b8dd3c1abd.png

    16-bit 色彩模式:
    https://user-images.githubusercontent.com/8943519/126943601-579577fe-db9f-4816-a2cd-850ac8b6353d.png

    这种操作的色彩精度损失还是挺明显的,说明 Photoshop 在处理色彩的时候,因为每一步都需要把浮点色彩转换成整数色彩,在这个过程中精度损失会比较大。
    kkocdko
        12
    kkocdko  
    OP
       2021-07-26 19:32:27 +08:00
    @wdhwg001 那看来我这个工具还是有点用的咯~
    不过我觉得可以做个 Photoshop 的插件,毕竟精度损失主要是因为中间过程太多?一步到位损失会小很多吧
    wdhwg001
        13
    wdhwg001  
       2021-07-26 22:51:12 +08:00 via iPhone
    @kkocdko 是的,但其实最初 out1 和 out2 的合成就是有损的,而且是 8bit,所以永远做不到无损复原。

    但中间过程使用更高精度的运算还是很有必要的,毕竟 PS 里每通道最高 16 位的整数色无论如何都会丢失信息。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   5863 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 01:58 · PVG 09:58 · LAX 18:58 · JFK 21:58
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.