2017-04-03 2 views
1

Ich muss Bilder auf einem Bild-Steuerelement, die eine Zusammensetzung von zwei PNG-Dateien sind, wo das obere Bild transparente Pixel an bestimmten Positionen hat, präsentieren.MFC CImage Alpha Blending falsch gegangen

Das Ergebnis sollte von plotter.png

enter image description here

mit bar.png

enter image description here

auf seiner Oberseite überlappt erscheint als (Beachten Sie die seltsamen weißen Konturen auf der Bar):

enter image description here

aber es sollte sein:

enter image description here

Der Code, den ich für sie gemacht ist einfach wie

CImage image; 
    if (FAILED(image.Load(L"plotter.png"))) 
     return false; 

    CImage imageBar; 
    if (FAILED(imageBar.Load(L"bar.png"))) 
     return false; 

    imageBar.AlphaBlend(image.GetDC(), CPoint()); 
    image.ReleaseDC(); 


    ((CStatic*)GetDlgItem(IDC_PICTURE))->SetBitmap(image); 

ich die MSDN-Dokumentation auf Alpha Blending a Bitmap gelesen haben und BLENDFUNCTION structure und einige Experimente gemacht haben. Ein Detail mich auf den Text starren Ich zitiert:

Dieses Flag wird gesetzt, wenn das Bitmap ein Alpha-Kanal hat (das heißt, pro-Pixel-alpha). Beachten Sie, dass die APIs Alpha-Multiplikation verwenden, die bedeutet, dass die roten, grünen und blauen Kanalwerte in der Bitmap mit dem Alpha-Kanalwert multipliziert werden müssen. Beispiel: Wenn der Alphakanalwert x ist, müssen die roten, grünen und blauen Kanäle multipliziert mit x sein und vor dem Aufruf durch 0xff geteilt sein.

Alphablend verwendet premultiplied alpha, die nach dem Laden bedeutet I auf die Bitmap gehen und jedes Pixel durch seine eigene alpha vervielfachen. Also habe ich versuchte

for (int i = 0; i < imageBar.GetWidth(); i++) 
{ 
    for (int j = 0; j < imageBar.GetHeight(); j++) 
    { 
     BYTE* ptr = (BYTE*) imageBar.GetPixelAddress(i, j); 
     ptr[0] = (ptr[0] * ptr[3])/255; 
     ptr[1] = (ptr[1] * ptr[3])/255; 
     ptr[2] = (ptr[2] * ptr[3])/255; 
    } 
} 

vor der AlphaBlend Linie und was ich habe noch nicht zufriedenstellend :(

Also, wie kann ich ein richtig zusammengesetzt Bild?

+0

Stellen Sie sicher, dass Ihre PNG-Dateien 24-Bit sind, da 8-Bit-PNGs keine Transparenz unterstützen. – l33t

Antwort

1

Nach einigen Tagen und Nacht der Verzweiflung, ich habe endlich http://forums.codeguru.com/showthread.php?420631-setting-CImage-alpha-values&p=1560260#post1560260 gefunden, die eine Lösung ähnlich wie ich es versucht habe, aber mit der Addition von 127 zu jedem Pixel, das ist eine Sache, die funktionierte, aber ich habe nicht zu der Zeit, noch ich verstanden hatte sich bemüht, es noch zu verstehen, also vor der AlphaBlend Zeile gibt es jetzt:

for (int i = 0; i < imageBar.GetWidth(); i++) 
{ 
    for (int j = 0; j < imageBar.GetHeight(); j++) 
    { 
     BYTE* ptr = (BYTE*)imageBar.GetPixelAddress(i, j); 
     ptr[0] = ((ptr[0] * ptr[3]) + 127)/255; 
     ptr[1] = ((ptr[1] * ptr[3]) + 127)/255; 
     ptr[2] = ((ptr[2] * ptr[3]) + 127)/255; 
    } 
} 

und jetzt ist das angezeigte Bild gut komponiert.

Verwandte Themen