[C#]Gerade in Bitmap schreiben?

multimolti

Erfahrenes Mitglied
Hallo!

Ich habe ein zweidimensionales Array mit Farbwerten, das ein Bitmapbild darstellt. Also kann ich z.B. mit bild[15, 20] auf den Pixel (15/20) des Bildes zugreifen.

Jetzt muss ich eine gerade Linie zwischen zwei Punkten zeichnen. Die Funktion dazu soll einmal das Array als Referenz bekommen und dann noch die Start- und Endpunkte.

Ich habe hier einen Linien-Zeichnen-Algorithmus gefunden, aber da der mit einem eindimensionalen Array arbeitet kann ich den nicht 1:1 übernehmen, und ich bekomme das ganze auch nicht angepasst.

Kann mir jemand helfen? Danke!
 
Hallo multimolti,

wenn Du unsicheren Code verwendest, solltest Du den Algorithmus unverändert übernehmen können. Markiere dazu einfach die Methode als unsafe und erstelle innerhalb der fixed-Anweisung einen Zeiger auf das Array:

Code:
fixed(System.Drawing.Color * pColor = &bild[0,0])
{// Weiteren Code einfügen
// Zugriff auf die Elemente über pColor[index]
...
}
Der Code ist zwar nicht getestet, sollte aber eigentlich funktionieren.

Gruß
PhoenixLoe
 
Hä?^^

Also System.Drawing.Color verwende ich nicht, habe meine eigene Color-Klasse, die einfach nur R, G und B speichert, aber das dürfte ja keinen allzu großen Unterschied machen.

Meine Funktion sieht prinzipiell erst mal so aus:

C#:
public static void DrawLine(ref Color[,] map, Point start, Point end, Color pix)
{
    // Code zum Zeichnen der Gerade
}

Und dann soll die Funktion mit dem unsicheren Code so aussehen?

C#:
public static void DrawLine(ref Color[,] bild, Point start, Point end, Color pix)
{
    fixed(Color * map = &bild[0,0])
    {		
    	// Zugriff auf die Elemente über map[index]

        int y0 = (int)start.Y;
        int y1 = (int)end.Y;
        int x0 = (int)start.X;
        int x1 = (int)end.X;
        
        // Ab hier kopierter Code von der Website
        
		int dy = (int)(end.Y - start.Y);
        int dx = (int)(end.X - start.X);
        int stepx, stepy;

        if (dy < 0) { dy = -dy; stepy = -map.GetLength(0); } else { stepy = map.GetLength(0); }
        if (dx < 0) { dx = -dx; stepx = -1; } else { stepx = 1; }
        dy <<= 1;
        dx <<= 1;

        y0 *= map.GetLength(0);
        y1 *= map.GetLength(0);
        map[x0 + y0] = pix;
        if (dx > dy)
        {
            int fraction = dy - (dx >> 1);
            while (x0 != x1)
            {
                if (fraction >= 0)
                {
                    y0 += stepy;
                    fraction -= dx;
                }
                x0 += stepx;
                fraction += dy;
                map[x0 + y0] = pix;
            }
        }
        else
        {
            int fraction = dx - (dy >> 1);
            while (y0 != y1)
            {
                if (fraction >= 0)
                {
                    x0 += stepx;
                    fraction -= dy;
                }
                y0 += stepy;
                fraction += dx;
                map[x0 + y0] = pix;
            }
        }
    }
}

Da meckert das Visual Studio leider gleich rum, einerseits mag er all die Stellen, wo ich "map" benutze nicht:

y0 *= map.GetLength(0); --> Pointers and fixed size buffers may only be used in an unsafe context
y0 *= map.GetLength(0); --> Operator '.' cannot be applied to operand of type 'meinnamespace.Color'

Andererseits mag er das "fixed" nicht:
fixed (Color* map = &bild[0, 0]) --> Cannot take the address of, get the size of, or decclare a pointer to a managed type
fixed (Color* map = &bild[0, 0]) --> Pointers and fixed size buffers may only be used in an unsafe context


Danke schon mal für die Hilfe, aber zumindest so, wie ich das verstanden habe, funktioniert es nicht =(
 
Zuletzt bearbeitet von einem Moderator:
Oh, wie peinlich :D Habe mir nur die erste Lösung angeschaut und dann nach unten gescrollt, um die "optimierteste" zu bekommen. Naja, dann Versuch ichs mal mit Step 3 ;-)
 
Soo, der Code scheint gut zu funktionieren, dann liegt das Problem wohl eher bei meiner Implementierung des Bildes -.-

Ich lese jetzt grad mal zum Testen eine komplett weiße ASCII-PBM-Datei ein (da ist einfach ne 1 für Schwarz und ne 0 für Weiß).
Dann konvertiere ist das Bild in ein Farbbild (also einfach die 1 durch 0/0/0 und die 0 durch 255/255/255 ersetzen), die Struktur des 2D-Arrays ist die Gleiche.
Jetzt lasse ich nur noch die Funktion auf das Array los, um eine Gerade (zum Testen) von 100/50 nach 300/350 in Rot zeichnen zu lassen. Das Bild sieht am Ende aber aus wie im Anhang (große Ansicht wählen, um die Punkte sehen zu können).

Da liegt dann ja wohl irgendwie ein Problem darin, wie ich entweder die Arrays interpretiere oder wie ich die Daten nachher wieder in eine Datei speicher. Habt ihr, wenn ihr euch das Bild anschaut, direkt eine Idee, was ich falsch gemacht habe? Ansonsten poste ich nachher noch mal den Code, wie ich die Bilder lese/schreibe.
 

Anhänge

  • colormap.png
    colormap.png
    856 Bytes · Aufrufe: 30
Zurück