打印

[讨论] Kirikiri2系统的txt分割型立绘的合成问题

Kirikiri2系统的txt分割型立绘的合成问题

首先感谢resty大的插件
没有这插件也不能提取メルクリア~水の都に恋の花束を~

这几天合成从メルクリア~水の都に恋の花束を~提取出来的立绘
发现一个问题
其中一张合成图

全图: bst_02black.png

合成后眼泪是黑色的
开游戏看看
原本是这样的


经过几天研究
发现问题在于txt档内type栏
引用:
#layer_type        name        left        top        width        height        type        opacity        visible        layer_id        group_layer_id       
                                1100        1320                                               
0        顔原点        469        246        2        3        13        255        1        11816               
0        20_21_22_24_25_26_27_28        0        0        0        0        13        255        0        11893        2030       
0        01_02_03_04_05_06_07_08_09_10_11_12_13_14_15_17        0        0        0        0        13        255        0        11894        2030       
0        23        383        191        132        108        13        255        0        11899        2030       
0        涙        410        231        94        69        21        255        1        11901        711       
0        涙影        410        231        94        70        16        255        1        11900        711       
0        涙        419        242        79        20        21        255        1        11903        720       
0        涙k        419        242        80        21        16        255        1        11902        720       
0        涙 のコピー        414        243        88        23        21        255        1        11905        2041       
0        涙k のコピー        413        192        144        107        16        255        1        11904        2041       
2        28        0        0        0        0        13        255        0        484        2006       
2        27        0        0        0        0        13        255        0        482        2006       
2        21_22        0        0        0        0        13        255        0        480        2006       
2        頬hi        0        0        0        0        13        255        1        2020        1990       
2        頬デフォルト        0        0        0        0        13        255        1        2028        1990       
2        12_15        0        0        0        0        13        255        0        718        2028       
2        11_17_24        0        0        0        0        13        255        0        716        2028       
2        10_19_20_27        0        0        0        0        13        255        0        714        2028       
2        03_04_06_22_25_28        0        0        0        0        13        255        0        712        2028       
type栏是记载吉里吉里内部定义的合成模式
详细:
http://devdoc.kikyou.info/tvp/docs/kr2doc/contents/TPC.html
http://devdoc.kikyou.info/tvp/do ... /GraphicSystem.html

13=ltPsNormal
   普通的合成/Photoshop的Normal混合模式 (alpha blending?)
14=ltPsAdditive
   Photoshop的Linear Dodge (覆い焼き(リニア))混合模式
15=ltPsSubtractive
   Photoshop的Linear Burn (焼き込み(リニア))混合模式
16=ltPsMultiplicative
   Photoshop的Multiply (乗算)混合模式
17=ltPsScreen
   Photoshop的Screen (スクリーン)混合模式
18=ltPsOverlay
   Photoshop的Overlay (オーバーレイ)混合模式
19=ltPsHardLight
   Photoshop的Hard Light (ハードライト)混合模式
20=ltPsSoftLight
   Photoshop的Soft Light (ソフトライト)混合模式
21=ltPsColorDodge
   Photoshop的Color Dodge (覆い焼きカラー)混合模式
22=ltPsColorDodge5
   Photoshop 5.x以下的Color Dodge (覆い焼きカラー)混合模式
23=ltPsColorBurn
   Photoshop的Color Burn (焼き込みカラー)混合模式
24=ltPsLighten
   Photoshop的Lighten (比較(明))混合模式
25=ltPsDarken
   Photoshop的Darken (比較(暗))混合模式
26=ltPsDifference
   Photoshop的Difference (差の絶対値)混合模式
27=ltPsDifference5
   Photoshop 5.x以下的Difference (差の絶対値)混合模式
28=ltPsExclusion
   Photoshop的Exclusion (除外)混合模式

这张立绘的问题是眼泪那个图层的type是21
即是需要Color Dodge混合模式合成

