Autor Beitrag
Sven Bauermann
Hält's aus hier
Beiträge: 8



BeitragVerfasst: Mo 14.11.11 17:21 
Hallo liebe Gemeinde.
Ich bin neu hier und hoffe, dass jemand eine Erklärung für mein Problem hat. Ich werde mich bemühen, dass Board mit nützlichen Beiträgen zu füllen, wenn ich etwas beisteuern kann.


Einleitung:
Aus einem ANSI NIST File (Biometric Standard - ist aber hier nicht von Bedeutung),
werden aus einem binären Bytebereich, Datenfelder ausgelesen.

So z.B. liegt ab der Bytestelle 13 bis 62512 ein Bild.
Durch die Spezifikation des Filestandards, wird ein 1000 x 500 Pixel großes Bild,
mit einer Auflösung von 500ppi erwartet (Auflösung hier aber uninteressant).
Der Ursprung des Bildes ist ein Signaturpad oder gescanntes Bild.
8 Pixel wurden in ein byte gepackt. Das Bild ist unkomprimiert.
Es handelt sich also um ein Black and White Bild.
Das Bild ist exakt 62500 byte groß. Bei 8 Pixel für ein byte, steht jedes Bit für ein Pixel
als 62500 x 8 = 500.000 Pixel. Völlig korrekt bis hier. Leider liefert
der aus meiner Sicht korrekt Code ein Bild mit weißen Hintergrund und
einigen schön verteilten schwarzen Strichen, keine Unterschrift.

Ich habe ausgeschlossen, dass es sich bei den BitmapData Werten um
Schrott handelt. Ich habe mit einem Freeware Nistviewer (Cognaxon), das
File geöffnet und die Unterschrift ordentlich dargestellt.Lediglich der
Hintergrund ist schwarz und die Schrift weiß. Das Unterschirften Bild ist bei dem Freeware Tool zwar invertiert aber ansonsten ok.
Ich habe keine Idee wieso, das bei meinem Versuch nicht so ist. Ich schicke das 62500k große Bytearray in die Welt ein Bitmap zu werden und wähle natürlich für FormatPixel.Format1bppIndexed. Bin ratlos.

Vielen Dank für Ideen und Hilfe
Gruß Sven

Hier mein Code:

Aufruf:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
XImage = CopyDataToBitmap(rawdata, _HLL, _VLL, PixelFormat.Format1bppIndexed);

protected Bitmap CopyDataToBitmap(byte[] data, int pWidth, int pHeight, PixelFormat pPix)
{
    //here create the bitmap to the know height, width and format
    Bitmap bmp = new Bitmap(pWidth, pHeight, pPix);
    //bmp.SetResolution(500.0F, 500.0F);

    //create a bitmapdata and lock all pixel to be written
    BitmapData bmpData = bmp.LockBits(new Rectangle(00, bmp.Width, bmp.Height), 
                                      ImageLockMode.WriteOnly, bmp.PixelFormat);

    //Copy the data from the byte array into BitmapData.Scan0
    Marshal.Copy(data, 0, bmpData.Scan0, data.Length);

    //unlock the pixel
    bmp.UnlockBits(bmpData);

    bmp.Save(@"C:\Sigantur.bmp",ImageFormat.Bmp);

    //return the bitmap
    return bmp;
}


Moderiert von user profile iconTh69: C#-Tags hinzugefügt
Sven Bauermann Threadstarter
Hält's aus hier
Beiträge: 8



BeitragVerfasst: Di 29.11.11 12:24 
Die Lösung für dieses Problem:

FormatPixel.Format1bppIndexed ist hierfür nicht geeignet. Windows arbeit ja mit RGB Farben.

Es ist notwenig, selbststänig das gesamten Byte Array durchzugehen und in den byte die 8 - bit Werte auszulesen.
Achtung in diesen Fall aber Rückwärts die bits auslesen. Jedes Bit ergibt einen Schwarz oder Weiß Wert und ist dann entsprechend pro bit in ein 3 byte RGB Wert umzusetzen.

Also: byte[1] = 01010110 = 0 (255 255 255), 1 (0 0 0 ), 1 (0 0 0) usw.

Daraus ergibt sich ein 1 500 000 Byte Array aus dem dann ein Bitmap erstellt werden kann.

Sven
pdelvo
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 55
Erhaltene Danke: 11



BeitragVerfasst: Di 29.11.11 16:33 
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
        public byte[] BitToRGB(byte[] input)
        {
            byte[] result = new byte[input.Length * 8 * 3];//8 pixels per byte, 3 bytes per pixel

            byte[] white = new byte[] { 255255255 };
            byte[] black = new byte[] { 000 };

            for (int i = 0; i < input.Length; i++)
            {
                for (int j = 0; j < 8; j++)
                {
                    Buffer.BlockCopy(CheckFlag(input[i], j) ? white : black, 0, result, ((i * 8) + j) * 33);
                }
            }
            return result;
        }

        public bool CheckFlag(byte b, int index)
        {
            return (b & (1 << index)) != 0;
        }


Dann natürlich als Format 24 bit rgb nehmen. Ob es funktioniert weiss ich nicht, kenne das Format nicht und habs nicht getestet und schnell hier reingeschrieben. Einfach mal ausprobieren