【急求解】C# PNG图片重叠透明问题

我想做个C#的小游戏,两个PNG图片分别放在两个pictureBox里,但是两个图片重叠时,上层图片对下层是不透明的,只是对背景透明。在网上找了好久也没找到解决方法。(本... 我想做个C#的小游戏,两个PNG图片分别放在两个pictureBox里,但是两个图片重叠时,上层图片对下层是不透明的,只是对背景透明。在网上找了好久也没找到解决方法。
(本人刚学C#,烦请高手详细指导)谢谢
展开
 我来答
冰麟轻武
2010-07-25 · TA获得超过603个赞
知道小有建树答主
回答量:360
采纳率:0%
帮助的人:288万
展开全部
/// <summary>
/// 根据图片计算GraphicsPath路径
/// </summary>
/// <param name="img">gif或者png图片</param>
/// <returns>图片不透明区域路径</returns>
public unsafe static GraphicsPath subGraphicsPath(Image img)
{
if (img == null) return null;

// 建立GraphicsPath, 给我们的位图路径计算使用
GraphicsPath g = new GraphicsPath( FillMode.Alternate);

Bitmap bitmap = new Bitmap(img);

int width = bitmap.Width;
int height = bitmap.Height;
BitmapData bmData = bitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite,PixelFormat.Format24bppRgb);
byte* p = (byte*)bmData.Scan0;
int offset = bmData.Stride - width * 3;
int p0, p1, p2; // 记录左上角0,0座标的颜色值
p0 = p[0];
p1 = p[1];
p2 = p[2];

int start = -1;
// 行座标 ( Y col )
for (int Y = 0; Y < height; Y++)
{
// 列座标 ( X row )
for (int X = 0; X < width; X++)
{
if (start == -1 && (p[0] != p0 || p[1] != p1 || p[2] != p2)) //如果 之前的点没有不透明 且 不透明
{
start = X; //记录这个点
}
else if (start > -1 && (p[0] == p0 && p[1] == p1 && p[2] == p2)) //如果 之前的点是不透明 且 透明
{
g.AddRectangle(new Rectangle(start, Y, X - start, 1)); //添加之前的矩形到
start = -1;
}

if (X == width - 1 && start > -1) //如果 之前的点是不透明 且 是最后一个点
{
g.AddRectangle(new Rectangle(start, Y, X - start + 1, 1)); //添加之前的矩形到
start = -1;
}
//if (p[0] != p0 || p[1] != p1 || p[2] != p2)
// g.AddRectangle(new Rectangle(X, Y, 1, 1));
p += 3; //下一个内存地址
}
p += offset;
}
bitmap.UnlockBits(bmData);
bitmap.Dispose();
// 返回计算出来的不透明图片路径
return g;
}

上面的方法

下面的调用,假如你的控件是pictureBox1

GraphicsPath g = subGraphicsPath(pictureBox1.Image);
if (g == null) return;
pictureBox1.Region = new Region(g);

PS,用这个代码的时候需要选择项目属性->生成->勾选"允许不安全代码"
不懂再HI我
jiangfandd
2010-07-22 · TA获得超过202个赞
知道小有建树答主
回答量:252
采纳率:0%
帮助的人:179万
展开全部
用GDI+重写
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
程炫宋修平
2019-12-24 · TA获得超过4535个赞
知道大有可为答主
回答量:3050
采纳率:27%
帮助的人:193万
展开全部
///
<summary>
///
根据图片计算GraphicsPath路径
///
</summary>
///
<param
name="img">gif或者png图片</param>
///
<returns>图片不透明区域路径</returns>
public
unsafe
static
GraphicsPath
subGraphicsPath(Image
img)
{
if
(img
==
null)
return
null;
//
建立GraphicsPath,
给我们的位图路径计算使用
GraphicsPath
g
=
new
GraphicsPath(
FillMode.Alternate);
Bitmap
bitmap
=
new
Bitmap(img);
int
width
=
bitmap.Width;
int
height
=
bitmap.Height;
BitmapData
bmData
=
bitmap.LockBits(new
Rectangle(0,
0,
width,
height),
ImageLockMode.ReadWrite,PixelFormat.Format24bppRgb);
byte*
p
=
(byte*)bmData.Scan0;
int
offset
=
bmData.Stride
-
width
*
3;
int
p0,
p1,
p2;
//
记录左上角0,0座标的颜色值
p0
=
p[0];
p1
=
p[1];
p2
=
p[2];
int
start
=
-1;
//
行座标
(
Y
col
)
for
(int
Y
=
0;
Y
<
height;
Y++)
{
//
列座标
(
X
row
)
for
(int
X
=
0;
X
<
width;
X++)
{
if
(start
==
-1
&&
(p[0]
!=
p0
||
p[1]
!=
p1
||
p[2]
!=
p2))
//如果
之前的点没有不透明

不透明
{
start
=
X;
//记录这个点
}
else
if
(start
>
-1
&&
(p[0]
==
p0
&&
p[1]
==
p1
&&
p[2]
==
p2))
//如果
之前的点是不透明

透明
{
g.AddRectangle(new
Rectangle(start,
Y,
X
-
start,
1));
//添加之前的矩形到
start
=
-1;
}
if
(X
==
width
-
1
&&
start
>
-1)
//如果
之前的点是不透明

是最后一个点
{
g.AddRectangle(new
Rectangle(start,
Y,
X
-
start
+
1,
1));
//添加之前的矩形到
start
=
-1;
}
//if
(p[0]
!=
p0
||
p[1]
!=
p1
||
p[2]
!=
p2)
//
g.AddRectangle(new
Rectangle(X,
Y,
1,
1));
p
+=
3;
//下一个内存地址
}
p
+=
offset;
}
bitmap.UnlockBits(bmData);
bitmap.Dispose();
//
返回计算出来的不透明图片路径
return
g;
}
上面的方法
下面的调用,假如你的控件是pictureBox1
GraphicsPath
g
=
subGraphicsPath(pictureBox1.Image);
if
(g
==
null)
return;
pictureBox1.Region
=
new
Region(g);
PS,用这个代码的时候需要选择项目属性->生成->勾选"允许不安全代码"
不懂再HI我
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 更多回答(1)
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式