Desidero utilizzare le immagini parzialmente trasparenti nelle operazioni di trascinamento/rilascio. Tutto questo è impostato e funziona bene, ma l'effettiva trasformazione della trasparenza ha uno strano effetto collaterale. Per qualche motivo, i pixel sembrano essere fusi su uno sfondo nero.Windows Form: creazione di una bitmap del cursore parzialmente trasparente
L'immagine seguente descrive il problema:
Figura a) è la bitmap originale.
La figura b) è ciò che viene prodotto dopo che è stata eseguita la miscelazione alfa. Ovviamente questo è molto più scuro del previsto filtro alfa al 50%.
Figura c) è l'effetto desiderato, immagine a) con una trasparenza del 50% (aggiunta alla composizione con un programma di disegno).
Il codice che uso per produrre l'immagine trasparente è la seguente:
Bitmap bmpNew = new Bitmap(bmpOriginal.Width, bmpOriginal.Height);
Graphics g = Graphics.FromImage(bmpNew);
// Making the bitmap 50% transparent:
float[][] ptsArray ={
new float[] {1, 0, 0, 0, 0}, // Red
new float[] {0, 1, 0, 0, 0}, // Green
new float[] {0, 0, 1, 0, 0}, // Blue
new float[] {0, 0, 0, 0.5f, 0}, // Alpha
new float[] {0, 0, 0, 0, 1} // Brightness
};
ColorMatrix clrMatrix = new ColorMatrix(ptsArray);
ImageAttributes imgAttributes = new ImageAttributes();
imgAttributes.SetColorMatrix(clrMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);
g.DrawImage(bmpOriginal, new Rectangle(0, 0, bmpOriginal.Width, bmpOriginal.Height), 0, 0, bmpOriginal.Width, bmpOriginal.Height, GraphicsUnit.Pixel, imgAttributes);
Cursors.Default.Draw(g, new Rectangle(bmpOriginal.Width/2 - 8, bmpOriginal.Height/2 - 8, 32, 32));
g.Dispose();
imgAttributes.Dispose();
return bmpNew;
Qualcuno sa il motivo per cui l'alpha blending non funziona?
Aggiornamento I:
Per chiarezza, il codice funziona se sto alphablending sulla cima di una superficie disegnato. Il problema è che voglio creare un'immagine completamente semitrasparente da un'immagine esistente e usarla come un cursore dinamico durante le operazioni di trascinamento/rilascio. Anche saltando quanto sopra e dipingendo solo un rettangolo pieno di colore 88ffffff produce un colore grigio scuro. Qualcosa di strano sta succedendo con l'icona.
Aggiornamento II:
Dal momento che ho reseached un bel po 'e che questo ha qualcosa a che fare con la creazione del cursore, sarò comprendono che il codice qui sotto anche. Se I GetPixel-campiona la bitmap appena prima della chiamata CreateIconIndirect, i quattro valori di colore sembrano essere intatti. Quindi ho la sensazione che i colpevoli potrebbero essere i membri hbmColor o hbmMask della struttura IconInfo.
Ecco la struttura ICONINFO:
public struct IconInfo { // http://msdn.microsoft.com/en-us/library/ms648052(VS.85).aspx
public bool fIcon; // Icon or cursor. True = Icon, False = Cursor
public int xHotspot;
public int yHotspot;
public IntPtr hbmMask; // Specifies the icon bitmask bitmap. If this structure defines a black and white icon,
// this bitmask is formatted so that the upper half is the icon AND bitmask and the lower
// half is the icon XOR bitmask. Under this condition, the height should be an even multiple of two.
// If this structure defines a color icon, this mask only defines the AND bitmask of the icon.
public IntPtr hbmColor; // Handle to the icon color bitmap. This member can be optional if this structure defines a black
// and white icon. The AND bitmask of hbmMask is applied with the SRCAND flag to the destination;
// subsequently, the color bitmap is applied (using XOR) to the destination by using the SRCINVERT flag.
}
E qui è il codice che in realtà crea il cursore:
public static Cursor CreateCursor(Bitmap bmp, int xHotSpot, int yHotSpot) {
IconInfo iconInfo = new IconInfo();
GetIconInfo(bmp.GetHicon(), ref iconInfo);
iconInfo.hbmColor = (IntPtr)0;
iconInfo.hbmMask = bmp.GetHbitmap();
iconInfo.xHotspot = xHotSpot;
iconInfo.yHotspot = yHotSpot;
iconInfo.fIcon = false;
return new Cursor(CreateIconIndirect(ref iconInfo));
}
Le due funzioni esterne sono definite come segue:
[DllImport("user32.dll", EntryPoint = "CreateIconIndirect")]
public static extern IntPtr CreateIconIndirect(ref IconInfo icon);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetIconInfo(IntPtr hIcon, ref IconInfo pIconInfo);
Non conosco la risposta, ma questa è una domanda molto buona. :) –
Grazie! Sembra davvero * davvero * strano per me che anche dopo quindici anni di operazioni di trascinamento/rilascio e cursori personalizzati, questa cosa non può essere risolta facilmente. Ottengo * qualche * trasparenza così almeno il sistema suggerisce che si possa fare. Dopo tre giorni passati a battere sulla tastiera e a leggere articoli, ho un leggero sospetto che potrebbe essere necessario attingere alla struttura BITMAPV5HEADER. Ecco un articolo in C++ che potrebbe risolvere il problema: http://support.microsoft.com/default.aspx?scid=kb;en-us;318876. Se qualcuno può portarlo, sarò lieto di consegnare il voto di risposta accettato. – Pedery