`
huobengle
  • 浏览: 854574 次
文章分类
社区版块
存档分类
最新评论

C#将图形快速处理成不规则区域

 
阅读更多
using System.Runtime.InteropServices;
[DllImport("gdi32.dll")]
public static extern IntPtr ExtCreateRegion(IntPtr lpXform, uint nCount,
ref byte lpRgnData);
public static int RGN_AND= 1;
public static int RGN_OR = 2;
public static int RGN_XOR= 3;
public static int RGN_DIFF= 4;
public static int RGN_COPY= 5;
public static int RGN_MIN = RGN_AND;
public static int RGN_MAX= RGN_COPY;
[DllImport("gdi32.dll")]
public static extern int CombineRgn(IntPtr hrgnDest, IntPtr hrgnSrc1, IntPtr hrgnSrc2,
int fnCombineMode);
[DllImport("gdi32.dll")]
public static extern bool DeleteObject(IntPtr hObject);
public Region ImageToRegion(Image AImage, Color ATransparent)
{
//转贴请注明出处ZswangY37(wjhu111#21cn.com) 时间2007-05-25
if (AImage == null) return null;
Bitmap vBitmap = new Bitmap(AImage);
BitmapData vBitmapData = vBitmap.LockBits(
new Rectangle(0, 0, vBitmap.Width, vBitmap.Height),
ImageLockMode.ReadOnly, PixelFormat.Format32bppRgb);
int vAddress = (int)vBitmapData.Scan0;
int vOffset = vBitmapData.Stride - vBitmap.Width * 4; // 每行多出的字节数
int h = vBitmap.Height, w = vBitmap.Width;
int vTransparent = ColorTranslator.ToWin32(ATransparent); // 透明色
int vAllocRect = (0x1000 - sizeof(uint) * 8) / sizeof(int); // 预分配的矩形数
if (h * w < vAllocRect) vAllocRect = h * w;
Byte[] vBuffer = new byte[sizeof(uint) * 8 + sizeof(int) * 4 * vAllocRect];
//头信息dwSize/iType/nCount/nRegSize
uint vCount = 0;
vBuffer[0] = sizeof(uint) * 8; //dwSize//头信息大小
vBuffer[4] = 1; //iType//int RDH_RECTANGLES = 1;//数据类型
IntPtr vResult = IntPtr.Zero;
uint vPointer = sizeof(uint) * 8;
bool vWriteRect = false;
bool vWriteAlways = false;
for (int y = 0; y < h; y++)
{
int vBlockStart = 0;
bool vLastMaskBit = false;
for (int x = 0; x < w; x++)
{
int i = Marshal.ReadInt32((IntPtr)vAddress) & 0x00FFFFFF;
if (vTransparent == i) // 透明色
{
if (vLastMaskBit)
vWriteRect = true;
}
else
{
if (!vLastMaskBit)
{
vBlockStart = x;
vLastMaskBit = true;
}
}
if (x == w - 1)
{
if (y == h - 1)
{
vWriteRect = true;
vWriteAlways = true;
}
else if (vLastMaskBit)
{
vWriteRect = true;
}
x++;
}
if (vWriteRect)
{
if (vLastMaskBit)
{
vCount++;
WriteRect(vBuffer, ref vPointer,
new Rectangle(vBlockStart, y, x - vBlockStart, 1));
}
if (vCount == vAllocRect || vWriteAlways)
{
vBuffer[8] = (byte)vCount;
vBuffer[9] = (byte)(vCount >> 8);
vBuffer[10] = (byte)(vCount >> 16);
vBuffer[11] = (byte)(vCount >> 24);
IntPtr hTemp = ExtCreateRegion(IntPtr.Zero,
sizeof(uint) * 8 + sizeof(int) * 4 * vCount,
ref vBuffer[0]);
if (vResult == IntPtr.Zero)
vResult = hTemp;
else
{
CombineRgn(vResult, vResult, hTemp, RGN_OR);
DeleteObject(hTemp);
}
vCount = 0;
vPointer = sizeof(uint) * 4;
vWriteAlways = false;
}
vWriteRect = false;
vLastMaskBit = false;
}
vAddress += 4;
}
vAddress += vOffset;
}
vBitmap.UnlockBits(vBitmapData);
return Region.FromHrgn(vResult);
}
private void WriteRect(byte[] ARGNData, ref uint ptr, Rectangle r)
{
ARGNData[ptr] = (byte)r.X;
ARGNData[ptr + 1] = (byte)(r.X >> 8);
ARGNData[ptr + 2] = (byte)(r.X >> 16);
ARGNData[ptr + 3] = (byte)(r.X >> 24);
ARGNData[ptr + 4] = (byte)r.Y;
ARGNData[ptr + 5] = (byte)(r.Y >> 8);
ARGNData[ptr + 6] = (byte)(r.Y >> 16);
ARGNData[ptr + 7] = (byte)(r.Y >> 24);
ARGNData[ptr + 8] = (byte)r.Right;
ARGNData[ptr + 9] = (byte)(r.Right >> 8);
ARGNData[ptr + 10] = (byte)(r.Right >> 16);
ARGNData[ptr + 11] = (byte)(r.Right >> 24);
ARGNData[ptr + 12] = (byte)r.Bottom;
ARGNData[ptr + 13] = (byte)(r.Bottom >> 8);
ARGNData[ptr + 14] = (byte)(r.Bottom >> 16);
ARGNData[ptr + 15] = (byte)(r.Bottom >> 24);
ptr += 16;
}
private void button1_Click(object sender, EventArgs e)
{
Region = ImageToRegion(pictureBox1.Image, Color.White);
}
分享到:
评论

相关推荐

    C#不规则封闭图形选点方案

    C#不规则封闭图形选点方案

    C#实现不规则图形分割成多个矩形组合可视化工具, 核心是一个找最大内切矩形的算法

    C#代码,不规则图形分割成多个矩形,可视化工具, 核心是一个找最大内切矩形的算法 牵涉到的知识点: 1. 图片的加载和像素解析,绘制到pictureBox上 2.控制pitctureBox缩放(ctrl+滚轮)和移动 3.动态生成bitmap,...

    根据图片 获得不规则图形

    项目中遇到一些不规则的图片作品需要合成,给一张不规则的png图片(比如圆形图片,中间是白色的圆形区域,外面是透明区域),需要将用白色区域裁剪用户图片并且要求效率不低于1s 解决方案 先声明我是转载的 我用过...

    图片不规则部分高亮显示编辑器

    在图片中使用句柄编辑不规则区域,在显示图片时,如果鼠标划过被编辑的区域,则该区域高亮显示。

    C#实训教程

    2.9 C#编程规则 46 2.10 内容总结 50 2.11 独立实践 50 3 对象和结构 52 3.1 类和结构 52 3.2 类和成员 53 3.3 构造函数 60 3.4 结构 65 3.5 部分类 68 3.6 内容总结 72 3.7 独立实践 72 4 继承 73 4.1 继承的类型 ...

    C#.net_经典编程例子400个

    165 实例113 波形图的绘制 166 4.2 图形转换 168 实例114 BMP转换成JPG格式 168 实例115 JPG转换成BMP格式 170 实例116 位图转化为WMF 171 实例117 Ico文件转化为位图 172 实例118...

Global site tag (gtag.js) - Google Analytics