Board logo

标题: [讨论] Kirikiri2系统的txt分割型立绘的合成问题 [打印本页]

作者: sfsuvival    时间: 2010-03-19 22:40     标题: 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 编辑 ]
作者: 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?

[ 本帖最后由 haibara 于 2010-03-20 22:46 编辑 ]
作者: haibara    时间: 2010-03-20 14:13

sfsuvival, 我想问下,一般blending后最终图象的alpha怎么处理的

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

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

[ 本帖最后由 haibara 于 2010-03-20 14:17 编辑 ]
作者: airlose    时间: 2010-03-20 18:01

呃,偶是飘过的,本来有问题问,现在解决了。。。

[ 本帖最后由 airlose 于 2010-03-20 18:26 编辑 ]
作者: 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?

[ 本帖最后由 haibara 于 2010-03-21 20:52 编辑 ]
作者: sfsuvival    时间: 2010-03-22 02:41

...我对图像处理的认识不深
这只是研究出来的结果
我也不知道那些合成模式的原理...
引用:
原帖由 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-α)Value[sub]0[/sub]+αValue[sub]1[/sub]
Value[sub]0[/sub], Value[sub]1[/sub]和Value是RGBA的数值

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

α[sub]o[/sub]是最终图象的alpha
C[sub]o[/sub]是最终图象的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 编辑 ]
作者: haibara    时间: 2010-03-22 10:50

引用:
原帖由 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 编辑 ]
作者: sfsuvival    时间: 2010-03-22 16:04

引用:
原帖由 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 编辑 ]
作者: haibara    时间: 2010-03-23 00:17

引用:
原帖由 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 编辑 ]
作者: sfsuvival    时间: 2010-03-23 12:35

引用:
原帖由 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
α[sub]o[/sub]C[sub]o[/sub]=(α[sub]a[/sub]C[sub]a[/sub]+(1-α[sub]a[/sub])α[sub]b[/sub]C[sub]b[/sub])


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


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

[ 本帖最后由 sfsuvival 于 2010-03-23 12:38 编辑 ]
作者: haibara    时间: 2010-03-23 20:55

引用:
原帖由 sfsuvival 于 2010-03-23 12:35 发表


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

当SourceConstantAlpha=0xFF (合成时不需要改整张图的opacity)
Dst.Red = Src.Red + (1 - Src.Alpha) * Dst.Red
Dst.Green = Src.Green + (1 - Src.Alpha) ...
好麻烦。还是用这个好了


刚才看了IM的实现,我的妈呀,大概是SVG标准那个实现

00088 static inline void MagickPixelCompositeOver(const MagickPixelPacket *p,
00089   const MagickRealType alpha,const MagickPixelPacket *q,
00090   const MagickRealType beta,MagickPixelPacket *composite)
00091 {
00092   MagickRealType
00093     gamma;
00094
00095   if (alpha == TransparentOpacity)
00096     {
00097       *composite=(*q);
00098       return;
00099     }
00100   gamma=1.0-QuantumScale*QuantumScale*alpha*beta;
00101   composite->opacity=(MagickRealType) QuantumRange*(1.0-gamma);
00102   gamma=1.0/(gamma <= MagickEpsilon ? 1.0 : gamma);
00103   composite->red=gamma*MagickOver_(p->red,alpha,q->red,beta);
00104   composite->green=gamma*MagickOver_(p->green,alpha,q->green,beta);
00105   composite->blue=gamma*MagickOver_(p->blue,alpha,q->blue,beta);
00106   if ((p->colorspace == CMYKColorspace) && (q->colorspace == CMYKColorspace))
00107     composite->index=gamma*MagickOver_(p->index,alpha,q->index,beta);
00108 }


00038 static inline MagickRealType MagickOver_(const MagickRealType p,
00039   const MagickRealType alpha,const MagickRealType q,const MagickRealType beta)
00040 {
00041   MagickRealType
00042     pixel;
00043
00044   pixel=(1.0-QuantumScale*alpha)*p+(1.0-QuantumScale*beta)*q*QuantumScale*alpha;
00045   return(pixel);
00046 }

[ 本帖最后由 haibara 于 2010-03-23 23:29 编辑 ]
作者: haibara    时间: 2010-03-24 22:53

alpha = deltaPixel[i + 3] & 0xff;
                                        beta = basicPixel[i + 3] & 0xff;
                                        resultPixel = (byte) blend(basicPixel & 0xff, deltaPixel & 0xff, alpha);
                                        resultPixel[i + 1] = (byte) blend(basicPixel[i + 1] & 0xff, deltaPixel[i + 1] & 0xff, alpha);
                                        resultPixel[i + 2] = (byte) blend(basicPixel[i + 2] & 0xff, deltaPixel[i + 2] & 0xff, alpha);
                                       

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

若基本图无alpha,或者是opaque alpha,这个就够了

