Delphi-Forum.de Delphi-Library.de
C-Sharp-Forum.de C-Sharp-Library.de
Registrieren Login Suche Hilfe Sitemap
[2.0] Pixel-Farbe in Bitmap ändern
spacer
Autor Nachricht
Christoph1972
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starhalf offtopic star

Beiträge: 307
Erhaltene Danke: 1
Dabei seit: 20.09.2008



VS2005 Standard / C# & VB.Net
BeitragVerfasst: Di 09.03.10 15:07 
.NET Version: 2.0
Antworten mit Zitat Beitrag melden
Hallo Leute,

ich möchte Pixel von einem „schwarz“ –weiß Image verändern. Und zwar möchte ich die Farbe der schwarzen Pixel in eine beliebige Farbe ändern. Bisher habe ich das so gemacht und bin damit gut gefahren:

ausblenden C#-Quelltext markieren
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
private Bitmap ChangeColor(Image image, Color color)
{
Bitmap pic = new Bitmap(image);
Bitmap newPic = new Bitmap(pic.Width, pic.Height);

ColorMap[] cMap = new ColorMap[1];

cMap[0] = new ColorMap();
cMap[0].OldColor = Color.Black;
cMap[0].NewColor = color;

ImageAttributes imageAtributes = new ImageAttributes();
imageAtributes.SetRemapTable(cMap);

using (Graphics g = Graphics.FromImage(newPic))
{
g.DrawImage(pic, new Rectangle(0, 0, pic.Width, pic.Height), 0, 0, pic.Width, pic.Height, GraphicsUnit.Pixel, imageAtributes);
}

return newPic;
}


Nun ist es aber so, das in einigen Images die Grafik abgestuft ist, also dunkel grau - bis schwarze Pixel. Da komme ich mit der Methode natürlich nicht weiter.

Es wäre kein Problem, wenn alle Pixel die nicht weiß sind, in schwarz umgewandelt werden. Das wäre genau das was ich benötige.

Hat jemand eine Idee, wie alle Farben die in dem Image enthalten sind in eine ColorMap bekomme? Wobei ich nicht die GetPixel Methode mit einer Schleife verwenden möchte, das dauert viel zulange.

Mit einer ColorMatrix könnte es auch gehen, ich habe nur keine Vorstellung, wie die Matrix für schwarz abgebildet werden muss.Diese Matrix macht ein Image schwarz weiß, mit Grauabstufungen:

ausblenden C#-Quelltext markieren
1:
ColorMatrix colorMatrix = new ColorMatrix(new float[][] { new float[] { 0.299F, 0.299F, 0.299F, 0, 0 }, new float[] { 0.587F, 0.587F, 0.587F, 0, 0 }, new float[] { 0.114F, 0.114F, 0.114F, 0, 0 }, new float[] { 0, 0, 0, 1, 0 }, new float[] { 0, 0, 0, 0, 1 } });


Ehrlich gesagt verstehe ich die ColorMatrix nicht wirklich und bin daher nicht in der Lage sie so zu ändern, dass sie nur schwarz abbildet.


Besteht eventuell eine Möglichkeit es "einfach" über die ImageAtributes zu lösen?


Vielleicht hat ja jemand eine Idee. Ich befürchte das es viel einfacher ist als ich denke, aber wer weis.......

_________________
Gruß
Christoph
Private Nachricht sendenPosting in privater Nachricht zitieren Webseite dieses Mitglieds besuchen
Christian S.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starhalf offtopic starofftopic star
Chefentwickler

Beiträge: 17441
Erhaltene Danke: 95
Dabei seit: 07.07.2002
Wohnort: Server-Souterrain

Win 7
Delphi Prism, C# (VS 2010)
BeitragVerfasst: Di 09.03.10 22:58  Antworten mit Zitat Beitrag melden
Hast Du mal geschaut, wie schnell das ist, wenn Du es mittels LockBits und den entsprechenden Operationen direkt an den Bytes machst? Ich habe das ein paar Mal benutzt und der Geschwindigkeitsvorteil gegenüber GetPixel / SetPixel ist sehr, sehr deutlich.

