高手来试试,菜鸟不要来-------GDI画图遮罩问题

jhjhzr 2009-11-04 10:54:50
3张图,一张背景图(相框),一张原图(用户照片),一个遮罩辅助图(黑白图)
目的:黑白图,白色区域显示相框,黑色的部分显示用户照片,3张图都是不规则图形

现存问题:
假设3张图一样
相框和白色区域可以刚好匹配,但是用户的照片不会和黑色区域匹配,用网上找到的位图与或运算后,相框区域一样会出现用户的照片与或运算后的颜色。

代码如下:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Reflection;

namespace WindowsFormsApplication1
{
public partial class Form2 : Form
{
[DllImport("gdi32.dll")]
static public extern IntPtr CreateCompatibleDC(IntPtr hDC);
[DllImport("gdi32.dll", EntryPoint = "BitBlt")]
public static extern bool BitBlt(IntPtr hdcDest, int nXDest,
int nYDest, int nWidth, int nHeight, IntPtr hdcSrc,
int nXSrc, int nYSrc, int dwRop);
[DllImport("user32.dll", EntryPoint = "GetDC")]
public static extern IntPtr GetDC(IntPtr hWnd);
[DllImport("gdi32.dll")]
public static extern int SetROP2(int h, int op);
[DllImport("gdi32.dll")]
static public extern bool DeleteObject(IntPtr hObject);
[DllImport("gdi32.dll")]
static public extern IntPtr SelectObject(IntPtr hDC, IntPtr hObject);
[DllImport("gdi32.dll")]
static public extern IntPtr DeleteDC(IntPtr hDC);

const int SRCAND = 0x8800C6; // (DWORD) dest = source AND dest
const int SRCCOPY = 0xCC0020; // (DWORD) dest = source
const int SRCERASE = 0x440328; // (DWORD) dest = source AND (NOT dest )
const int SRCINVERT = 0x660046; // (DWORD) dest = source XOR dest
const int SRCPAINT = 0xEE0086; // (DWORD) dest = source OR dest
const int BLACKNESS = 0x42;
const int DSTINVERT = 0x550009;
const int MERGECOPY = 0xC000CA;
const int MERGEPAINT = 0xBB0226;
const int NOTSRCCOPY = 0x330008;
const int NOTSRCERASE = 0x1100A6;
const int PATCOPY = 0xF00021;
const int PATINVERT = 0x5A0049;
const int PATPAINT = 0xFB0A09;
const int WHITENESS = 0xFF0062;



public Form2()
{
InitializeComponent();
}

private void Form2_Load(object sender, EventArgs e)
{
//用户照片
Bitmap BmpForeground = new Bitmap("D:/fore.jpg");

//遮罩图(黑白图)
Bitmap BmpFilter = new Bitmap("D:/Bball_mask.png");

//相框
Bitmap BmpBackground = new Bitmap("D:/Bball_frame.png");


Image img = new Bitmap(540, 705);
Graphics g = Graphics.FromImage(img);
System.IntPtr hdc = g.GetHdc();

System.IntPtr hMemBackground = CreateCompatibleDC(hdc);
System.IntPtr hMemFilt = CreateCompatibleDC(hdc);
System.IntPtr hMemFore = CreateCompatibleDC(hdc);

System.IntPtr hBmpBackground = SelectObject(hMemBackground, BmpBackground.GetHbitmap());
System.IntPtr hBmpFilt = SelectObject(hMemFilt, BmpFilter.GetHbitmap());
System.IntPtr hBmpFore = SelectObject(hMemFore, BmpForeground.GetHbitmap());


BitBlt(hdc, 0, 0, BmpFilter.Width, BmpFilter.Height, hMemFilt, 0, 0, SRCCOPY);
BitBlt(hdc, 0, 0, BmpFilter.Width, BmpFilter.Height, hMemBackground, 0, 0, SRCAND);
BitBlt(hdc, 0, 0, BmpFilter.Width, BmpFilter.Height, hMemFore, 0, 0, SRCPAINT);

SelectObject(hMemBackground, hBmpBackground);
SelectObject(hMemFore, hBmpFore);
SelectObject(hMemFilt, hBmpFilt);
g.ReleaseHdc();
DeleteDC(hMemFore);
DeleteDC(hMemFilt);
DeleteDC(hMemBackground);
img.Save("D:/test2.png");
//pictureBox1.Image = img;
}
}
}


