Laden...

32bit Bitmap in 16bit Bitmap umwandeln

Erstellt von S.R. vor 14 Jahren Letzter Beitrag vor 14 Jahren 4.234 Views
S
S.R. Themenstarter:in
221 Beiträge seit 2007
vor 14 Jahren
32bit Bitmap in 16bit Bitmap umwandeln

Hallo,

ich habe hier auf der Festplatte eine Grafik-Datei "test.bmp". Diese hat das Pixelformat "Format32bppArgb". Nun möchte ich ein neues Bitmap erstellen, allerdings mit dem Pixelformat "Format16bppArgb15555" und dann das ganze unter test2.bmp abspeichern.

Hat jemand von euch n' Idee wie ich dies gepacken bekomme? Stehe da was auf dem Schlauch und bin mit meinen Ansätzen am Ende 😃

Danke

Stefan

3.971 Beiträge seit 2006
vor 14 Jahren

Es gibt 3 Arten von Menschen, die die bis 3 zählen können und die, die es nicht können...

S
S.R. Themenstarter:in
221 Beiträge seit 2007
vor 14 Jahren

Hi,

vielen Dank für den Link. Habe schon gegoogeld - keine Sorge, aber leider nicht das gefunden, was ich gesucht habe. Habe den Code nun wie folgt stehen:

Bitmap bmp1 = (Bitmap.FromFile("d:\\test-1.bmp") as Bitmap);
Rectangle r = new Rectangle(0, 0, bmp1.Width, bmp1.Height);
Bitmap bmp = bmp1.Clone(r, PixelFormat.Format16bppArgb1555);
bmp.Save("d:\\te.bmp", ImageFormat.Bmp);

Jetzt müsste doch mein bmp eine 16-bit Bmp-Datei sein und dementsprechend deutlich kleiner (vom Speicherplatz her) als die original-Datei, oder? Dies ist allerdings nicht der Fall und daher frag ich mich - was mache ich falsch?

Hat jemandn n' Tipp auf Lager?

Dankend

Stefan

49.485 Beiträge seit 2005
vor 14 Jahren

Hallo S.R.,

vermutlich ist Encoder.ColorDepth ausschlaggebend. Den Encoder musst du beim Speichern (Bitmap.Save) angeben. Siehe JPEG-Dateigröße beeinflussen?!.

herbivore

S
S.R. Themenstarter:in
221 Beiträge seit 2007
vor 14 Jahren

Hi,

habe meinen Code nun wie folgt angepasst:

Bitmap bmp1 = (Bitmap.FromFile("d:\\test-1.bmp") as Bitmap);
  ImageCodecInfo myImageCodecInfo = GetEncoderInfo("image/bmp");
  System.Drawing.Imaging.Encoder myEncoder = System.Drawing.Imaging.Encoder.ColorDepth;

  EncoderParameters myEncoderParameters = new EncoderParameters(1);
  myEncoderParameters.Param[0] = new EncoderParameter(myEncoder, 16L);
  bmp1.Save("d:\\result.bmp", myImageCodecInfo, myEncoderParameters);

Leider ist das Ergebnis weiterhin, dass result.bmp genauso groß ist und die gleiche Auflösung hat wie test-1.bmp. Hat jemand einen weiteren Tipp auf LAger, was hier schief läuft?

Dankend

Stefan

S
401 Beiträge seit 2008
vor 14 Jahren

Servus,

ich habe da mal ne Frage. Welche Suchbegriff hast du bei Google eingegeben?
Google

Der letzte Link (zumindestens bei mir) dürfte für die Interessant sein. Ein kommpletes Beispiel, dass Funktionieren (ungetestet) sollte.

Orginal Code:


using System.Drawing;
using System.Drawing.Imaging;
using System.IO;

class Sample {

public void ConvertIcon() {


// Loading the original icon
Icon icon = new Icon("originalIcon.ico");

// Converting it to bitmap, to allow image manipulation
Bitmap bitmap = icon.ToBitmap();
   
// This rectangle has no meaning for us, it just has to encompass the entire image
Rectangle r = new Rectangle(0, 0, bitmap.Width, bitmap.Height);

// Using the clone method to convert the icon
Bitmap bmp = bitmap.Clone(r, PixelFormat.Format16bppArgb1555);

// And we claim back the icon (to retain the ico format) and save it.
icon = Icon.FromHandle(bmp.GetHicon());

FileStream stream = new FileStream("convertedIcon.ico", FileMode.Create);
icon.Save(stream);

stream.Close();
}
}
S
S.R. Themenstarter:in
221 Beiträge seit 2007
vor 14 Jahren

Hi,

das ist doch genau das Beispiel von meinem zweiten Post - bei mir halt ohne Kommentare und ohne die Icon-Umwandlung. Allerdings funktioniert das ganze bei mir nicht.

Daher bin ich immer noch auf der Suche nach einer Funktion, die das macht, was ich brauche.

Dankend

Stefan

S
401 Beiträge seit 2008
vor 14 Jahren

Ähmm, ja 🤔 Entschuldige

Leider habe ich zur Zeit kein Windows zur Hand. Kannst du mal ein Bild + das 16bit hochladen?

S
248 Beiträge seit 2008
vor 14 Jahren

Hallo S.R.,

Leider ist das Ergebnis weiterhin, dass result.bmp genauso groß ist und die gleiche Auflösung hat wie test-1.bmp. Hat jemand einen weiteren Tipp auf LAger, was hier schief läuft?

Bei mir liefert die Clone Methode schon ein 32-bit Bild zurück. Von daher ist es nur logisch, dass die Datei dann auch 32-bit ist.

Du könntest diese Methode verwenden:

public static Bitmap ConvertBitmap(Bitmap bitmap, PixelFormat format)
{
    if (bitmap == null)
    {
        throw new ArgumentNullException("bitmap");
    }

    Bitmap result = null;
    try
    {
        Rectangle rect = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
        result = new Bitmap(bitmap.Width, bitmap.Height, format);

        BitmapData dstData = result.LockBits(rect, ImageLockMode.WriteOnly, format);
        try
        {
            BitmapData srcData = new BitmapData();
            srcData.Scan0 = dstData.Scan0;
            srcData.Stride = dstData.Stride;

            bitmap.LockBits(rect, ImageLockMode.ReadOnly | ImageLockMode.UserInputBuffer, format, srcData);
            bitmap.UnlockBits(srcData);
        }
        finally
        {
            result.UnlockBits(dstData);
        }
    }
    catch
    {
        if (result != null)
        {
            result.Dispose();
        }
        throw;
    }
    return result;
}

Dabei solltest du jedoch beachten, dass GDI+ bzw .NET kein Format16bppArgb1555 unterstützen. D.h. du musst dich mit Format16bppRgb555 oder Format16bppRgb565 begnügen.

Spooky

Edit: Methode geändert, sodass keine 3. temporäre Bitmap erzeugt wird. So schreibt die eine Bitmap die Pixeldaten direkt in die andere.

S
401 Beiträge seit 2008
vor 14 Jahren

Servus,

Frage an Microsoft, wieso gibt es ein PixelFormat? Wenn die Einstellungen ignoriert werden! Bei nicht Unterstützung würde ich eine Exception erwarten!!!

S
S.R. Themenstarter:in
221 Beiträge seit 2007
vor 14 Jahren

Hi,

@Siassei:
genauso sehe ich das auch. Das muss einfach n' Bug sein 😃

@Spook:
Klappt reibungslos! Vielen Dank dafür.

Damit hätten wir schon wieder eine Sorge weniger.

Bis demnächst...

Stefan