_________________
I am of peace. Always.
Private Nachricht sendenPosting in privater Nachricht zitieren Webseite dieses Mitglieds besuchen
Christoph1972
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starhalf offtopic star

(Threadstarter)

Beiträge: 307
Erhaltene Danke: 1
Dabei seit: 20.09.2008



VS2005 Standard / C# & VB.Net
BeitragVerfasst: Mi 10.03.10 00:08  Antworten mit Zitat Beitrag melden
Ah, vielen Dank für die Info! Von LookBits und den entsprechenden Operationen habe ich bisher nichts gehört. Ich werde mich darüber informieren. Anregungen und Hinweise sind wie immer willkommen!

_________________
Gruß
Christoph
Private Nachricht sendenPosting in privater Nachricht zitieren Webseite dieses Mitglieds besuchen
danielf
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star

Beiträge: 900
Erhaltene Danke: 14
Dabei seit: 28.01.2009
Wohnort: Stuttgart

Windows XP
C# (VS 2008)
BeitragVerfasst: Mi 10.03.10 09:22  Antworten mit Zitat Beitrag melden
Hallo,

schau mal hier habe ich ein Tutorial mit einem hilfreichen Vergleich gefunden. Selber habe ich damals für Bildoperationen auch die Bitlock-Methode verwendent, wie sie Christian angesprochen hat. Müsste aber erst nachschauen wie ich das damals 'genau' gemacht hab. Ansatzweise sah es so aus.

Wenn du damit nicht weiter kommst, kann ich gerne mal mein Projekt laden (gerade kein Zugriff) und schauen wie ich es da gemacht hab.

Gruß Daniel
Private Nachricht sendenPosting in privater Nachricht zitieren Webseite dieses Mitglieds besuchen
Christoph1972
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starhalf offtopic star

(Threadstarter)

Beiträge: 307
Erhaltene Danke: 1
Dabei seit: 20.09.2008



VS2005 Standard / C# & VB.Net
BeitragVerfasst: Do 11.03.10 20:50  Antworten mit Zitat Beitrag melden
Hallo Leute,

ich musste leider feststellen, dass es doch keine gute Lösung ist, das Image komplett einzuschwärzen. Von daher hat sich die Fragestellung erledigt.

Was mich aber doch interessiert, ist die Optimierung der GetPixel Methode, mittels unsafe Aufruf. So wie ich es gemacht habe dauert es immer noch recht lange.


ausblenden C#-Quelltext markieren
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
unsafe void Test(Bitmap image)
{
Color color;

for (Int32 y = 0; y < image.Height; y++)
{
for (Int32 x = 0; x < image.Width; x++)
{
color = image.GetPixel(x, y);
}
}
}
}



Ist das so korrekt?

_________________
Gruß
Christoph
Private Nachricht sendenPosting in privater Nachricht zitieren Webseite dieses Mitglieds besuchen
Christian S.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starhalf offtopic starofftopic star
Chefentwickler

Beiträge: 17441
Erhaltene Danke: 95
Dabei seit: 07.07.2002
Wohnort: Server-Souterrain

Win 7
Delphi Prism, C# (VS 2010)
BeitragVerfasst: Do 11.03.10 20:59  Antworten mit Zitat Beitrag melden
Wird unsafe nicht nur dann schneller, wenn man auch unsafe Operationen ausführt? :gruebel:

Auch hier würde ich wieder zum LockBits-Schema raten.

_________________
I am of peace. Always.
Private Nachricht sendenPosting in privater Nachricht zitieren Webseite dieses Mitglieds besuchen
danielf
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star

Beiträge: 900
Erhaltene Danke: 14
Dabei seit: 28.01.2009
Wohnort: Stuttgart

Windows XP
C# (VS 2008)
BeitragVerfasst: Do 11.03.10 21:04  Antworten mit Zitat Beitrag melden
Nein, so einfach ist es nicht ;)

