大富翁论坛版权所有
来自:crazycock, 时间:2002-1-5 20:46:00, ID:837114
目的:将一张BMP图像(简称A)的中间某个区域进行羽化,然后和另外一张BMP图(简称B)(例如一个像框的图象 ),然后让两张图像合并,让B的中间(即非像框区域)为透明,显示出A在这个区域中间,另外,A在B的中间 显示出来的内容的边缘是经过羽化的,并非直接拼在一起。
有以下几个问题:
1。如何实现BMP图中,规则区域边缘的羽化问题(就是说其中一块圆形或矩形的区域),无论控件实现或者自 己写代码都可。
2。如何实现图像透明的效果。(我认为可以这样考虑,让B图需要透明的地方用某个颜色,然后建立一个BMP图 C,在C图上写内容,从B图某个点开始读,如果B图中的某个点不是那个预先设定的"透明颜色",那么就往C图 上填B的点,如果读到B图上某个点是"透明点",那么就写对应位置A图的点的内容,不知道这样考虑是否合适 ??)
3。如何实现两个图像内容的颜色累加,也就是说两张图的累加效果?是直接将他们的RGB值累加吗?或者求平 均值??
4。控件我找了很多,大富翁里有关的问题我也找了,不过好象没有能够完全解决我的问题的答案,希望大家讨 论一下。
来自:vine, 时间:2002-1-5 20:52:00, ID:837123
》如何通过算法设置出象photoshop里一幅图象在另一幅图象上如何透明地显示,
并且可以设置透明度,如50%的透明度。并不是单幅图象的透明性。
Tbitmap有关的属性:
1.TansparentColor: 透明色;
2.PixelFormat:指明每一象点颜色所占的二进位数;
pf16bit: 点2字节;
pf24bit: 3字节;
pf32bit: 4字节;
3.ScanLine[行号];每一行象素缓冲的首址,即数组
的首址,每一象点占连续字节;
有了上面的3个属性,就可以写出合成2幅图象的算法;
算法:
for 第0行 到 最后一行
for 第0列 TO 最后一列
begin
1.取第一幅一个象点c1;
2.取第二幅一个象点c2;
3.如果c1是透明色,c3:=c2;
如果c2是透明色,c3:=c1;
4.送c3
end
我有个效率不高(速度很慢),但效果绝对好的算法:
for 第0行 到 最后一行
for 第0列 TO 最后一列
begin
1.取第一幅一个像点c1的R色 c1R;
2.取第二幅一个像点c2的R色 c2R;
3.新像点的R色 cR := (c1R*K+c2R*(1-K));
4.取第一幅一个像点c1的G色 c1G;
5.取第二幅一个像点c2的G色 c2G;
6.新像点的G色 cG := (c1G*K+c2G*(1-K));
7.取第一幅一个像点c1的B色 c1B;
8.取第二幅一个像点c2的B色 c2B;
9.新像点的B色 cB := (c1B*K+c2B*(1-K));
10.新像点的RGB色 cRGB := RGB(cR,cG,cB);
end
其中 K 是2个图合并时,第一幅图的权重。改变这个 K 值可以得到一个渐变的效果。
可将下面代码转换为DELPHI代码就可:
CDC memDC;
CBitmap &cBitmap=m_bmpDraw;
CBitmap* pOldMemBmp = NULL;
COLORREF col,colMask;
CRect cRect;
int x, y;
CRgn wndRgn, rgnTemp;
GetWindowRect(&cRect);
CPoint ptOrg=cRect.TopLeft();
BITMAP bmInfo;
cBitmap.GetObject(sizeof(bmInfo),&bmInfo);
CRect rcNewWnd=CRect(ptOrg,CSize(bmInfo.bmWidth,bmInfo.bmHeight));
memDC.CreateCompatibleDC(pDC);
pOldMemBmp = memDC.SelectObject(&cBitmap);
colMask=memDC.GetPixel(0,0);
wndRgn.CreateRectRgn(0, 0, rcNewWnd.Width(), rcNewWnd.Height());
for(x=0; x<=rcNewWnd.Width(); x++)
{
for(y=0; y<=rcNewWnd.Height(); y++)
{
col = memDC.GetPixel(x, y);
if(col == colMask)
{
rgnTemp.CreateRectRgn(x, y, x+1, y+1);
wndRgn.CombineRgn(&wndRgn, &rgnTemp, RGN_XOR);
rgnTemp.DeleteObject();
}
}
}
if (pOldMemBmp) memDC.SelectObject(pOldMemBmp);
SetWindowRgn((HRGN)wndRgn, TRUE);
MoveWindow(rcNewWnd);
呵呵!看来这些人没明白你的意思呀!我曾经研究过这个问题,不过我是用VC做的,不知道用DELPHI怎么做, 不过我可以把算法告诉你:取得两幅为图在每一点的像素值,分离出R,G,B的值,生成位图相应像素的R,G, B由下面公式决定:R=kR1+(1-k)R2 G=kG1+(1-k)G2 B=kB1+(1-k)B2 k为透明度,范围是0%-100% , R1,R2,G1,G2,B1,B2为混合的两幅位图分离出来的R,G,B值,R,G,B为混合后的相应像素的R,G,B值。
APIer(APIer) (2001-1-2 17:01:00) 得0分
使用DDraw吧,这是一个简单的Alpha特效啊。
nononono的方法是可行的,但是使用了太多的乘法,还要用到浮点,在16位位图游戏编程中,大家通常使用这 样的方法来进行Alpha混合:
1先分色并移位
2进行混色:(混色深度为32,足够了)
DestColor= (RscColor-DestColor)*Alpha_Depth〉〉5+DestColor;(R.G.B分别计算)
3最后合色
nononono(null,null) (2001-1-7 12:39:00) 得0分
akuan,这样试试:
分离RGB3色用"位与"、"移位"运算的方法;
透明的比例按 32、16分级。
如:如果是按32级,
A图的权重 K = n/32,则B图的权重 = (32-n)/32,
可以得到这样的算法:
cR := (c1R*n+c2R*(32-n));
再对cR右移4位。
这样的算法要快很多。
来自:YB_unique, 时间:2002-1-6 10:44:00, ID:837724
My God!问题好多啊!^_^
1。羽化就是色彩的平滑淡化处理。要卷老兄贴算法给你吧!
2。透明效果就是布尔运算而已,别想得太复杂!
3。颜色累加看你追求的效果而言,非得取平均值也无可非议。说来说去就是Blend。
4。不知道你是如何搜索论坛资源的,我的记忆中 2 和 3 在论坛里都有答案!
来自:卷起千堆雪tyn, 时间:2002-1-6 19:20:00, ID:838678
归结起来就是一个Alpha混合的问题!
留下MAIL,我发给你一个完整的例程,自己去研究;可以满足你的要求。
来自:卷起千堆雪tyn, 时间:2002-1-6 21:54:00, ID:838964
通常的位图都是包括R、G、B三个通道;但在某些位图里,还附有一个Alpha通道。那么这个通道是用来做什么的呢?这个通道一般是保存位图颜色位数深度、透明度等等信息的,只要你修改这个通道的信息,就会改变整个位图的性质,比如实现透明、遮罩、轨迹、融合、渐层覆盖等效果.
来自:coolbaby, 时间:2002-1-7 21:03:00, ID:841332
卷起千堆雪tyn兄 :
colortorgb以后,是不是 不是所有的图都有alpha通道的信息?
来自:卷起千堆雪tyn, 时间:2002-1-7 21:06:00, ID:841343
colortorgb仅仅是将TColor转变为LongInt,没有包含什么Alpha通道的信息;
Alpha通道是自己余外定义的。
可以看看TColor的定义。