在PS将那图层调回Color Dodge混合模式就没有问题了

全图: bst_02.png

合成这类立绘要注意一下

有兴趣研究的
JS set.rar
115

[ 本帖最后由 sfsuvival 于 2010-03-20 03:09 编辑 ]
要命,要重写了,用ImageMagick肯定不行了

blend(dest, min(1.0, dest ÷ ( 1.0 - src ) ), α)

这可不是一般alpha blending...

        private static int blendNormal(int dest, int src, int alpha) {
                return (src * alpha + dest * (255 - alpha)) / 255;
        }

        private static int blendColorDodge(int dest, int src, int alpha) {
                return blendNormal(dest, Math.min(255, dest / (255 - src)), alpha);
        }

src不会等于1.0?

[ 本帖最后由 haibara 于 2010-03-20 22:46 编辑 ]
sfsuvival, 我想问下,一般blending后最终图象的alpha怎么处理的

是与src的alpha一样,还是process(src alpha,dest alpha)这样的?

我想把alpha处理固定下来,把上面所有的blending模式加到directmuxer里面去

[ 本帖最后由 haibara 于 2010-03-20 14:17 编辑 ]
呃,偶是飘过的,本来有问题问,现在解决了。。。

[ 本帖最后由 airlose 于 2010-03-20 18:26 编辑 ]
我的空间,一些稀有北米版游戏下载及其他
为了避免被HX,大部分没有预览,留给识货人士。。。
http://hi.baidu.com/acgcg
北米版及日版CG分流
http://tora.to/discutter/40144.htm


private static int blendColorDodge(int dest, int src, int alpha) {
                return blendNormal(dest, src == 255 ? src : Math.min(255, (dest << 8) / (255 - src)), alpha);
        }

为什么dest要x256?

[ 本帖最后由 haibara 于 2010-03-21 20:52 编辑 ]
...我对图像处理的认识不深
这只是研究出来的结果
我也不知道那些合成模式的原理...
引用:
原帖由 haibara 于 2010-03-20 01:51 发表
要命,要重写了,用ImageMagick肯定不行了

blend(dest, min(1.0, dest ÷ ( 1.0 - src ) ), α)

这可不是一般alpha blending...

        private static int blendNormal(int dest, int src, int alpha) {
                return (src * alpha + dest * (255 - alpha)) / 255;
        }

        private static int blendColorDodge(int dest, int src, int alpha) {
                return blendNormal(dest, Math.min(255, dest / (255 - src)), alpha);
        }

src不会等于1.0?
这个可能是因为有用min
所以即使dest ÷ ( 1.0 - src ) 是无限大也不管了...
引用:
原帖由 haibara 于 2010-03-20 14:13 发表
sfsuvival, 我想问下,一般blending后最终图象的alpha怎么处理的

是与src的alpha一样,还是process(src alpha,dest alpha)这样的?

我想把alpha处理固定下来,把上面所有的blending模式加到directmuxer里面去
老实说我弄不清什么是alpha blending...
我觉得alpha blending的α是指整个图层的opacity
不是从图层的alpha channel拿出来的数值...
Value=(1-α)Value0+αValue1
Value0, Value1和Value是RGBA的数值

我看到一个更像是用alpha channel的数值合成图层的算式
http://en.wikipedia.org/wiki/Alpha_compositing
αoab(1-αa)
Co=(Caαa+Cbαb(1-αa))/ αo

αo是最终图象的alpha
Co是最终图象的RGB值
引用:
原帖由 haibara 于 2010-03-21 20:47 发表
private static int blendColorDodge(int dest, int src, int alpha) {
                return blendNormal(dest, src == 255 ? src : Math.min(255, (dest << 8) / (255 - src)), alpha);
        }

为什么dest要x256?
不知道你在哪里找到这算式...

