调用 API 中的 BitBlt 函数。
函数功能:该函数对指定的源设备环境区域中的像素进行位块(bit_block)转换,以传送到目标设备环境。
函数原型:BOOL BitBlt(HDC hdcDest,int nXDest,int nYDest,int nWidth,int nHeight,HDC hdcSrc,int nXSrc,int nYSrc,DWORD dwRop);
参数:
hdcDest:指向目标设备环境的句柄。
nXDest:指定目标矩形区域左上角的X轴逻辑坐标。
nYDest:指定目标矩形区域左上角的Y轴逻辑坐标。
nWidth:指定源和目标矩形区域的逻辑宽度。
nHeight:指定源和目标矩形区域的逻辑高度。
hdcSrc:指向源设备环境的句柄。
nXSrc:指定源矩形区域左上角的X轴逻辑坐标。
nYSrc:指定源矩形区域左上角的Y轴逻辑坐标。
dwRop:指定光栅操作代码。这些代码将定义源矩形区域的颜色数据,如何与目标矩形区域的颜色数据组合以完成最后的颜色。
- using System;
- using System.Collections.Generic;
- using System.Text;
- using System.Runtime.InteropServices;
- public class Win32Support
- {
- /// <summary>
- /// Enumeration to be used for those Win32 function
- /// that return BOOL
- /// </summary>
- public enum Bool
- {
- False = 0,
- True
- };
- /// <summary>
- /// Enumeration for the raster operations used in BitBlt.
- /// In C++ these are actually #define. But to use these
- /// constants with C#, a new enumeration type is defined.
- /// </summary>
- public enum TernaryRasterOperations
- {
- //SRCCOPY:将源矩形区域直接拷贝到目标矩形区域
- SRCCOPY = 0x00CC0020, // dest = source
- //SRCPAINT:通过使用布尔型的OR(或)操作符将源和目标矩形区域的颜色合并
- SRCPAINT = 0x00EE0086, // dest = source OR dest
- //SRCAND:通过使用AND(与)操作符来将源和目标矩形区域内的颜色合并
- SRCAND = 0x008800C6, // dest = source AND dest
- //SRCINVERT:通过使用布尔型的XOR(异或)操作符将源和目标矩形区域的颜色合并
- SRCINVERT = 0x00660046, // dest = source XOR dest
- //SRCERASE:通过使用AND(与)操作符将目标矩形区域颜色取反后与源矩形区域的颜色值合并
- SRCERASE = 0x00440328, // dest = source AND (NOT dest)
- //NOTSRCCOPY:将源矩形区域颜色取反,于拷贝到目标矩形区域。
- NOTSRCCOPY = 0x00330008, // dest = (NOT source)将位图做NOT运算
- //NOTSRCERASE:使用布尔类型的OR(或)操作符组合源和目标矩形区域的颜色值,然后将合成的颜色取反
- NOTSRCERASE = 0x001100A6, // dest = (NOT src) AND (NOT dest)先将位图与目的DC做OR运算,再将其做NOT运算
- //MERGECOPY:表示使用布尔型的AND(与)操作符将源矩形区域的颜色与特定模式组合一起。
- MERGECOPY = 0x00C000CA, // dest = (source AND pattern)将选择的画刷与位图做AND运算
- //MERGEPAINT:通过使用布尔型的OR(或)操作符将反向的源矩形区域的颜色与目标矩形区域的颜色合并。
- MERGEPAINT = 0x00BB0226, // dest = (NOT source) OR dest 先将位图做NOT运算,再与目的DC做OR运算
- //PATCOPY:将特定的模式拷贝到目标位图上。
- PATCOPY = 0x00F00021, // dest = pattern 将选择的画刷贴到目的DC
- //PATPAINT:通过使用布尔OR(或)操作符将源矩形区域取反后的颜色值与特定模式的颜色合并。然后使用OR(或)操作符将该操作的结果与目标矩形区域内的颜色合并。
- PATPAINT = 0x00FB0A09, // dest = DPSnoo
- //PATINVERT:通过使用XOR(异或)操作符将源和目标矩形区域内的颜色合并
- PATINVERT = 0x005A0049, // dest = pattern XOR dest 将目的DC与选择的画刷做XOR运算
- //DSTINVERT:表示使目标矩形区域颜色取反。
- DSTINVERT = 0x00550009, // dest = (NOT dest) 将目的DC做NOT运算
- //BLACKNESS表示使用与物理调色板的索引0相关的色彩来填充目标矩形区域,(对缺省的物理调色板而言,该颜色为黑色)。
- BLACKNESS = 0x00000042, // dest = BLACK 将位图转换为黑色
- //WHITENESS:使用与物理调色板中索引1有关的颜色填充目标矩形区域。(对于缺省物理调色板来说,这个颜色就是白色)
- WHITENESS = 0x00FF0062, // dest = WHITE
- };
- /// <summary>
- /// BitBlt
- /// </summary>
- /// <param name="hObject">背景图片句柄。</param>
- /// <param name="nXDest">从背景图片X坐标处画。</param>
- /// <param name="nYDest">从背景图片Y坐标处画。</param>
- /// <param name="nWidth">在背景图片上画多宽。</param>
- /// <param name="nHeight">在背景图片上画多高。</param>
- /// <param name="hObjSource">要画上去的图片句柄。</param>
- /// <param name="nXSrc">从要画上去的图片的X坐标处画。</param>
- /// <param name="nYSrc">从要画上去的图片的Y坐标处画。</param>
- /// <param name="dwRop">运算方式。</param>
- /// <returns>如果函数成功,那么返回值非零;如果函数失败,则返回值为零。Windows NT:若想获取更多错误信息,请调用GetLastError函数。</returns>
- [DllImport("coredll.dll", EntryPoint = "BitBlt")]//PocektPc 的 API 封装在 coredll.dll 中 EntryPoint 为调用coredll.dll中的哪个方法,extern 表示此方法在外部实现,实现 API 中的方法必须用 Static 修饰
- public static extern Bool BitBlt(
- IntPtr hObject,
- int nXDest, int nYDest,
- int nWidth, int nHeight,
- IntPtr hObjSource, int nXSrc, int nYSrc,
- TernaryRasterOperations dwRop);
- }
上面已将图片合成的核心代码写好了。
我们需要准备好所需的图片:
back.jpg
carton.jpg
通过反射获取到图片资源carton.jpg:
Image source = new Bitmap(System.Reflection.Assembly.GetExecutingAssembly()
.GetManifestResourceStream("LouKong.carton.jpg"));
定义全局变量用来控制获取高度
int image = 0;
实现窗体重绘事件 Paint
- private void Form1_Paint(object sender, PaintEventArgs e)
- {
- using (Image back = new Bitmap(System.Reflection.Assembly.GetExecutingAssembly()
- .GetManifestResourceStream("LouKong.back.jpg")))
- {
- Graphics backGrp = Graphics.FromImage(back);
- Graphics souceGrp = Graphics.FromImage(source);
- IntPtr bp = backGrp.GetHdc();
- IntPtr sp = souceGrp.GetHdc();
- int height = image * source.Height / 2;
- Win32Support.BitBlt(bp, 20, 20, source.Width / 2, source.Height / 2, sp, source.Width / 2, height, Win32Support.TernaryRasterOperations.SRCAND);
- Win32Support.BitBlt(bp, 20, 20, source.Width / 2, source.Height / 2, sp, 0, height, Win32Support.TernaryRasterOperations.SRCPAINT);
- backGrp.ReleaseHdc(bp);//释放句柄
- souceGrp.ReleaseHdc(sp);//释放句柄
- e.Graphics.DrawImage(back, 0, 0);
- }
- }
在Timer时间中:
- private void timer1_Tick(object sender, EventArgs e)
- {
- if (image == 0)
- image = 1;
- else
- image = 0;
- this.Refresh();
- }
在 Form_load事件中启动Timer
timer1.Enabled = true;