Forum: PC-Programmierung C# Bitmap in array und Anzeigen


von Anonymous U. (gastt)


Lesenswert?

Hallo Forum

Ich bin etwas am Verzweifeln. Habe schon viel C code für Mikrocontroller 
geschrieben. Jetzt wollte ich mit C# ein kleines PC-Programm erstellen. 
Ziel ist es die Pixel einer Tif-Datei in ein Array einzulesen, das Array 
verändern und das Ergebnis auf dem Bildschirm anzuzeigen.

Einiges funktioniert schon:
Tif einlesen - decodieren (in BitmapSource) - Pixelarray 
(eindimensional) da rausextrahieren (4 bytes/pixel) - Pixelarray 
(2dimensional) umsortieren (1 byte/pixel, nur sw/ws)

zur Anzeige:
Array in bitmap wandeln und auf picturebox ausgeben.

Mir kommt dies alles uuunglaublich umständlich vor. Ich frage mich: Geht 
das auch einfacher? Das ist doch eigentlich eine unglaublich einfache 
Problemstellung!

Hier ist mal meine Class zum umwandeln vom 2D-Array in ein bmp-dingens:
1
using System;
2
using System.Collections.Generic;
3
using System.Linq;
4
using System.Text;
5
using System.Threading.Tasks;
6
using System.IO;
7
using System.Windows;
8
using System.Drawing.Imaging;
9
using System.Drawing;
10
using System.Runtime.InteropServices;
11
12
13
namespace myProgram
14
{
15
    class rendering
16
    {
17
        // nimmt mein Objekt pixarray und macht daraus einen bmp stream
18
        internal static Image render(pixarray pixels)
19
        {
20
            // neues bitmap
21
            var b = new Bitmap(pixels.getsizeX(), pixels.getsizeY(), PixelFormat.Format8bppIndexed);
22
23
            // erstelle farbpalette
24
            ColorPalette ncp = b.Palette;
25
            for (int i = 0; i < 256; i++)
26
                ncp.Entries[i] = Color.FromArgb(255, i, i, i);
27
            b.Palette = ncp;
28
29
            // kopierter code, macht auch irgendwas
30
            var BoundsRect = new Rectangle(0, 0, pixels.getsizeX(), pixels.getsizeY());
31
            BitmapData bmpData = b.LockBits(BoundsRect,
32
                                            ImageLockMode.WriteOnly,
33
                                            b.PixelFormat);
34
35
            IntPtr ptr = bmpData.Scan0;
36
37
            // sortiert 2D-Array in 1D um
38
            int bytes = bmpData.Stride * b.Height;
39
            var rgbValues = new byte[bytes];
40
41
            for (int y = 0; y < pixels.getsizeY(); ++y)
42
            {
43
                for (int x = 0; x < pixels.getsizeX(); ++x)
44
                {
45
                    rgbValues[y * pixels.getsizeX() + x] = (byte)(255-pixels.getpix(x, y)*255);
46
                }
47
            }
48
49
            Marshal.Copy(rgbValues, 0, ptr, bytes);
50
            b.UnlockBits(bmpData);
51
            return b;
52
        }
53
    }
54
}

von Torsten C. (torsten_c) Benutzerseite


Lesenswert?

Eleganter ist es mit GetPixel und SetPixel, aber laaangsaaam.

Schneller geht es mit "unsafe":
https://msdn.microsoft.com/de-de/library/t2yzs44b.aspx

von Anonymous U. (gastt)


Lesenswert?

Sollte schon schnell gehen. Deine Idee wäre also das Tif in eine 
BmpSource umwandeln und die BmpSource so ausgeben, wie sie ist? Und zur 
schnellen bearbeitung von Pixeln per zeiger direkt auf die Source 
zugreifen?

von Torsten C. (torsten_c) Benutzerseite


Lesenswert?

Nein. Ich meinte nur, weil Du "uuunglaublich umständlich" schreibst.

Das ist halt der Preis für das Tempo:
LockBits und Marshal.Copy sind schneller als GetPixel und SetPixel.

Vielleicht bringt "unsafe" noch zusätzlich was.

Direkt per Pointer auf die BmpSource? Habe ich noch nicht gesehen, bin 
aber auch nicht der Experte. Falls es also jemand noch "schneller" weiß, 
lerne ich auch gern dazu.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.