Jakub Florczyk - Blog o programowaniu .NET

Programista praktyczny

Półprzezroczyste grafiki .NET Compact Framework

W jednym z poprzednich artykułów opisywałem sposób wyrysowywania grafik z użyciem ColorKey aby uzyskać efekt przezroczystości. W tym artykule chciałbym poruszyć temat grafik o stałym ustalonym przez nas kanale alfa.

Aby uzyskać efekt półprzezroczystości wykorzystamy funkcję AlphaBlend z biblioteki coredll.dll. Po szczegóły na temat tej metody zapraszam na http://www.pinvoke.net ponieważ ja w tym artykule ograniczę się tylko do części wspieranej przez .NET CF:

[DllImport("coredll.dll")]
private extern static int AlphaBlend(IntPtr hdcDest, int xDest, int yDest, int cxDest, int cyDest, IntPtr hdcSrc, int xSrc, int ySrc, int cxSrc, int cySrc, BlendFunction blendFunction);

private struct BlendFunction
{
	public byte BlendOp;
	public byte BlendFlags;
	public byte SourceConstantAlpha;
	public byte AlphaFormat;
}

W BlendFunction możemy tylko ustawić SourceConstantAlpha, czyli stałe alfa dla grafiki. Poniżej prosty class extension:

internal static class GraphicsExtensions
{
	internal static void AlphaBlend(this Graphics source, Graphics destination, byte alpha, int xSrc, int ySrc, int wSrc, int hSrc, int xDest, int yDest, int wDest, int hDest)
        {
            	IntPtr hdcDst = source.GetHdc();
            	IntPtr hdcSrc = destination.GetHdc();
            	BlendFunction blendFunction = new BlendFunction();
            	blendFunction.BlendOp = 0; // jedyna wspierana operacja
            	blendFunction.BlendFlags = 0; // dokumentacja zaleca wstawienie tutaj ?0?
            	blendFunction.SourceConstantAlpha = alpha; // nasze alfa
            	blendFunction.AlphaFormat = 0; // wyłączone alfa na pixel
            	AlphaBlend(hdcDst, xDest, yDest, wDest, hDest, hdcSrc, xSrc, ySrc, wSrc, hSrc, blendFunction);
            	source.ReleaseHdc(hdcSrc);
            	destination.ReleaseHdc(hdcDst);
        }
}

Teraz wystarczy tylko na istniejącego Graphics-a nałożyć drugiego z określoną grafiką:

using (Bitmap  colorImage = new Bitmap(128, 128))
{
	using (Graphics gCi = Graphics.FromImage(colorImage))
	{
		gCi.Clear(Color.Red);
		g.AlphaBlend(gCi, 192,
      			0, 0, colorImage.Width, colorImage.Height,
    			0, 0, colorImage.Width, colorImage.Height);
	}
}

W przypadku jak powyżej g jest naszym aktualnym graphicsem na którym rysujemy. Graphics gCi to jest pokolorowany na czerwono kwadrat, któremu nadajemy alfa o wartości 192. Oczywiście nic nie stoi na przeszkodzie aby używać dowolnych “rysowalnych” elementów jak w screenie poniżej:

blipmobile

Next post »

7 ResponsesLeave one →

  1. Adam Ciszewski

     /  2009-09-23

    Witam chciałbym zapytać czy grafiki (górne cztery) są wyrysowywane bezpośrednio na formie i potem pola jakie zajmują służą jako przyciski ? czy może na jakimś przezroczystym tle komponentu ? próbuje wykorzystac picturebox z transparentną grafiką uzyskana wg. Pana wczesniejszego przepisu (colorKey), ale wyrysowuje grafike podczas “Paint” i pozostaje mi niestety backcolor PictureBox’a (caly obszar niezajęty przez wyrysowywany obraz) :/ (ale przynajmniej z pominięciem koloru transparentnego) czy mogę prosić o poradę ?

  2. Jakub Florczyk

     /  2009-10-21

    @Adam Ciszewski

    Po pierwsze to nie Pan :p Sorka ale umknął mi jakoś ten komentarz. Całość jest rysowana na jednym formie i to bardzo pokombinowane, żeby taki efekt uzyskać a do tego koszmarnie wolne.
    Co do PictureBox to takiego efektu nie uzyskasz. Musisz sam rysować grafikę na Formie, przeciążając metodę OnPaint i wtedy rysować z ColorKey.

  3. Piotr G

     /  2009-12-25

    Witam
    Nie mogę dodać referencji coredll.dll dla visual studio 2008 co może być tego powodem ?

  4. Jakub Florczyk

     /  2009-12-25

    @Piotr G

    Nie można dodać referencji do tej biblioteki. Musisz znać definicję funkcji i się odwoływać przez DllIpmort. Jak np. w pierwszym przykładzie z tego wpisu.

  5. Piotr G

     /  2009-12-25

    Dzięki wielkie :)
    A może Pan w wolnym czasie opisać przykładową implementacje biblioteki Winsock Orcas.dll dla windows mobile pod Visual Studio 2008 ? Bo nigdzie nie mogę jej znaleźć. Lub jak sprawdzić w system.net.socket czy doszedł cały pakiet z serwera do clienta na programie(cliencie) ?

  1. Blog o programowaniu .NET – Jakub Florczyk » Przezroczyste grafiki w .NET Compact Framework

Leave a Reply