首页  编辑  

关于图像的一些讨论

Tags: /超级猛料/Picture.图形图像编程/图片处理/   Date Created:

大富翁论坛版权所有

来自: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的定义。