...全文
389 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
stevenkoh 2012-10-11
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 的回复:]
1、黑白图与相框进行“与”运算,得到相框和黑色的区域
2、复制反向黑白图(黑变白,白变黑),与用户照片进行“与”运算,得到除去相框部分的用户照片图
3、上面2个部分作“或”运算 [/Quote]

长知识了
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 jhjhzr 的回复:]
有没有其他思路,比如扫描图片,3个图片如果一起读,判断黑白图的象素值,根据值不同,画另外两个图中不同的象素。如果获取BitmapData,怎么判断一个象素的颜色?怎么同步读图画图?
[/Quote]

一个例子


Rectangle rect = new Rectangle(0, 0, bit.Width, bit.Height);
BitmapData dataIn = bit.LockBits(rect, ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
int* pBase = (int*)(dataIn.Scan0.ToPointer());
int* pIn = pBase;
for (int i = 0; i < rect.Height; ++i)
{
pIn = pBase;
for (int j = 0; j < rect.Width; ++j)
{
Console.Writeline(*pIn);
++pIn;
}
pBase += (dataIn.Stride >> 2);
}

bit.UnlockBits(dataIn);
jhjhzr 2009-11-04
  • 打赏
  • 举报
回复
有没有其他思路,比如扫描图片,3个图片如果一起读,判断黑白图的象素值,根据值不同,画另外两个图中不同的象素。如果获取BitmapData,怎么判断一个象素的颜色?怎么同步读图画图?
jhjhzr 2009-11-04
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 softlove03 的回复:]
一张背景图(相框),
一张原图(用户照片),
一个遮罩辅助图(黑白图)
3张图尺寸一样

提供另一个思路
1 将遮罩辅助图的黑色部分的颜色的alpha值设置为0,如果遮罩辅助图是PNG格式的带alpha的,可以忽略此操作。
2 (将遮罩辅助图的像素的alpha值对应赋值给相框。如果相框是PNG格式的带alpha的,可以忽略以上所有操作。
3 建立一个bitmap
4 在bitmap上绘制背景图
5 在bitmap上绘制相框


[/Quote]
怎么设置某一区域的alpha?这个区域也是不规则的。
你指的是扫描位图吗?

我现在的方法是
黑白图与相框进行“与”运算,得到相框和黑色的区域
然后再和用户照片"或"运算,黑色区域被用户照片替换,但是原来相框的区域也会出现相框和用户照片”或“运算后的结果,就是原来相框的区域的图象有问题,我只想保留相框的图象就行了。
  • 打赏
  • 举报
回复
一张背景图(相框),
一张原图(用户照片),
一个遮罩辅助图(黑白图)
3张图尺寸一样

提供另一个思路
1 将遮罩辅助图的黑色部分的颜色的alpha值设置为0,如果遮罩辅助图是PNG格式的带alpha的,可以忽略此操作。
2 (将遮罩辅助图的像素的alpha值对应赋值给相框。如果相框是PNG格式的带alpha的,可以忽略以上所有操作。
3 建立一个bitmap
4 在bitmap上绘制背景图
5 在bitmap上绘制相框

你妹的特盗不 2009-11-04
  • 打赏
  • 举报
回复
我知道,不过我是菜鸟
jhjhzr 2009-11-04
  • 打赏
  • 举报
回复
csdn没人啦!~~~
阿发伯 2009-11-04
  • 打赏
  • 举报
回复
透明白色的ARGB值是0x00ffffff,纯白色的ARGB值是0xffffffff,用0xffffffff与任何颜色“与”都等于原来的颜色;黑色也是如此,透明黑色就是0,纯黑色是0xff000000,与任何颜色“与”都会去掉原来颜色的RGB部分,而保留起Alpha部分。只要你根据这个原理去操作,根本就不必担心透明区域的问题。
jin20000 2009-11-04
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 lfs09 的回复:]
我知道,不过我是菜鸟
[/Quote]
我也是菜鸟,但我知道不知道呢
flybao51 2009-11-04
  • 打赏
  • 举报
回复
就为楼主那句菜鸟不要来而进来的,知道也不告诉你
jhjhzr 2009-11-04
  • 打赏
  • 举报
回复
把透明改成白色可以了,不过又有个问题,如果不改白色透明的如何处理?我们的需求需要保留透明区域。
jhjhzr 2009-11-04
  • 打赏
  • 举报
回复
白色区域是透明的,不知道是不是因为这个原因,取反有问题,我叫美工把透明改成白色试试
阿发伯 2009-11-04
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 jhjhzr 的回复:]
引用 10 楼 maozefa 的回复:
我这第二步与你以前是不同的处理,你是直接用黑白图与照片“或”,我的却是“复制反向黑白图(黑变白,白变黑),与用户照片进行“与””,不会出现你说的问题