[ 本帖最后由 haibara 于 2010-03-25 07:09 编辑 ]
作者: haibara    时间: 2010-03-24 22:54

alpha = deltaPixel[i + 3] & 0xff;
                                        beta = basicPixel[i + 3] & 0xff;
                                        gramma = alpha + beta - alpha * beta / 255;
                                        if (gramma == 0) {
                                                delta = 1;
                                        } else {
                                                delta = gramma;
                                        }
                                        resultPixel = (byte) (composite(deltaPixel & 0xff, basicPixel & 0xff, alpha, beta) / delta);
                                        resultPixel[i + 1] = (byte) (composite(deltaPixel[i + 1] & 0xff, basicPixel[i + 1] & 0xff, alpha, beta) / delta);
                                        resultPixel[i + 2] = (byte) (composite(deltaPixel[i + 2] & 0xff, basicPixel[i + 2] & 0xff, alpha, beta) / delta);
                                        resultPixel[i + 3] = (byte) gramma;

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

按照svg那个来完整的是这样,不过速度居然差不多,vm优化的厉害

[ 本帖最后由 haibara 于 2010-03-25 00:45 编辑 ]
作者: sfsuvival    时间: 2010-03-25 18:41

im的好像和svg不同
翻了一下
如果图是8位/色彩通道
TransparentOpacity = QuantumRange = 255
QuantumScale = 1/255
MagickEpsilon = 2.0*1.1920928955078125e-07
MagickRealType = double
im合成后的α是alpha*beta...

svg的不又是和维基的alpha compositing一样...
结果svg的src-over=M$的AC_SRC_OVER=维基的alpha compositing
可信性较高?
作者: haibara    时间: 2010-03-25 19:23

引用:
原帖由 sfsuvival 于 2010-03-25 18:41 发表
im的好像和svg不同
翻了一下
如果图是8位/色彩通道
TransparentOpacity = QuantumRange = 255
QuantumScale = 1/255
MagickEpsilon = 2.0*1.1920928955078125e-07
MagickRealType = double
im合成后的α是alp ...
我程序已经改成svg的src-over,M$的AC_SRC_OVER,维基的alpha compositing

        private static int blend(int src, int dest, int alpha) {
                if (alpha == 0) {
                        return dest;
                }
                if (alpha == 255) {
                        return src;
                }
                return dest + (src - dest) * alpha / 255;
        }

        private static int blend(int src, int dest, int alpha, int beta) {
                if (alpha == 0) {
                        return dest;
                }
                if (alpha == 255 || beta == 0) {
                        return src;
                }
                if (beta == 255) {
                        return blend(src, dest, alpha);
                }
                return (src * alpha * 255 + dest * beta * 255 - dest * alpha * beta) / (alpha * 255 + beta * 255 - alpha * beta);
        }

[ 本帖最后由 haibara 于 2010-03-26 14:49 编辑 ]
作者: sfsuvival    时间: 2010-03-26 22:37

看不到有什么问题
用java实现svg的src-over/M$的AC_SRC_OVER/维基的alpha compositing
应该就是这样...

blending是需要2张图
但blend mode是一张图的属性
haibara你是怎样处理?
看PS是用src的blend mode将src和dst合成
然后将合成后的图的blend mode设为dst的...

[ 本帖最后由 sfsuvival 于 2010-03-26 23:40 编辑 ]
作者: haibara    时间: 2010-04-02 11:08

引用:
原帖由 sfsuvival 于 2010-03-26 22:37 发表
看不到有什么问题
用java实现svg的src-over/M$的AC_SRC_OVER/维基的alpha compositing
应该就是这样...

blending是需要2张图
但blend mode是一张图的属性
haibara你是怎样处理?
看PS是用src的blend mode将sr ...
我不太懂ps

directmuxer合成模式从差分图那边取

目前还有个问题:

我测试
整数的算法(alpha blending),即
(src * alpha * 255 + dest * beta * (255 - alpha)) / (alpha * 255 + beta * 255 - alpha * beta);
浮点数的算法(complex composite的normal),即
Sa = alpha / 255D;
Da = beta / 255D;
Sc = src / 255D;
Dc = dest / 255D;
Sca = Sa * Sc;
Dca = Da * Dc;
Ra = Sa + Da - Sa * Da;
(Sca + Dca * (1 - Sa)) / Ra * 255

目测看边缘锯齿差别很大,为什么,精度?

[ 本帖最后由 haibara 于 2010-04-02 12:01 编辑 ]
作者: sfsuvival    时间: 2010-04-03 01:57

引用:
原帖由 haibara 于 2010-04-02 11:08 发表


我不太懂ps

directmuxer合成模式从差分图那边取

目前还有个问题:

