Problem mit GDI+ und Colormatrix

Hallo,

ich nutze VB.Net und stosse dabei auf folgendes Problem!

Ich habe eine Picturebox, wo ich ein Bild lade und anzeige. Diese Picturebox nennen wir mal PicBild. Nun möchte ich das das Bild auf Befehl invertiert wird. Dazu verwende ich folgende Routine

 Private Sub InvertPicture(ByVal Pic As PictureBox, ByVal CM As Imaging.ColorMatrix)
 Dim Bmp As New Bitmap(Pic.Image.Width, Pic.Image.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb)
 Bmp.SetResolution(Pic.Image.HorizontalResolution, Pic.Image.VerticalResolution)
 Dim G As Graphics = Graphics.FromImage(Bmp)
 Dim ImgAttr As New Imaging.ImageAttributes
 ImgAttr.SetColorMatrix(CM, Imaging.ColorMatrixFlag.Default, Imaging.ColorAdjustType.Bitmap)
 G.DrawImage(Pic.Image, New Rectangle(0, 0, Pic.Image.Width, Pic.Image.Height), 0, 0, Bmp.Width, Bmp.Height, GraphicsUnit.Pixel, ImgAttr)
 G.Dispose()
 ImgAttr.Dispose()
 PictureBox1.Image = Bmp
 End Sub

Aufrufen tue ich die Routine mittels

 Dim cm As Imaging.ColorMatrix = New Imaging.ColorMatrix(New Single()() {New Single() {-1.0F, 0.0F, 0.0F, 0.0F, 0.0F}, New Single() {0.0F, -1.0F, 0.0F, 0.0F, 0.0F}, New Single() {0.0F, 0.0F, -1.0F, 0.0F, 0.0F}, New Single() {0.0F, 0.0F, 0.0F, 1.0F, 0.0F}, New Single() {0.0F, 0.0F, 0.0F, 0.0F, 1.0F}})
 InvertPicture(picBild, cm)

zu Testzwecken soll das invertierte Bild in eine andere Picturebox geschrieben werden. Das Resultat ist aber nun, das dieses Bild schwarz bleibt! Ändere ich die Werte für die ColorMatrix, so ändert sich das Bild auch entsprechend. Also Graustufen etc. Nur beim invertieren klappt das nicht :frowning:

Eine sehr langwierige Recherche im Internet brachte mich auf folgende Seite.

http://www.bobpowell.net/negativeimage.htm

Da mein Englisch nicht so toll ist, hatte ich da einige Probleme.
Aber soweit ich es verstanden habe, gibt es einen Bug in der Colormatrix. Diesen könnte man beheben, wenn man erst auf das Bild folgende Matrix anwendet.

Matrix00=0.99f
Matrix11=0.99f
Matrix22=0.99f
Matrix33=1
Matrix44=1
Matrix40=.04f
Matrix41=.04f
Matrix42=.04f

Also habe ich folgendes probiert. Auf das Bild die oben genannte Matrix angewendet und gleich danach die Matrix für das invertieren des Bildes angewendet. Das Resultat ist jedoch, das das Bild auch schwarz bleibt.

Hat jemand noch eine Idee woran das liegen kann?
Habe ich den Inhalt auf der oben genannten Seite vielleicht falsch verstanden?

MfG Alex

Moin Anno74,

zunächst einmal: Du hast alles richtig verstanden :smile:

Du bist nur nicht bist zum Ende gekommen.
die Matrix zum invertieren ist schlicht und ergreifend nicht vollständig.

 invColorMatrix.Matrix00 = -1;
 invColorMatrix.Matrix11 = -1;
 invColorMatrix.Matrix22 = -1;
 invColorMatrix.Matrix33 = 1;
 invColorMatrix.Matrix40 = invColorMatrix.Matrix41 = invColorMatrix.Matrix42 = invColorMatrix.Matrix44 = 1;
 invColorMatrix.Matrix43 = 0;

Dadurch, dass dir die letzten werte fehlen, „zerschießt“ es dir die Farbwerte.
schließlich soll die Matrix am Ende so aussehen:

new float[][]
{
 new float[] {-1, 0, 0, 0, 0},
 new float[] {0, -1, 0, 0, 0},
 new float[] {0, 0, -1, 0, 0},
 new float[] {0, 0, 0, 1, 0},
 new float[] {1, 1, 1, 0, 1}
}

