我做了一個使用OnPaint和base.OnPaint的控件。 現在我想要在某些條件下將所有顏色都顛倒過來。但我該怎麼做?我知道如何反轉圖像,但我如何處理圖形對象?在控件上反轉顏色
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
MyOwnPaint(e);
if(Condition)
InvertColors(e);
}
我做了一個使用OnPaint和base.OnPaint的控件。 現在我想要在某些條件下將所有顏色都顛倒過來。但我該怎麼做?我知道如何反轉圖像,但我如何處理圖形對象?在控件上反轉顏色
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);
}
}
+1的控制,正如我的回答中所述 - 我同意這樣做更好。 – meklarian
感謝downvote沒有解釋...毫無意義! –
這裏沒有問題。 – Lazarus
出於興趣,你爲什麼想要這樣做?也許有更好的解決方案。 –
對不起。但現在是一個問題 – magol