Autor Beitrag
Rassi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 79



BeitragVerfasst: Mi 02.09.09 17:20 
Hallo.

Ich möchte das Image einer PictureBox abspeichern.
ausblenden C#-Quelltext
1:
pictureBox1.Image.Save(textBox1.Text, System.Drawing.Imaging.ImageFormat.Jpeg);					

Dieses Image hat eine Farbtiefe von 24Bit.
Gespeichert werden soll es aber mit 8-Bit.
Wie mache ich das?

Gruß
Rasmus
Christian S.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 20451
Erhaltene Danke: 2264

Win 10
C# (VS 2019)
BeitragVerfasst: Mi 02.09.09 17:52 
Du willst also ein Graustufenbild haben?

_________________
Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".
Rassi Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 79



BeitragVerfasst: Mi 02.09.09 17:56 
Hallo.
Ja, so ist es.
Das Umwandeln in Graustufen, habe ich auch schon.
Wichtig ist, dass das Bild mit einer Farbtiefe von 8-Bit gespeichert wird.
Wenn ich es, wie oben gezeigt, abspeichere, wird immer ein Bild mit einer Bittiefe von 24Bit gespeichert (Dateiinfo, siehe Anhang).
Ich brauche aber 8-Bit.

Gruß
Rasmus
Einloggen, um Attachments anzusehen!
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4798
Erhaltene Danke: 1059

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Do 03.09.09 11:25 
Ich denke, dafür wirst du ein neues Bitmap erstellen müssen, welche das entsprechende PixelFormat (Format8bppIndexed) hat und dann die Daten kopieren.
Als Konstruktor dafür müßte
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
public Bitmap(
    int width,
    int height,
    int stride,
    PixelFormat format,
    IntPtr scan0
)

s.a. msdn.microsoft.com/e...ibrary/zy1a2d14.aspx gehen.
Und anschließend noch die Palette anpassen.

An die Pixel-Daten kommst du mittels Bitmap.LockBits().Scan0 (ich nehme an, dein Image ist eine Bitmap).

Und dann für das neue Bitmap Save(..., ImageFormat.Jpeg) aufrufen.
Rassi Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 79



BeitragVerfasst: Fr 04.09.09 10:01 
Hallo.
Danke für den Tip.
@Th69:
Ich habe im Netz folgende Funktion gefunden. Diese stützt sich auf deine Tips.
ausblenden volle Höhe 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:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
public static Bitmap ConvertBitmap(Bitmap bitmap, PixelFormat format)
        {
            if (bitmap == null)
            {
                throw new ArgumentNullException("bitmap");
            }

            Bitmap result = null;
            try
            {
                //Größe des Quell-Bitmap ermitteln.
                Rectangle rect = new Rectangle(00, bitmap.Width, bitmap.Height);

                //Ziel-Bitmap in dem gewünschten Pixel-Format erstellen.
                result = new Bitmap(bitmap.Width, bitmap.Height, format);

                //Das Ziel-Bitmap im Speicher sperren. An dstDate die Sperr-Informationen übergeben.
                BitmapData dstData = result.LockBits(rect, ImageLockMode.WriteOnly, format);
                try
                {
                    //Neues BitmapData erzeugen.
                    BitmapData srcData = new BitmapData();

                    //Adresse der ersten Pixeldaten umkopieren.
                    srcData.Scan0 = dstData.Scan0;

                    //Schrittbreite des Bitmaps umkopieren.
                    srcData.Stride = dstData.Stride;

                    //Das Quell-Bitmap im Speicher sperren. Sperrinformationen von srcData (Ziel-Bitmap) weitergeben.
                    bitmap.LockBits(rect, ImageLockMode.ReadOnly | ImageLockMode.UserInputBuffer, format, srcData);

                    //Sperrung des Quell-Bitmaps aufheben.
                    bitmap.UnlockBits(srcData);

                }
                finally
                {
                    ////Sperrung des Ziel-Bitmaps aufheben.
                    result.UnlockBits(dstData);
                }
            }
            catch
            {
                if (result != null)
                {
                    result.Dispose();
                }
                //                throw;
            }
            return result;
        }


Nur wird ein Fehler in der Codezeile 25 ausgelöst (Es wurde versucht, im geschützten Speicher zu lesen oder zu schreiben. Dies ist häufig ein Hinweis darauf, dass anderer Speicher beschädigt ist.):
ausblenden C#-Quelltext
1:
bitmap.LockBits(rect, ImageLockMode.ReadOnly | ImageLockMode.UserInputBuffer, format, srcData);					



Die Funktion rufe ich wie folgt auf:
ausblenden C#-Quelltext
1:
Bitmap Bild_neu = ConvertBitmap(Bild_original, PixelFormat.Format8bppIndexed);					

Hierbei ist das Pixelformat von Bild_original = Format32bppPArgb.


Könnt ihr mir helfen, diese Funktion so hinzubekommen, dass es funktioniert?

Ich habe mal Kommentare dazugeschrieben. Völlig offen für mich ist, wie das Quell-Bitmap zum Ziel-Bitmap kopiert wird. Das wird sicherlich genau in der Zeile 25 gemacht. Kann mir das jemand erklären?


Gruß
Rasmus
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4798
Erhaltene Danke: 1059

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Fr 04.09.09 19:45 
Hallo Rasmus,

den Code hast du von mycsharp.de (www.mycsharp.de/wbb2...d.php?threadid=74364), oder?

Warum der Code bei dir eine Exception wirft, weiß ich nicht genau, evtl. wegen der Umwandlung von einem RGB-Bild zu einem Palettenbild. Du verwendest doch jetzt Format8bppIndexed?

Evtl. ist es aber noch einfacher, indem du die Clone-Methode (msdn.microsoft.com/d...ibrary/ms141944.aspx) aufrufst, d.h.
ausblenden C#-Quelltext
1:
2:
3:
4:
Rectangle rect = new Rectangle(00, bitmap.Width, bitmap.Height);
Bitmap result = bitmap.Clone(rect, PixelFormat.Format8bppIndexed);

result.Save(...);

Dann brauchst du nicht von Hand mit dem BitmapData-Objekt rumhantieren.

Ich hoffe, es klappt jetzt...