[英]Invert colors on a control
我做了一個使用OnPaint和base.OnPaint的控件。 現在,我希望所有顏色在特定條件下都可以反轉。 但是我該怎么做呢? 我知道如何反轉圖像,但是如何處理Graphics對象?
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
MyOwnPaint(e);
if(Condition)
InvertColors(e);
}
在開始之前,我想說我同意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);
}
}
這不是您問題的直接答案,而是一種可能的替代方法,它更干凈一些,並且我認為,與反轉控件的顏色相比,它更符合Windows標准。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.