C#将图形快速处理成不规则区域
来源:互联网 发布:isis 剿灭 知乎 编辑:程序博客网 时间:2024/05/17 04:07
C#将图形快速处理成不规则区域
来源:
http://blog.sina.com.cn/u/589d32f5010009nf
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.FromArgb(216, 233, 236));
}
- C#将图形快速处理成不规则区域
- C#将图形快速处理成不规则区域
- C#将图形快速处理成不规则区域
- Android 不规则图形点击区域判断
- c#图形区域剪切
- 饼图 + 不规则区域事件处理
- 点击图片中不规则图形提示选中不同区域
- Android不规则图形点击提示选中不同区域
- c#图形区域组合操作
- hitTest:方法练习 - 不规则区域点击事件处理
- 不规则区域窗口
- CombineRectRgn创建不规则区域
- OSPF不规则区域解决
- 不规则imageview区域点击
- 图像不规则区域拷贝
- iOS 画出不规则图形
- 不规则图形 尖角转圆角
- OpenCV截取图像的任意形状区域,规则的图形(圆、椭圆、矩形),不规则鼠标自己选择
- Ehlert Drive SnapShot Portable v1 43 17635 Incl Keymaker-CORE
- Ehlert Drive SnapShot Portable v1 43 17634 x64 Incl Keymaker-CORE
- 多线程编程 - GCD
- Ubuntu下C++基于eigen库SVD矩阵奇异值分解效率分析
- 线段树的一些题和对应的做法
- C#将图形快速处理成不规则区域
- refactor : switch-case
- vb.net中彩色图像数据的快速获取
- 一维图像数据数组处理应该注意的几个问题
- 几种经典的二值化方法及其vb.net实现
- hbase和虚拟机开发
- NYOJ 733 万圣节派对(abs函数的认识)
- 简单的量杯液位显示控件
- 快速比较两副图片是否相同