我测试
整数的算法(alpha blending),即
(src * alpha * 255 + dest * beta * (255 - alpha)) / (alpha * 255 + beta * 255 - alpha ...
double的精确度已经很高
会否你在处理运算时做了些减低精确度的动作?

我用你给的源码写了个试试
两种方法输出的数字一样,没有问题
复制内容到剪贴板
代码:
import java.util.Random;

public class TestRange {
        public static void main(String[] args) {
                Random randomGenerator = new Random();
                int src = randomGenerator.nextInt(256);
                int dest = randomGenerator.nextInt(256);
                int alpha = randomGenerator.nextInt(256);
                int beta = randomGenerator.nextInt(256);
                double Sa, Da, Sc, Dc, Sca, Dca, Ra, Rc;
               
                int gamma = alpha * 255 + beta * 255 - alpha * beta;
                int res = (src * alpha * 255 + dest * beta * (255 - alpha)) / gamma;
                gamma /= 255;
                System.out.println(res);
                System.out.println(gamma);
               
                Sa = alpha / 255D;
                Da = beta / 255D;
                Sc = src / 255D;
                Dc = dest / 255D;
                Sca = Sa * Sc;
                Dca = Da * Dc;
                Ra = Sa + Da - Sa * Da;
                Rc = (Sca + Dca * (1 - Sa)) / Ra;
                System.out.println((int)(Rc * 255));
                System.out.println((int)(Ra * 255));
        }
}
[ 本帖最后由 sfsuvival 于 2010-04-03 04:41 编辑 ]
作者: haibara    时间: 2010-04-03 10:22

引用:
原帖由 sfsuvival 于 2010-04-03 01:57 发表


double的精确度已经很高
会否你在处理运算时做了些减低精确度的动作?

我用你给的源码写了个试试
两种方法输出的数字一样,没有问题

import java.util.Random;

public class TestRange {
        public sta ...
我觉得没有,而且我尽量减少除法的,所以上下同时比一般多乘了次255,才有(src * alpha * 255 + dest * beta * (255 - alpha)) / (alpha * 255 + beta * 255 - alpha * beta)

而且也应该与非算法部分无法,我在这2个算法相互替换写法,结果还是有异常

总之就是锯齿部分有差别

还有

http://www.w3.org/TR/2009/WD-SVGCompositing-20090430/
http://www.w3.org/TR/2004/WD-SVG12-20041027/rendering.html

这2个不同版本,应该选择哪个,按照目测ps里colordodge是2004的,softlight是2009的

而且Subtractive/LinearBurn在SVG没有实现怎么办

[ 本帖最后由 haibara 于 2010-04-03 20:55 编辑 ]
作者: sfsuvival    时间: 2010-04-04 05:59

引用:
原帖由 haibara 于 2010-04-03 10:22 发表


我觉得没有,而且我尽量减少除法的,所以上下同时比一般多乘了次255,才有(src * alpha * 255 + dest * beta * (255 - alpha)) / (alpha * 255 + beta * 255 - alpha * beta)

而且也应该与非算法部分无法,我在这2个算法相互替换写法,结果还是有异常

总之就是锯齿部分有差别
既然你觉得是算法的问题
可以像我那样抽出来试试
也许会发现问题所在...

我上面写的java测试过没有问题
也许你可以对比一下?
这个问题既然隐藏得这么好
没有完整源码很难推测哪里有问题...
引用:
还有

http://www.w3.org/TR/2009/WD-SVGCompositing-20090430/
http://www.w3.org/TR/2004/WD-SVG12-20041027/rendering.html

这2个不同版本,应该选择哪个,按照目测ps里colordodge是2004的,softlight是2009的
既然这种立绘是由psd分割出来的
用ps的方法将其合并是最好的
因为我不懂这些合成模式的原理
只看算法我也看不出实际会有什么不同的效果
你觉得那种和ps的效果相近就用那种吧
你是用那个版本的ps
我的是cs2
不同版本的ps合成效果应该不会不同吧...
引用:
而且Subtractive/LinearBurn在SVG没有实现怎么办
...svg没有也没有办法
唯有选别的...
之前你提到的java的BlendComposite没有Subtractive/LinearBurn的源码吗?
难道效果和ps的差很远?

[ 本帖最后由 sfsuvival 于 2010-04-04 06:11 编辑 ]
作者: haibara    时间: 2010-04-04 09:11

引用:
原帖由 sfsuvival 于 2010-04-04 05:59 发表

既然你觉得是算法的问题
可以像我那样抽出来试试
也许会发现问题所在...

我上面写的java测试过没有问题
也许你可以对比一下?
这个问题既然隐藏得这么好
没有完整源码很难推测哪里有问题...


既然这种立 ...
昨天与soul1000测试了下,结果发现整数我做了提前优化的关系,即我做了当alpha,beta等于0,255时,化简了公式,所以与浮点产生了差别

对于colordodge,softlight,那就以ps为标准,本来想提供选项SVG 2004,SVG 2009的

BlendComposite是有Subtractive的

case SUBTRACT:
                    return new Blender() {
                        @Override
                        public void blend(int[] src, int[] dst, int[] result) {
                            result[0] = Math.max(0, src[0] + dst[0] - 256);
                            result[1] = Math.max(0, src[1] + dst[1] - 256);
                            result[2] = Math.max(0, src[2] + dst[2] - 256);
                            result[3] = Math.min(255, src[3] + dst[3] - (src[3] * dst[3]) / 255);
                        }
                    };

                    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;

1st计算出2nd需要的result,问题是2nd里的alpha,在我这里应该是result的alpha,它原来是自定义的预乘系数
作者: sfsuvival    时间: 2010-04-05 01:16

http://www.java2s.com/Code/Java/ ... ndCompositeDemo.htm
这是你找到的BlendComposite源码来源?
引用:
* <h2>Opacity</h2>
* <p>Each blending mode has an associated opacity, defined as a float value
* between 0.0 and 1.0. Changing the opacity controls the force with which the
* compositing operation is applied. For instance, a composite with an opacity
* of 0.0 will not draw the source onto the destination. With an opacity of
* 1.0, the source will be fully drawn onto the destination, according to the
* selected blending mode rule.</p>
* <p>The opacity, or alpha value, is used by the composite instance to mutiply
* the alpha value of each pixel of the source when being composited over the
* destination.</p>
引用:
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;
2nd里的alpha应该是指整张图层的opacity
不是指像素内的alpha值
现在DirectMuxer设所有图层的opacity为255 => alpha = 1.0
dstPixel[3] + (result[3] - dstPixel[3]) * alpha = result[3]
现在2nd就是普通设像素值的方法

2nd与blend方式无关
你可以先实现BlendComposite的SUBTRACT和ps对比一下结果

[ 本帖最后由 sfsuvival 于 2010-04-05 01:26 编辑 ]
作者: haibara    时间: 2010-04-05 01:57

引用:
原帖由 sfsuvival 于 2010-04-05 01:16 发表
http://www.java2s.com/Code/Java/ ... ndCompositeDemo.htm
这是你找到的BlendComposite源码来源?




2nd里的alpha应该是指整张图层的opacity
不是指像素内的alpha值
现在DirectMuxer设所有 ...
是,来自官方的swinglabs,http://swingx.dev.java.net/

那算法里面的alpha,是自定义的图层alpha,如果写成我这里的情况,应该是结构图的alpha吧

明天测试看减法

[ 本帖最后由 haibara 于 2010-04-05 12:25 编辑 ]
作者: haibara    时间: 2010-04-05 23:13

还有个大问题

目前按照SVG来的alpha blending虽然目测与ps的normal一样

但实际取读字节数据,有发现相当多的点的RGB不同呀

这个我烦恼了很长时间了
作者: sfsuvival    时间: 2010-04-06 08:12

引用:
原帖由 haibara 于 2010-04-05 23:13 发表
还有个大问题

目前按照SVG来的alpha blending虽然目测与ps的normal一样

但实际取读字节数据,有发现相当多的点的RGB不同呀

这个我烦恼了很长时间了
PS的blending太复杂
又有opacity/fill/layer mask/adjustment layer等东西
即使opacity=100%,fill=100%,没有layer mask和adjustment layer
是否只根据blend mode合成
假设的确是只根据blend mode合成
而且blend mode是和SVG的标准一样
也不知道PS会否对合成前/时/后做些特别处理,如优化速度/合成效果等
要做到和PS的合成完全一样似乎十分困难

做了些测试
随意选两张用
DirectMuxer (Alpha blending/Complex composite)
GIMP 2.6.8
ImageMagick 6.5.8-8
Photoshop CS2
PicComposite
pngmux
SAI 1.1.0
进行普通合成
虽然目测所有合成图是一样的
但事实是没有两张所有像素完全相同的合成图…
上述的软件都输出不同的合成图…
看来也没有其它软件能做到和PS的合成一样
没有通用标准的东西就是这样?

[ 本帖最后由 sfsuvival 于 2010-04-06 08:26 编辑 ]
作者: soul1000    时间: 2010-04-06 08:31

哎,不同软件有不同的算法优化,有得喜欢精度是浮点的,有的是整形的,有得可能会进行4舍5入什么的,不要再为某一点算出来是0xFFFFFF又还是0xFFFFFE而去计较了 = =  反正也看不出,只要公式正确就可以了。。。
作者: haibara    时间: 2010-04-06 14:26

public int lineardodge() {
                Ra = Math.min(1D, Sa + Da);
                return (int) (Ra * 255);
        }

        public int lineardodge(int src, int dest) {
                Sc = Math.min(1D, (src / 255D) + (dest / 255D));
                Dc = dest / 255D;
                Sca = Sa * Sc;
                Dca = Da * Dc;
                return (int) ((Sca + Dca * (1 - Sa)) / Ra * 255);
        }

        public int linearburn() {
                Ra = Sa + Da - Sa * Da;
                return (int) (Ra * 255);
        }

        public int linearburn(int src, int dest) {
                Sc = Math.max(0D, (src / 255D) + (dest / 255D) - 1D);
                Dc = dest / 255D;
                Sca = Sa * Sc;
                Dca = Da * Dc;
                return (int) ((Sca + Dca * (1 - Sa)) / Ra * 255);
        }

以上猜测虽然目测很象PS了,但是总有小部分不一样

下面我看IM的源码写了lineardodge

        private final long QuantumRange = 65535L;
        private final double QuantumScale = 1D / 65535L;
        private final double MagickEpsilon = 1.0e-10;

        public int lineardodge() {               
                  Sa=1D-QuantumScale*alpha;
                  Da=1D-QuantumScale*beta;
                  gamma=RoundToUnity(Sa+Da-Sa*Da);
                  return (int) (QuantumRange*(1D-gamma));  
        }

        public int lineardodge(int src, int dest) {
                  gamma=1D/(Math.abs(gamma) <= MagickEpsilon ? 1D : gamma);
                  return (int) (gamma*(src*Sa+dest*Da));
        }

        private double RoundToUnity(double value) {
                return (value < 0D ? 0D : (value > 1D) ? 1D : value);
        }

我觉得应该是等价的,但是合成出来差太多了,不知怎么搞的

IM源码:
static inline void CompositeLinearDodge(const MagickPixelPacket *p,
  const MagickRealType alpha,const MagickPixelPacket *q,
  const MagickRealType beta,MagickPixelPacket *composite)
{
  MagickRealType
    Da,
    gamma,
    Sa;

  Sa=1.0-QuantumScale*alpha;  /* simplify and speed up equations */
  Da=1.0-QuantumScale*beta;
  gamma=RoundToUnity(Sa+Da-Sa*Da); /* over blend, as per SVG doc */
  composite->opacity=(MagickRealType) QuantumRange*(1.0-gamma);
  /*
    Operation performed directly - not need for sub-routine.
  */
  gamma=1.0/(fabs(gamma) <= MagickEpsilon ? 1.0 : gamma);
  composite->red=gamma*(p->red*Sa+q->red*Da);
  composite->green=gamma*(p->green*Sa+q->green*Da);
  composite->blue=gamma*(p->blue*Sa+q->blue*Da);
  if (q->colorspace == CMYKColorspace)
    composite->index=gamma*(p->index*Sa+q->index*Da);
}

[ 本帖最后由 haibara 于 2010-04-06 22:58 编辑 ]
作者: sfsuvival    时间: 2010-04-07 00:23

引用:
原帖由 haibara 于 2010-04-06 14:26 发表
        public int lineardodge(int src, int dest) {
                Sc = Math.min(1D, (src / 255D) + (dest / 255D));
                Dc = dest / 255D;
                Sca = Sa * Sc;
                Dca = Da * Dc;
                return (int) ((Sca + Dca * (1 - Sa)) / Ra * 255);
        }
看不懂你为何将部分blending先算到Sc内...
引用:
        private final long QuantumRange = 65535L;
        private final double QuantumScale = 1D / 65535L;
        private final double MagickEpsilon = 1.0e-10;
你这个是每通道16位的定义
每通道8位的话
QuantumRange = 255
QuantumScale = 1 / 255
MagickEpsilon = 1.0e-6

参考:
http://www.imagemagick.org/RMagick/doc/constants.html
http://www.imagemagick.org/api/M ... type_8h-source.html
引用:
00039 #if (MAGICKCORE_QUANTUM_DEPTH == 8)
00040 #define MagickEpsilon  1.0e-6
00041 #define MagickHuge     1.0e6
00042 #define MaxColormapSize  256UL
00043 #define MaxMap  255UL
00044
00045 typedef double MagickRealType;
00046 #if defined(MAGICKCORE_HDRI_SUPPORT)
00047 typedef float Quantum;
00048 #define QuantumRange  255.0
00049 #define QuantumFormat  "%g"
00050 #else
00051 typedef unsigned char Quantum;
00052 #define QuantumRange  255UL
00053 #define QuantumFormat  "%u"
00054 #endif

作者: haibara    时间: 2010-04-07 07:12

引用:
原帖由 sfsuvival 于 2010-04-07 00:23 发表

看不懂你为何将部分blending先算到Sc内...


你这个是每通道16位的定义
每通道8位的话
QuantumRange = 255
QuantumScale = 1 / 255
MagickEpsilon = 1.0e-6

参考:
http://www.imagemagick.org/RMagick/ ...
因为我看blendcomposite是先混合出result再与dest进行blending的

奇怪,我搜索的怎么是那样的(/www/api/MagickCore/magick-type_8h.html),不过即使换成8位,结果仍然很大不同

[ 本帖最后由 haibara 于 2010-04-07 07:15 编辑 ]
作者: sfsuvival    时间: 2010-04-08 19:23

引用:
原帖由 haibara 于 2010-04-07 07:12 发表


因为我看blendcomposite是先混合出result再与dest进行blending的

奇怪,我搜索的怎么是那样的(/www/api/MagickCore/magick-type_8h.html),不过即使换成8位,结果仍然很大不同
不是指这段吧...
引用:
// 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;
我找不到其它先混合出result再与dest进行blending的地方...

IM可能还有其它处理
只用CompositeLinearDodge做不到效果...
作者: haibara    时间: 2010-04-08 20:53

引用:
原帖由 sfsuvival 于 2010-04-08 19:23 发表


不是指这段吧...

我找不到其它先混合出result再与dest进行blending的地方...

IM可能还有其它处理
只用CompositeLinearDodge做不到效果...
case SUBTRACT:
                    return new Blender() {
                        @Override
                        public void blend(int[] src, int[] dst, int[] result) {
                            result[0] = Math.max(0, src[0] + dst[0] - 256);
                            result[1] = Math.max(0, src[1] + dst[1] - 256);
                            result[2] = Math.max(0, src[2] + dst[2] - 256);
                            result[3] = Math.min(255, src[3] + dst[3] - (src[3] * dst[3]) / 255);
                        }
                    };

这部是是linearburn

                    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;

这部是alpha blending


不过,其实不要紧,我搞定了


public int lineardodge() {
                Ra = RoundToUnity(Sa + Da);
                return (int) (Ra * 255);
        }

        public int lineardodge(int src, int dest) {
                Sc = src / 255D;
                Dc = dest / 255D;
                Sca = Sa * Sc;
                Dca = Da * Dc;
                return (int) (RoundToUnity(Sca + Dca) / Ra * 255);
        }

        public int linearburn() {
                Ra = Sa + Da - Sa * Da;
                return (int) (Ra * 255);
        }

        public int linearburn(int src, int dest) {
                Sc = src / 255D;
                Dc = dest / 255D;
                Sca = Sa * Sc;
                Dca = Da * Dc;
                return (int) (RoundToUnity(Sca + Dca - Sa * Da) / Ra * 255);
        }

目测与PS一样了,linearburn把f=Sc+Dc-1代入SVG那个公式,并设x,y,z=1(我猜的)
lineardodge其实就是plus,只不过原来没做区间验证,所以有问题,不过我看不懂公式怎么计算出Sa + Da的?

[ 本帖最后由 haibara 于 2010-04-08 21:15 编辑 ]
作者: haibara    时间: 2010-04-09 14:06

sfsuvival, 我想问你的PSD是怎么做

如何正确解析TXT中的合成关系?有什么公式吗
作者: sfsuvival    时间: 2010-04-09 23:51

引用:
原帖由 haibara 于 2010-04-08 20:53 发表
case SUBTRACT:
                    return new Blender() {
                        @Override
                        public void blend(int[] src, int[] dst, int[] result) {
                            result[0] = Math.max(0, src[0] + dst[0] - 256);
                            result[1] = Math.max(0, src[1] + dst[1] - 256);
                            result[2] = Math.max(0, src[2] + dst[2] - 256);
                            result[3] = Math.min(255, src[3] + dst[3] - (src[3] * dst[3]) / 255);
                        }
                    };

这部是是linearburn

                    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;

这部是alpha blending
我是看不懂你为何做linearburn之后又做alpha blending...
BlendComposite那个alpha你也说是自定义的图层alpha
只做linearburn就可以了...
不过既然你搞定了,也不深究下去了
引用:
不过我看不懂公式怎么计算出Sa + Da的?
我也不明白SVG的plus
f(Sc,Dc) = Sc + Dc
X        = 1
Y        = 1
Z        = 1

Da'  = X.Sa.Da  + Y.Sa.(1-Da)   + Z.Da.(1-Sa)
按理是
Da'  = Sa.Da  + Sa.(1-Da)   + Da.(1-Sa)
     = Sa + Da - Sa.Da
真的不知道如何会变成这样…
Da'  = Sa.Da + Da.Sa + Sa.(1 - Da) + Da.(1 - Sa)
     = Sa + Da
引用:
原帖由 haibara 于 2010-04-09 14:06 发表
sfsuvival, 我想问你的PSD是怎么做

如何正确解析TXT中的合成关系?有什么公式吗
我是写Photoshop的脚本 (Script) 制作psd的
我只作過天神乱漫和メルクリア的psd
也只研究过这两个的txt文件

txt有两种
一种是描述图层的 (*.txt,不包括*_info.txt)
另一种是如何使用图层组成表情的 (*_info.txt)

描述图层的txt
引用:
#layer_type        name        left        top        width        height        type        opacity        visible        layer_id        group_layer_id       
layer_type是该图层是普通图层(ArtLayer) 还是图层文件夹(LayerSet/Group)
0是普通图层,2是图层文件夹
type见本帖1L
layer_id是分割后的图的id
group_layer_id是该图层所在的图层文件夹的id

天神乱漫的比较简单
type只有13和16
而且没有group_layer_id
メルクリア的很麻煩
我看過的type有13,14,16,21
而且有group_layer_id
图层名称混乱
还有些txt写是type=left=top=width=height=0的垃圾图层
(对应的是不透明全白32x32的32位图)


描述如何使用图层组成表情的txt
列大概有三种
1. dress为首的列,描述如何组成服装/身体
引用:
dress        01        base        ダミー
就是ダミー,沒用的…

天神乱漫
引用:
dress        パジャマ        diff        1        パジャマポーズA
dress        パジャマ        diff        2        パジャマポーズA(腕差分)
dress        制服春エプロン        diff        1        エプロン制服春ポーズA
dress        制服春エプロン        diff        2        エプロン制服春ポーズA(腕差分)
メルクリア
引用:
dress        01        diff        a        素体/01a
dress        01        diff        b        素体/01b
dress        01        diff        c        上乗せ/c指_通常
dress        01        diff        c        素体/01c
dress        01        diff        TA        素体/01TA
第二栏+第四栏是该组合的名称
第五栏是图层位置(素体/01a->”素体”图层文件夹下的”01a”图层)

虽说是组合
但不一定将其合并就了事
如上述メルクリア的
dress        01        diff        c        上乗せ/c指_通常
dress        01        diff        c        素体/01c
这个要”素体/01c” +face+”上乗せ/c指_通常” 依次迭上去
因为face会盖过手指
所以要用”上乗せ/c指_通常”盖上去

2. face为首的列,描述如何组成表情
天神乱漫
引用:
face        01        base        通常1
face        02        base        笑顔1
face        03        base        真剣
メルクリア
引用:
face        face01        base        表情/眉/01_02_03_04_14_22
face        face01        base        表情/目/01_02_06_13_21
face        face01        base        表情/口/01
face        face01        base        表情/頬hi/01_02_06_07_08_11_12_13_14_15_16_17_18_21
第二栏是该组合的名称
第四栏是图层位置

3. rename为首的列,用来重命名以上组合
メルクリア
引用:
rename        dress        制服1        01
rename        diff        腕上げ        a
rename        face        通常        face01
第二栏是组合类型(diff是dress列的diff)
将第四栏的名称重命名为第三栏
01->制服1
a->腕上げ
face01->通常

合成基本就是将face的组合迭在dress的组合上
例外就是上面提到的”素体/01c” +face+”上乗せ/c指_通常”

完...

[ 本帖最后由 sfsuvival 于 2010-04-19 20:49 编辑 ]
作者: haibara    时间: 2010-04-15 16:38

kiririi2TXT更新完成

https://yukict.com/bbs/viewthrea ... p;page=11#pid614485
作者: sfsuvival    时间: 2010-04-19 20:48

补充33L的内容,之前忘了说
1. 我看过有些メルクリア描述图层的txt的opacity不是255,是230的
所以opacity也不能忽视
整个txt看来也只有visible栏可以不理…
2. 33L写的 素体/01a->”素体”图层文件夹下的”01a”图层
“01a” 不一定是图层,可以是图层文件夹
素体/01a可以是指”素体”图层文件夹下的”01a”图层文件夹下的所有图层
3.
引用:
face        face01        base        表情/眉/01_02_03_04_14_22
face        face01        base        表情/目/01_02_06_13_21
face        face01        base        表情/口/01
face        face01        base        表情/頬hi/01_02_06_07_08_11_12_13_14_15_16_17_18_21
在组合内出现的先后是图层的次序
“表情/頬hi/01_02_06_07_08_11_12_13_14_15_16_17_18_21” 是底
依次迭上去是” 表情/口/01”
“表情/目/01_02_06_13_21”
最上的是” 表情/眉/01_02_03_04_14_22”

试了一下kirikiri2TXT
kirikiri2TXT没有输出txt记录的整张图的大小
你是交给DirectMuxer根据要合成的图决定合成图的大小?

现在kirikiri2TXT是将分割图根据txt的图层名称,再加上坐标和合成方式重命名吧?
如果*_info.txt没有rename命令
图的名称就只用*.txt内的图层名称
否则根据*_info.txt的rename命名?

kirikiri2TXT根据*_info.txt的rename重命名分割图有问题
rename是用来重命名一组图
不是针对一张图的
而每张图也可以属于多组合内
引用:
face        face01        base        表情/眉/01
face        xface01        base        表情/眉/01
"表情/眉/01"同时出现在face01和xface01
kirikiri2TXT将"表情/眉/01"命名为xface01在rename对应的名称
没有了face01的
解决方法可以是将属于多个组合的图复制多张再命名


用了メルクリア和天神乱漫的txt做测试

メルクリア
引用:

2010/04/19 3:17:21 kirikiri2TXT txt2bat
Warning: matched not definition 表情/その他/06 of Z:\TEMP\k\bst_02日未子_正面_1_7291.png
你应该是没有忽略以#开首的行吧?
所以有这个警告

天神乱漫
引用:
2010/04/19 3:17:15 kirikiri2TXT txt2bat
致命的: matched unknown layer id 498 of Z:\TEMP\a\葵_ポーズa_1_498.png

2010/04/19 3:17:15 kirikiri2TXT txt2bat
致命的: matched unknown layer id 514 of Z:\TEMP\a\葵_ポーズa_1_514.png

2010/04/19 3:17:15 kirikiri2TXT txt2bat
致命的: matched unknown layer id 421 of Z:\TEMP\a\葵_ポーズa_1_421.png
这三张是txt没有记录的图
你是读整个文件夹的所有分割图然后再在对应的txt找图层属性?

[ 本帖最后由 sfsuvival 于 2010-04-20 11:15 编辑 ]
作者: haibara    时间: 2010-05-20 23:25

opacity:指的是当前图层的opacity吧
作者: sfsuvival    时间: 2010-05-21 00:22

是的
opacity栏的数值指的是该图层的opacity
我说opacity是230的那组立绘
http://u.115.com/file/t12d795f1f
作者: haibara    时间: 2010-05-21 00:30

引用:
原帖由 sfsuvival 于 2010-05-21 00:22 发表
是的
opacity栏的数值指的是该图层的opacity
我说opacity是230的那组立绘
http://u.115.com/file/t12d795f1f
那比分计算alpha

按照SVG里应该是这样吧

Sa = (double) alpha / opacity;
Da = (double) beta / opacity;

原来是
Sa = (double) alpha / 255;
Sa = (double) beta / 255;
作者: sfsuvival    时间: 2010-05-21 22:50

应该是乘吧
如果opacity是[0,1] 的话
Sa = (double) alpha * opacity;
如果opacity是[0,255] 的话
Sa = (double) alpha / 255 * opacity;
作者: haibara    时间: 2010-05-22 01:05

引用:
原帖由 sfsuvival 于 2010-05-21 22:50 发表
应该是乘吧
如果opacity是[0,1] 的话
Sa = (double) alpha * opacity;
如果opacity是[0,255] 的话
Sa = (double) alpha / 255 * opacity;
SVG里Sa, Da肯定是[0,1], opacity按照txt来看是[0,255]
作者: haibara    时间: 2010-05-22 01:06

引用:
原帖由 sfsuvival 于 2010-05-21 22:50 发表
应该是乘吧
如果opacity是[0,1] 的话
Sa = (double) alpha * opacity;
如果opacity是[0,255] 的话
Sa = (double) alpha / 255 * opacity;
SVG里Sa, Da肯定是[0,1], opacity按照txt来看是[0,255]

opacity改变的是alpha换算到[0,1]的区域,应该吧
作者: haibara    时间: 2010-08-23 16:01

顶一下

sf,我问下,opacity是对当前图层而言,而非结果?
作者: sfsuvival    时间: 2010-08-25 07:51

opacity是对当前图层而言
不是结果
结果是由最底的图层开始累积得来的
如果opacity是指结果
那只要将一图层的opacity设0
在该图层下的所有图层都废了
作者: haibara    时间: 2010-08-25 08:52

看样子你看不到我给你QQ留言,是WEB QQ的关系

1,经过测试,你的importlayer只允许一个基本图,希望改一下
2,我准备重写kirikir2txt,但是有点忘记了,你什么有空,QQ上讨论下
作者: haibara    时间: 2010-08-28 13:49

http://www.box.net/shared/pp6pt445rj

sfsuvival测试下,与你写的脚本数量是否一样
作者: sfsuvival    时间: 2010-08-28 20:44

试了一下
和我的一样
不过如果info.txt有这样的bug
复制内容到剪贴板
代码:
dress        00        diff        a        素体/00a
dress        00        diff        b        素体/00b
dress        00        diff        RO        素体/00RO
dress        00        diff        RR        素体/00RR
dress        00        diff        TA        素体/00TA

rename        dress        制服2        01
rename        dress        制服1        02
rename        dress        制服1ケープなし        03
rename        dress        制服1破け        04
rename        dress        裸        00

rename        diff        詠唱        a
rename        diff        ロッド無        b
rename        diff        ロッド1        RO
rename        diff        ロッド2        RR
rename        diff        タクト        TA
b错了
应该是b
现在kirikiri2txt因为不能配对?b所以没有复制”素体/00b”
info.txt也有颇多bug的...




欢迎光临 YUKI 飛雪之城 (https://yukict.com/bbs/) Powered by Discuz! 6.0.0