载入中
自定义HTML载入中... loading
日历
<<  <  2008 - 5  >  >>
Su Mo Tu We Th Fr Sa
        1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
载入中
边栏内容载入中... loading
置顶文章
请注意:本站软件下载方法 [3/12/2008 3:20:21 PM]
电脑初学者天地 [3/24/2008 4:22:08 AM]
C/C++初学者天地 [3/24/2008 5:10:51 PM]
小程序&休闲小游戏下载 [3/15/2008 6:07:29 PM]
D3D编程基础 [4/16/2008 2:08:06 PM]
C/C++编程工具下载 [3/12/2008 3:10:46 PM]
编程初学者天地 [3/10/2008 10:42:15 AM]
游戏编程大杂烩 [2/8/2008 10:52:12 AM]
杂文&历史 [4/17/2008 11:58:02 AM]
社会万象 [3/25/2008 1:45:02 AM]
Windows编程基础(C) [3/12/2008 7:31:05 PM]
减肥宝典 [3/9/2008 6:38:52 PM]
男人&女人 [2/13/2008 11:41:52 AM]
健康话题集:两性健康 [3/18/2008 5:01:32 PM]
健康话题 [3/9/2008 6:47:58 PM]
每日笑话 [3/9/2008 7:29:20 AM]
久坐不动容易得哪些病 [转贴 2008-05-10 07:16:24]  
近代研究表明,久坐不动容易诱发多种疾病,尤其是在办公室里面的白领人士。那么久坐不动容易得哪些病呢?

    久坐损心
    久坐不动血液循环减缓,日久则会使心脏机能衰退,引起心肌萎缩。尤其是患有动脉硬化等症的中老年人,久坐血液循环迟缓最容易诱发心肌梗塞和脑血栓形成。

    久坐伤肉
    祖国医学早就认识到“久坐伤肉”。久坐不动,气血不畅,缺少运动会使肌肉松弛,弹性降低,出现下肢浮肿,倦怠乏力,重则会使肌肉僵硬,感到疼痛麻木,引发肌肉萎缩。

    损筋伤骨
    久坐颈肩腰背持续保持固定姿势,椎间盘和棘间韧带长时间处于一种紧张僵持状态,就会导致颈肩腰背僵硬酸胀疼痛,或俯仰转身困难。特别是坐姿不当(如脊柱持续向前弯曲),还易引发驼背和骨质增生。
    久坐还会使骨盆和骶骼关节长时间负重,影响腹部和下肢血液循环,从而诱发便秘、痔疮,出现下肢麻木,引发下肢静脉曲张等症。

    久坐伤胃
    久坐缺乏全身运动,会使胃肠蠕动减弱,消化液分泌减少,日久就会出现食欲不振、消化不良以及脘腹饱胀等症状。

    伤神损脑
    久坐不动,血液循环减缓,则会导致大脑供血不足,伤神损脑,产生精神厌抑,表现为体倦神疲,精神萎靡,哈欠连天。若突然站起,还会出现头晕眼花等症状。久坐思虑耗血伤阴,老年人则会导致记忆力下降,注意力不集中。若阴虚心火内生,还会引发五心烦热,以及牙痛、咽干、耳鸣、便秘等症。

    保健专家建议:为了你的身心健康,不要久坐下棋,玩麻将,老年人更不可久坐家中闭门不出。凡工作需要久坐的人,不但要注意保持正确的坐姿,而且一次最好不要连续超过一小时,工作中每2小时中间最少应进行10分钟的工作操,或伸伸懒腰,或自由走动走动,以舒展四肢,缓解疲劳.

 

(字节数 : 1009)
Windows的位图alpha混合技术(Delphi代码) [转贴 2008-05-10 07:14:19]  

 

 

 