Du hast die Methode zwar als unsafe deklariert, aber verwendest dennoch mit der GetPixel-Methode eine Methode die im managed Bereich läuft.

Zum Beispiel für 24bppRGB:

ausblenden C#-Quelltext markieren
1:
2:
3:
4:
5:
6:
7:
8:
9:
Bitmap oBitmap;

bitmapData data = oBitmap.LockBits( rBounds, ImageLockMode.Read, oBitmap.PixelFormat );

int iCurrentPosition = iY * data.Stride + (iX * 3);

Color color = Color.FromArgb(data[ iCurrentPosition+2 ],
data[ iCurrentPosition+1 ],
data[ iCurrentPosition ] );


Besser ist es aber das LockBits nur einmal zu machen, am besten in einer Art Helper-Class der du das bitmap übergibts auf dem du arbeiten willst.

Gruß daniel
Private Nachricht sendenPosting in privater Nachricht zitieren Webseite dieses Mitglieds besuchen
Christoph1972
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starhalf offtopic star

(Threadstarter)

Beiträge: 307
Erhaltene Danke: 1
Dabei seit: 20.09.2008



VS2005 Standard / C# & VB.Net
BeitragVerfasst: Do 11.03.10 21:25  Antworten mit Zitat Beitrag melden
Hi,

vielen Dank für die schnellen Antworten! Ich hatte das mit unsafe aus der Hilfe, weiter wird da nicht drauf eingegangen. Ok, das LookBits werde ich mir mal anschauen.

_________________
Gruß
Christoph
Private Nachricht sendenPosting in privater Nachricht zitieren Webseite dieses Mitglieds besuchen
Christian S.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starhalf offtopic starofftopic star
Chefentwickler

Beiträge: 17441
Erhaltene Danke: 95
Dabei seit: 07.07.2002
Wohnort: Server-Souterrain

Win 7
Delphi Prism, C# (VS 2010)
BeitragVerfasst: Do 11.03.10 21:49  Antworten mit Zitat Beitrag melden
Hi!

Ich habe noch was bei mir auf der Platte gefunden. In grauer Vorzeit habe ich mal eine solche Klasse geschrieben, und nachdem ich gerade mal kurz drüber geguckt habe, scheint sie keine allzu schlimmen Jugendsünden zu enthalten. Außer einer: Das Disposable-Pattern war nicht richtig implementiert, was ich in Delphi Prism aber durch das hinzufügen eines Aspekts mit einer Zeile korrigieren konnte :mrgreen:

Ich hänge mal Quelltext und Kompilat an. Das Assembly behauptet, .NET 3.5 zu brauchen (das hängt mit dem Aspekt zusammen), läuft bei mir aber auch in einer .NET 2.0 Anwendung problemlos, wenn man die Warnungen ignoriert. ;-)

Quelltext (pas, 13.07 KB)
Kompilat mit unvollständiger XML-Doku (zip, 4.64 KB)

Benutzen tust Du's dann z.B. so:
ausblenden C#-Quelltext markieren
1:
2:
3:
4:
5:
6:
7:
8:
9:
            var bmp = new Bitmap(8000, 6000, System.Drawing.Imaging.PixelFormat.Format24bppRgb);

var fast = new FastBitmap(bmp, true);

for (int x = 0; x < 8000; x++)
for (int y = 0; y < 6000; y++)
fast.SetPixel(x, y, Color.Blue);

pictureBox1.Image = fast.Bitmap;;

Beachte in der XML-Doku bitte aber auch die Hinweise zur AutoUpdate-Eigenschaft und dem entsprechenden Parameter in den Konstruktoren.

Grüße
Christian
Einloggen, um Attachments anzusehen!
_________________
I am of peace. Always.
Private Nachricht sendenPosting in privater Nachricht zitieren Webseite dieses Mitglieds besuchen
Werbung ausblenden? Dann registriere Dich kostenlos. Weitere Gründe für eine Registrierung.


Werbung ausblenden? Dann registriere Dich kostenlos. Weitere Gründe für eine Registrierung.
Beiträge vom vorherigen Thema anzeigen:   
home home