Wenn du das korrigiert hast, sollte es laufen :smile:

MfG
Salbei

Hallo Salbei,

vielen Dank erst einmal für Deine Mühe :smile:

zunächst einmal: Du hast alles richtig verstanden :smile:

Gut dann bin ich ja beruhigt :smile:

Du bist nur nicht bist zum Ende gekommen.
die Matrix zum invertieren ist schlicht und ergreifend nicht
vollständig.

 invColorMatrix.Matrix00 = -1;
 invColorMatrix.Matrix11 = -1;
 invColorMatrix.Matrix22 = -1;
 invColorMatrix.Matrix33 = 1;
 invColorMatrix.Matrix40 = invColorMatrix.Matrix41
= invColorMatrix.Matrix42 = invColorMatrix.Matrix44 = 1;
 invColorMatrix.Matrix43 = 0;

Ok, dann ändere ich die Matrix zum invertieren um! Was mich aber wundert. Genau die Matrix die ich verwendet habe, taucht so oft in verschiedenen Foren auf :frowning: Das das da noch keiner bemerkt hat?

Dadurch, dass dir die letzten werte fehlen, „zerschießt“ es
dir die Farbwerte.
schließlich soll die Matrix am Ende so aussehen:

new float[][]
{
 new float[] {-1, 0, 0, 0, 0},
 new float[] {0, -1, 0, 0, 0},
 new float[] {0, 0, -1, 0, 0},
 new float[] {0, 0, 0, 1, 0},
 new float[] {1, 1, 1, 0, 1}
}

Wenn du das korrigiert hast, sollte es laufen :smile:

Ok, aber muss ich dann die Korrektur vorher noch vornehmen, wie ich es oben beschrieben habe? Sprich diese hier

 cm.Matrix00=cm.Matrix11=cm.Matrix22=0.99f;
 cm.Matrix33=cm.Matrix44=1;
 cm.Matrix40=cm.Matrix41=cm.Matrix42=.04f;

MfG
Salbei

MfG Alex

Moin Alex,

ja, die Korrektur musst du noch vor nehmen.

Das Problem ist auch eigentlich kein Fehler in der C#-Funktion. Ich bin mir da wirklich nicht sicher, aber da es ja eine 5x5 Matrix ist, denke ich, dass dort das CMYK-Farbmodell zur berechnung genommen wird. Zusätzlich mit einem Wert für die Transparenz. (Ist aber wirklich nur eine Vermutung.) http://de.wikipedia.org/wiki/CMYK#CMY-Farbraum_und_C…

Viel erfolg :wink:

MfG
Salbei

Kleiner Zusatz:

Lass dich nicht von meinem C#-Anmerkungen verwirren :wink:

Das Problem ist auch eigentlich kein Fehler in der
C#-Funktion.

Liegt dran, dass ich das ganze nicht in VB, sondern C# mache :wink: Hat aber für beides seine Gütligkeit.

Hallo Salbei,

ja, die Korrektur musst du noch vor nehmen.

Ok, dann baue ich die auch noch ein, obwohl es ja nun eigentlich dank Deiner Hilfe klappt :smile: Aber Schaden kann es ja nicht :smile:

Das Problem ist auch eigentlich kein Fehler in der
C#-Funktion. Ich bin mir da wirklich nicht sicher, aber da es
ja eine 5x5 Matrix ist, denke ich, dass dort das
CMYK-Farbmodell zur berechnung genommen wird. Zusätzlich mit
einem Wert für die Transparenz. (Ist aber wirklich nur eine
Vermutung.)
http://de.wikipedia.org/wiki/CMYK#CMY-Farbraum_und_C…
ell

Viel erfolg :wink:

Danke :smile: Aber nun stosse ich bereits auf das naechste Problem. Ich mache dazu aber mal einen neuen Thread auf. Vielleicht hast du da ja eine zündende Idee, wie ich das umgehen kann :smile:

MfG Alex

Das habe ich bereits mitbekommen. Aber Gott sei Dank, hatte ich keine Probleme das in VB umzusetzen. Meistens erkennt man ja, was das machen soll und dann ist die Umsetzung relativ simple :smile:

MfG Alex