[ 本帖最后由 sfsuvival 于 2010-03-22 04:36 编辑 ]
引用:
原帖由 sfsuvival 于 2010-03-22 02:41 发表
...我对图像处理的认识不深
这只是研究出来的结果
我也不知道那些合成模式的原理...


这个可能是因为有用min
所以即使dest ÷ ( 1.0 - src ) 是无限大也不管了...


老实说我弄不清什么是alpha blending.. ...
我比较认同αo是255的opaque,而非来源f(alpha,alpha)


也就是你给的文章的Alpha blending

java官方的desktop的BlendComposite也是这个实现(预乘alpha是个浮点参数,对像素做这样的操作,result做前期blend处理,在AlphaBlending中result是否等于src?),而java的标准库里的AlphaComposite就比较晕头转向了

                    blender.blend(srcPixel, dstPixel, result);

                    // mixes the result with the opacity
                    dstPixels[x] = ((int) (dstPixel[3] + (result[3] - dstPixel[3]) * alpha) & 0xFF) << 24 |
                                   ((int) (dstPixel[0] + (result[0] - dstPixel[0]) * alpha) & 0xFF) << 16 |
                                   ((int) (dstPixel[1] + (result[1] - dstPixel[1]) * alpha) & 0xFF) <<  8 |
                                    (int) (dstPixel[2] + (result[2] - dstPixel[2]) * alpha) & 0xFF;



而BlendComposite的COLOR_DODGE是这样的
public void blend(int[] src, int[] dst, int[] result) {
                            result[0] = src[0] == 255 ? 255 :
                                Math.min((dst[0] << 8) / (255 - src[0]), 255);
                            result[1] = src[1] == 255 ? 255 :
                                Math.min((dst[1] << 8) / (255 - src[1]), 255);
                            result[2] = src[2] == 255 ? 255 :
                                Math.min((dst[2] << 8) / (255 - src[2]), 255);
                            result[3] = Math.min(255, src[3] + dst[3] - (src[3] * dst[3]) / 255);
                        }

与kr2doc区别就在dest要x256

x256我看与ps效果是一样的,不乘明显错误

[ 本帖最后由 haibara 于 2010-03-22 11:19 编辑 ]
引用:
原帖由 haibara 于 2010-03-22 10:50 发表


我比较认同αo是255的opaque,而非来源f(alpha,alpha)


也就是你给的文章的Alpha blending
我也有这样想过
不过这样的话Alpha blending后的图和没有alpha一样(整张图的alpha都是255=整张图不透明=alpha没有用)
事件图合成还可以这样做
但立绘合成就麻烦了
合成后该透明的地方不透明了
我看见一些文章的Value0, Value1和Value是RGBA的数值
两张图的alpha和RGB值一样也去做alpha blending
不知道这是否正确...
引用:
java官方的desktop的BlendComposite也是这个实现(预乘alpha是个浮点参数,对像素做这样的操作,result做前期 blend处理,在AlphaBlending中result是否等于src?),而java的标准库里的AlphaComposite就比较晕头转向了

                    blender.blend(srcPixel, dstPixel, result);

                    // mixes the result with the opacity
                    dstPixels[x] = ((int) (dstPixel[3] + (result[3] - dstPixel[3]) * alpha) & 0xFF) << 24 |
                                   ((int) (dstPixel[0] + (result[0] - dstPixel[0]) * alpha) & 0xFF) << 16 |
                                   ((int) (dstPixel[1] + (result[1] - dstPixel[1]) * alpha) & 0xFF) <<  8 |
                                    (int) (dstPixel[2] + (result[2] - dstPixel[2]) * alpha) & 0xFF;