测试过了,先把黑白图取反,然后与用户照片做”与“运算,还是不行,黑色区域也会有用户照片的阴影,不知道是不是反向的不彻底。郁闷,这个问题搞了2天了
[/Quote]
黑色与任何颜色“与”只能是黑色,怎么还会“有用户照片的阴影”?那就只有2个原因了,一是你的操作用问题;二是黑白图的黑色“不纯”,不是真正的黑色
liherun 2009-11-04
  • 打赏
  • 举报
回复
菜鸟帮顶,只为学习不为分
jhjhzr 2009-11-04
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 maozefa 的回复:]
我这第二步与你以前是不同的处理,你是直接用黑白图与照片“或”,我的却是“复制反向黑白图(黑变白,白变黑),与用户照片进行“与””,不会出现你说的问题
[/Quote]
测试过了,先把黑白图取反,然后与用户照片做”与“运算,还是不行,黑色区域也会有用户照片的阴影,不知道是不是反向的不彻底。郁闷,这个问题搞了2天了
阿发伯 2009-11-04
  • 打赏
  • 举报
回复
我这第二步与你以前是不同的处理,你是直接用黑白图与照片“或”,我的却是“复制反向黑白图(黑变白,白变黑),与用户照片进行“与””,不会出现你说的问题
jhjhzr 2009-11-04
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 maozefa 的回复:]
引用 4 楼 jhjhzr 的回复:
我现在的方法是
黑白图与相框进行“与”运算,得到相框和黑色的区域
然后再和用户照片"或"运算,黑色区域被用户照片替换,但是原来相框的区域也会出现相框和用户照片”或“运算后的结果,就是原来相框的区域的图象有问题,我只想保留相框的图象就行了。

1、黑白图与相框进行“与”运算,得到相框和黑色的区域
2、复制反向黑白图(黑变白,白变黑),与用户照片进行“与”运算,得到除去相框部分的用户照片图
3、上面2个部分作“或”运算
[/Quote]
问题就出在步骤2,与运算后,黑色区域(相框的目标区域)也会有用户的照片阴影,不能保持黑色
阿发伯 2009-11-04
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 jhjhzr 的回复:]
我现在的方法是
黑白图与相框进行“与”运算,得到相框和黑色的区域
然后再和用户照片"或"运算,黑色区域被用户照片替换,但是原来相框的区域也会出现相框和用户照片”或“运算后的结果,就是原来相框的区域的图象有问题,我只想保留相框的图象就行了。
[/Quote]
1、黑白图与相框进行“与”运算,得到相框和黑色的区域
2、复制反向黑白图(黑变白,白变黑),与用户照片进行“与”运算,得到除去相框部分的用户照片图
3、上面2个部分作“或”运算
mjp1234airen4385 2009-11-04
  • 打赏
  • 举报
回复
建议请教论坛里的阿阿发伯。

110,525

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