我制作了一个使用OnPaint和base.OnPaint的控件。 现在我想要在某些条件下反转所有颜色。但是我该怎么做?我知道如何反转图像,但如何处理Graphics对象?
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
MyOwnPaint(e);
if(Condition)
InvertColors(e);
}
答案 0 :(得分:2)
在开始之前,我想说我同意Xaero的观点。似乎您的预期目标将从ErrorProvider类中受益。
也就是说,您可以通过P / Invoke使用BitBlt反转图形区域的内容。这是一个可以为你做的功能,虽然没有优化。我会把那部分留给你。此功能使用光栅操作来反转目标区域。在目的地上带有白色光源的XOR会导致目标处的颜色反转(按逻辑值,不一定是颜色空间)。
private void InvertGraphicsArea(Graphics g, Rectangle r)
{
if (r.Height <= 0) { return; }
if (r.Width <= 0) { return; }
using (Bitmap bmpInvert = GetWhiteBitmap(g, r))
{
IntPtr hdcDest = g.GetHdc();
using (Graphics src = Graphics.FromImage(bmpInvert))
{
int xDest = r.Left;
int yDest = r.Top;
int nWidth = r.Width;
int nHeight = r.Height;
IntPtr hdcSrc = src.GetHdc();
BitBlt(hdcDest, xDest, yDest, nWidth, nHeight,
hdcSrc, 0, 0, (uint)CopyPixelOperation.DestinationInvert);
src.ReleaseHdc(hdcSrc);
}
g.ReleaseHdc(hdcDest);
}
}
在包含此实用程序功能的类中,您需要导入System.Runtime.InteropServices以及BitBlt()的定义。此外,使用GetWhiteBitmap()辅助方法,此函数的内部更简洁。
using System.Runtime.InteropServices;
// ...
[DllImport("gdi32.dll",
EntryPoint="BitBlt",
CallingConvention=CallingConvention.StdCall)]
extern public static int BitBlt(
IntPtr hdcDesc, int nXDest, int nYDest, int nWidth, int nHeight,
IntPtr hdcSrc, int nXSrc, int nYSrcs, uint dwRop);
private Bitmap GetWhiteBitmap(Graphics g, Rectangle r)
{
int w = r.Width;
int h = r.Height;
Bitmap bmp = new Bitmap(w, h);
using (Graphics gTmp = Graphics.FromImage(bmp))
{
gTmp.Clear(Color.White);
}
return bmp;
}
这不是图形表面颜色的真正颜色转换反转 - 但这与在旧的win32天中完成高光的方式非常类似。为了测试这个,我修改了一个默认的WinForms应用程序并添加了以下代码,它处理双击,绘制,并具有替换状态的成员变量。
bool m_Highlight = false;
private void Form1_DoubleClick(object sender, EventArgs e)
{
m_Highlight = !m_Highlight;
this.Invalidate();
}
private void Form1_Paint(object sender, PaintEventArgs e)
{
// Note: sloppy, but just to show that everything is inverted.
using(Font font = new Font(FontFamily.GenericSerif, 20.0f, FontStyle.Bold))
{
e.Graphics.DrawString("Hello World!", font, Brushes.Red, 0.0f, 0.0f);
}
if (m_Highlight)
{
InvertGraphicsArea(e.Graphics, e.ClipRectangle);
}
}
答案 1 :(得分:1)