(北京大学地球与空间科学学院,100871

 

 

 

 

  要:本文介绍了在Windows环境下对位图的图像alpha混合技术,提供了alpha混合函数的实现方法,并对Windows API提供的alpha混合函数的使用进行了介绍。

 

 

 

 

关键词:Windows APIalpha混合,位图。

 

 

 

 

1 引言

 

 

在游戏、图像处理等程序中,经常会看到图像的淡入、淡出、两个或多个图像重叠显示、三维物体的光影效果等,这些特殊效果使用到的技术就是图像的混合技术,也叫图像的alpha混合。alpha混合是像素融合算法之一,就是按照“alpha”混合向量的值来混合源像素和目标像素,具体的说就是将源像素和目标像素加权相加的组合(混合)两个图像(源图像和目标图像)。源像素的权值通常被称为alpha值,目标像素的权值是(1&S722;alpha)1是最大的颜色值。alpha混合是按颜色通道定义,而不是按位定义的。

 

 

 

 

2 alpha混合的实现

 

 

我们定义alpha0时表示源像素完全透明,为1时表示完全不透明。假定我们用的是24位色或32位色位图,alpha混合的概念运算式为:

 

 

Dst.Red    = Src.Red   * alpha + (1-alpha) * Dst.Red  ;

 

 

Dst.Green  = Src.Green * alpha + (1-alpha) * Dst.Green;

 

 

Dst.Blue   = Src.Blue  * alpha + (1-alpha) * Dst.Blue ;

 

 

Dst.Alpha  = Src.Alpha * alpha + (1-alpha) * Dst.Alpha;

 

 

根据这个公式我们可以编制alpha混合图像的函数:

 

 

 

 

// 24位位图的alpha混合. 要求源位图和目标位图大小相等,且像素格式都为24

 

 

procedure AlphaBlend24(BitmapDest, BitmapSrc:TBitmap; Alpha:Byte);

 

 

var

 

 

  pDest, pSrc : PByteArray;

 

 

  X,Y :Integer;

 

 

  Beta:Integer;

 

 

begin

 

 

  Beta := 255 - Alpha;

 

 

  for Y := 0 to BitmapDest.Height - 1 do

 

 

  begin

 

 

    pDest := BitmapDest.ScanLine[Y];

 

 

    pSrc  := BitmapSrc.ScanLine[Y];

 

 

    for X := 0 to BitmapDest.Width - 1 do

 

 

    begin

 

 

      pDest[0]:= (pSrc[0] * Alpha + pDest[0] * Beta) div 255;

 

 

      pDest[1]:= (pSrc[1] * Alpha + pDest[1] * Beta) div 255;

 

 

      pDest[2]:= (pSrc[2] * Alpha + pDest[2] * Beta) div 255;

 

 

      Inc(Longword(pDest) ,3); // 指向下一个像素

 

 

      Inc(Longword(pSrc ) ,3);

 

 

    end;

 

 

  end;

 

 

end;

 

 

 

 

注意,代码中没有使用浮点数,只是将01alpha值用0255代替,这是Windows程序的通常做法。以上的代码只实现了24位位图的alpha混合,其它像素类型的alpha混合代码是相似的,所以这里不再给出。

 

 

 

 

3 、Windows APIAlphaBlend使用

 

 

由于图像的alpha混合技术使用非常广泛,所有图像处理引擎都支持这项操作,如OpenGLDirectX等。但是这些图像处理引擎都是用来处理复杂图像,而且使用比较复杂,如果我们的程序不是用来处理复杂图像而只需要简单的alpha混合功能,那么使用上述图形引擎就显得没有必要了。实际上在Windows 98Windows 2000中已经提供了实现alpha混合的API,就是AlphaBlend函数,这个函数是Windows 98Windows 2000GDI新加的功能AlphaBlend函数声明如下:

 

 

BOOL AlphaBlend(

 

 

HDC hdcDest, int nXOriginDest, int nYOriginDest, int nWidthDest,  int nHeightDest,

 

 

HDC hdcSrc, int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc,

 

 

BLENDFUNCTION blendFunction);

 

 

 

 

API函数中使用了一个结构

 

 

typedef struct _BLENDFUNCTION

 

 

{

 

 

    BYTE   BlendOp;

 

 

    BYTE   BlendFlags;

 

 

    BYTE   SourceConstantAlpha;

 

 

    BYTE   AlphaFormat;

 

 

} BLENDFUNCTION;

 

 

 

 

AlphaBlend函数的原型看起来和StretchBlt函数非常像,头5个参数指明了目标设备上下文和以逻辑坐标定义的矩形。同样,随后的5个参数指明了源设备上下文和以逻辑坐标定义的源表面的矩形。对源设备上下文也有限制,即源矩形必须在源设备上下文内,源设备上下文不能有剪切和旋转。注意,用到源设备上下文使得AlphaBlend函数不能直接使用DIB(即设备无关位图)。

 

 

最后一个参数blendFunction是一个BLENDFUNCTION结构。BLENDFUNCTION结构控制源和目标位图的混合方式,它的BlendOp字段指明了源混合操作,但只支持AC_SRC_OVER,即根据源alpha值把源图像叠加到目标图像上。OpenGLalpha混合还支持其他的方式,如常量颜色源。下一个字段BlendFalgs必须是0,也是为以后的应用保留的。最后一个字段AlphaFormat有两个选择:0表示常量alpha值,AC_SRC_ALPHA表示每个像素有各自的alpha通道。

 

 

如果AlphaFormat字段为0,源位图中的所有像素使用同样的常量alpha值,即SourceConstantAlpha字段中的值,该值实际上是0255,而不是01。这里0表示完全透明,255表示完全不透明。目标像素以255-SourceConstantAlpha值作为alpha值。

 

 

如果AlphaFormat字段的值是AC_SRC_ALPHA,源设备表面的每个像素必须有各自的alpha通道。即,必须是32-bpp的物理设备上下文,或是选中了32-bpp DDBDIB段的内存设备上下文。这些情况下,每个源像素有48位通道:红、绿、蓝和alpha。每个像素的alpha通道和SourceConstantAlpha字段一起用于把源和目标混合起来。实际用于计算的运算式如下:

 

 

Tmp.Red   = Src.Red   * SourceConstantAlpha / 255;

 

 

Tmp.Green = Src.Green * SourceConstantAlpha / 255;

 

 

Tmp.Blue  = Src.Blue  * SourceConstantAlpha / 255;

 

 

Tmp.Alpha = Src.Alpha * SourceConstantAlpha / 255;

 

 

Beta      = 255 – Tmp.alpha;

 

 

Dst.Red   = Tmp.Red   + Round((Beta * Dst.Red  )/255);

 

 

Dst.Green = Tmp.Green + Round((Beta * Dst.Green)/255);

 

 

Dst.Blue  = Tmp.Blue  + Round((Beta * Dst.Blue )/255);

 

 

Dst.Alpha = Tmp.Alpha + Round((Beta * Dst.Alpha)/255);

 

 

 

 

4 程序实例

 

 

下面演示AlphaBlend函数的使用,在Delphi 7中新建一工程,在Form1上放置三个Image控件和一个TrackBar控件,再加上一个Label控件和两个RadioButton控件。Image1中调入一个24位位图,Iamge2中调入另外一个24位位图,TrackBar1Min属性设为0,Max属性设为255,窗体如图1

 

 

 

 

程序的主要代码如下:

 

 

procedure TForm1.FormCreate(Sender: TObject);

 

 

begin

 

 

  Image3.Width := Image1.Width;

 

 

  Image3.Height := Image1.Height;

 

 

  TrackBar1Change(Self);

 

 

end;

 

 

 

 

procedure TForm1.TrackBar1Change(Sender: TObject);

 

 

begin

 

 

  Label1.Caption := IntToStr(TrackBar1.Position);

 

 

  if RadioButton1.Checked then

 

 

    AlphaDraw1

 

 

  else

 

 

    AlphaDraw2;

 

 

end;

 

 

 

 

// 使用AlphaBlend API进行alpha混合

 

 

procedure TForm1.AlphaDraw1;

 

 

var

 

 

  Bmp: TBitmap;

 

 

  BF: BLENDFUNCTION;

 

 

begin

 

 

  Bmp := TBitmap.Create;

 

 

  Bmp.Assign(Image1.Picture.Bitmap);

 

 

  BF.BlendOp := AC_SRC_OVER;

 

 

  BF.BlendFlags := 0;

 

 

  BF.SourceConstantAlpha := TrackBar1.Position;

 

 

  BF.AlphaFormat := 0;

 

 

 

 

  Windows.AlphaBlend(Bmp.Canvas.Handle, 0,0,Bmp.Width, Bmp.Height,

 

 

                     Image2.Picture.Bitmap.Canvas.Handle, 0,0,Bmp.Width, Bmp.Height,

 

 

                     BF);

 

 

  Image3.Canvas.Draw(0,0,Bmp);

 

 

  Bmp.Free;

 

 

end;

 

 

 

 

// 使用自编的AlphaBlend24函数进行alpha混合

 

 

procedure TForm1.AlphaDraw2;

 

 

var

 

 

  Bmp: TBitmap;

 

 

begin

 

 

  Bmp := TBitmap.Create;

 

 

  Bmp.Assign(Image1.Picture.Bitmap);

 

 

 

 

  AlphaBlend24(Bmp, Image2.Picture.Bitmap, TrackBar1.Position);

 

 

 

 

  Image3.Canvas.Draw(0,0,Bmp);

 

 

  Bmp.Free;

 

 

end;

 

 

 

 

运行时从左到右拖动TrackBar,最下面图像就由第一幅图逐渐变为第二幅图。本程序还演示了自编alpha混合函数的使用,效果与AlphaBlend相同。本示例程序在Delphi 7 Windows 2000中文版中运行通过。

 

 

 

 

参考文献:

 

 

1Windows 图形编程》(美)Feng Yuan   机械工业出版社,2002

 

 

2Windows 程序设计》(第5版)(美)Charles Petzold   北京大学出版社,1999

 

 

(字节数 : 45200)
上一页 | 1 | 2 | 3 | 4 | 5 | ... 197 | 下一页
和讯个人门户 v1.0 | 和讯部落 | 客服中心