这个是将blend完的值再和alpha混合
和计算premultiplied alpha的原理相似
但是不是计算premultiplied alpha的方法
所以我不知道这是什么...
引用:
而BlendComposite的COLOR_DODGE是这样的
public void blend(int[] src, int[] dst, int[] result) {
                            result[0] = src[0] == 255 ? 255 :
                                Math.min((dst[0] << 8) / (255 - src[0]), 255);
                            result[1] = src[1] == 255 ? 255 :
                                Math.min((dst[1] << 8) / (255 - src[1]), 255);
                            result[2] = src[2] == 255 ? 255 :
                                Math.min((dst[2] << 8) / (255 - src[2]), 255);
                            result[3] = Math.min(255, src[3] + dst[3] - (src[3] * dst[3]) / 255);
                        }

与kr2doc区别就在dest要x256

x256我看与ps效果是一样的,不乘明显错误
kr2doc的dest和src是[0,1]
blend(dest, min(1.0, dest ÷ ( 1.0 - src ) ), α)
所以当你的dest和src是[0,255] 的话要x255
至于x256的原因我看到的解释是因为x256比x255快(只需位移位(bit shifting))
我看到其它大同小异的计算方法
如GIMP的Dodge
http://docs.gimp.org/2.6/en/gimp-concepts-layer-modes.html
多了+1应该是为了避免除0

SVG的alpha compositing有记下composite后的alpha值
你可以去看看
http://www.w3.org/TR/2004/WD-SVG12-20041027/rendering.html

[ 本帖最后由 sfsuvival 于 2010-03-22 16:06 编辑 ]
引用:
原帖由 sfsuvival 于 2010-03-22 16:04 发表


我也有这样想过
不过这样的话Alpha blending后的图和没有alpha一样(整张图的alpha都是255=整张图不透明=alpha没有用)
事件图合成还可以这样做
但立绘合成就麻烦了
合成后该透明的地方不透明了
我看见一些文 ...
以extractdata为例,它alpha blending就当alpha none,只保留rgb...

最后关于alpha blending,还是MS看的爽眼,实在不高兴折腾了
http://msdn.microsoft.com/en-us/library/dd183393%28VS.85%29.aspx

至于dest ÷ ( 1.0 - src )等价rgb int是(dest/255)/(1-src/255)*255=dest/(1-src/255)=dest*255/(255-src)(原先是我自己乘除法搞错了,不过为什么不是255呢)
GIMP+1可能是防0,但是java那个本来就判断src是否等于255的。。。

[ 本帖最后由 haibara 于 2010-03-23 00:31 编辑 ]
引用:
原帖由 haibara 于 2010-03-23 00:17 发表


以extractdata为例,它alpha blending就当alpha none,只保留rgb...

最后关于alpha blending,还是MS看的爽眼,实在不高兴折腾了
http://msdn.microsoft.com/en-us/library/dd183393%28VS.85%29.aspx

至于 ...
M$这个不是和维基alpha compositing的公式一样吗?

当SourceConstantAlpha=0xFF (合成时不需要改整张图的opacity)
Dst.Red = Src.Red + (1 - Src.Alpha) * Dst.Red
Dst.Green = Src.Green + (1 - Src.Alpha) * Dst.Green
Dst.Blue = Src.Blue + (1 - Src.Alpha) * Dst.Blue
Dst.Alpha = Src.Alpha + (1 - SrcAlpha) * Dst.Alpha
因为Src和Dst是用premultiplied alpha
所以即是
Dst.Alpha * Dst.Color = Src.Alpha * Src.Color + (1 – Src.Alpha) * Dst.Alpha * Dst.Color
αoCo=(αaCa+(1-αabCb)


Dst.Alpha = Src.Alpha + (1 - SrcAlpha) * Dst.Alpha


x256的原因应该就是x256比x255快
Java的是正常做法
GIMP那+1比较

[ 本帖最后由 sfsuvival 于 2010-03-23 12:38 编辑 ]
查看积分策略说明

快速回复主题

选项

[完成后可按 Ctrl+Enter 发布]  预览帖子  恢复数据  清空内容

当前时区 GMT+8, 现在时间是 2024-03-29 20:36

Processed in 0.014287 second(s), 5 queries.