Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Delphi Bitmap: falsche Farben (https://www.delphipraxis.net/81014-bitmap-falsche-farben.html)

Sko 19. Nov 2006 09:01


Bitmap: falsche Farben
 
Liste der Anhänge anzeigen (Anzahl: 2)
Hallo,

ich hab mit meinem JPG-Kompressor mal meinen Guild Wars-Screenshotordner geöffnet. Dieses Spiel speichert Screenshots als Bitmap. Die Bitmaps werden aber in falschen Farben angezeigt. Andere Bitmaps (z.B. von Paint) werden aber richtig angezeigt.
Wenn ich diese Guild-Wars-Bitmaps mit einem anderen Grafikprogramm öffne werden sie auch richtig angezeigt, daher denke ich das der Fehler in meinem Programm liegt.
Die Bitmaps werden in normale Images und in Image32 geladen, daher kanns imho nicht an der Image-Komponente liegen.
Im Anhang mal 2 Bilder - richtig und falsch.

Ich hoffe ihr könnt mir helfen.

SirThornberry 19. Nov 2006 10:05

Re: Bitmap: falsche Farben
 
sieht aus als wären sie in einem Druckformat (nicht rgb).

Der_Unwissende 19. Nov 2006 10:07

Re: Bitmap: falsche Farben
 
Hi,
die Farben sind vertauscht (ok, dass siehst du ja). Du musst hier von deiner RGB Belegung in eine BRG Belegung umwandeln, dann sieht wieder alles richtig aus. Warum der das falsch macht weiß ich nicht.

Sko 19. Nov 2006 13:58

Re: Bitmap: falsche Farben
 
Zitat:

Zitat von Der_Unwissende
Hi,
die Farben sind vertauscht (ok, dass siehst du ja). Du musst hier von deiner RGB Belegung in eine BRG Belegung umwandeln, dann sieht wieder alles richtig aus. Warum der das falsch macht weiß ich nicht.

Ja, das hab ich gesehen, das Problem ist jetzt, wie soll ich erkennen ob ein Bild nun RGB, BRG oder sonstwas ist?

[Edit]Ich bin bis Mittwoch weg und weis nicht ob ich da Internet hab, nicht wundern wenn ich nicht gleich antworte[/Edit]

Sko 21. Nov 2006 10:30

Re: Bitmap: falsche Farben
 
*push*
hat keiner ne lösung?

OldGrumpy 21. Nov 2006 10:33

Re: Bitmap: falsche Farben
 
Kannst du das Bild von dem der Screenshot stammt mal hier anhängen? Dann würd ich mal in den Jpg-Header schauen.

Sko 21. Nov 2006 11:37

Re: Bitmap: falsche Farben
 
das Original ist ein Bitmap, ich werds zuhause mal packen und hochladen

Sko 21. Nov 2006 18:02

Re: Bitmap: falsche Farben
 
Liste der Anhänge anzeigen (Anzahl: 1)
So, hier ist das Originalbild, ist leider trotz Packen etwas groß.

Phantom1 21. Nov 2006 22:21

Re: Bitmap: falsche Farben
 
Ich hab mir mal dein Bitmap angeschaut und die Header sind eigentlich korrekt und auch die Farbwerte sind richtig abgespeichert in RGB, aber Delphi beachtet offenbar nicht die bfOffBits im TBitmapFileHeader. Denn zwischen dem TBitmapInfoHeader und den Farbdaten liegen bei deinem Bitmap noch 2 leere Bytes. Diese 2 Byte liest Delphi als Farbdaten ein, wodurch der fehler entsteht.

Du hast jetzt mehrere möglichkeiten: Du schreibst dir eine eigene Prozedur zum einlesen des Bitmaps oder du änderst die Bitmaps indem du die 2 leeren Bytes entfernst bevor sie in Delphi eingelesen werden. Die 2te möglichkeit (das entfernen der leeren Bytes) habe ich mal übernommen, hier der Code:
Delphi-Quellcode:
procedure BitmapVerify(FileName: TFileName);
var
  fs: TFileStream;
  fh: TBitmapFileHeader;
  ih: TBitmapInfoHeader;
  Offset: DWORD;
  Buffer: Pointer;
begin
  fs:=TFileStream.Create(FileName, fmOpenReadWrite);
  try
    fs.Position:=0;
    fs.ReadBuffer(fh, SizeOf(fh));
    fs.ReadBuffer(ih, SizeOf(ih));
    Offset:=fh.bfOffBits-(SizeOf(TBitmapFileHeader)+SizeOf(TBitmapInfoHeader));
    if Offset>0 then begin
      GetMem(Buffer, ih.biSizeImage);
      try
        fs.Position:=fh.bfOffBits;
        fs.ReadBuffer(Buffer^, ih.biSizeImage);
        fh.bfSize:=fh.bfSize-Offset;
        fh.bfOffBits:=fh.bfOffBits-Offset;
        fs.Position:=0;
        fs.WriteBuffer(fh, SizeOf(fh));
        fs.Position:=fh.bfOffBits;
        fs.WriteBuffer(Buffer^, ih.biSizeImage);
        fs.Size:=fh.bfSize;
      finally
        FreeMem(Buffer, ih.biSizeImage);
      end;
    end;
  finally
    fs.Free;
  end;
end;
mfg

Sko 21. Nov 2006 22:34

Re: Bitmap: falsche Farben
 
Wow, vielen Dank, funktioniert super *freu* :thumb:

OldGrumpy 21. Nov 2006 23:02

Re: Bitmap: falsche Farben
 
Tjo, da war jemand schneller :) Ich hatte mir schon was in der Richtung gedacht, ich hatte mal ein ähnliches Phänomen mit WAV-Files. Da war der Header nicht wie üblich 44 sondern 46 Bytes gross. Im Header stand zwar die richtige Größe, aber der WAV-Reader setzte 44 Bytes fix voraus, so dass dann die Filegröße nicht passte, da die 2 Bytes als Sample gelesen wurden, dem dann sein Pendant für den andern Kanal fehlte. Böse Falle :)

Sko 21. Nov 2006 23:36

Re: Bitmap: falsche Farben
 
Ich versuch grad daraus eine Prozedur zum Einlesen der Bitmaps zu bauen, damit die Quelldateien nicht verändert werden, aber das ist doch nicht so einfach wie ich dachte. Na mal sehen :coder2:

Phantom1 22. Nov 2006 09:05

Re: Bitmap: falsche Farben
 
OK, bin ich mal nicht so:

Delphi-Quellcode:
function LoadBitmap24(FileName: TFileName; var Bmp: TBitmap): Boolean;
var
  fs: TFileStream;
  fh: TBitmapFileHeader;
  ih: TBitmapInfoHeader;
begin
  Result:=False;
  fs:=TFileStream.Create(FileName, fmOpenRead);
  try
    fs.Position:=0;
    fs.ReadBuffer(fh, SizeOf(fh));
    fs.ReadBuffer(ih, SizeOf(ih));
    if ih.biBitCount=24 then begin
      fs.Position:=fh.bfOffBits;
      Bmp.Width:=ih.biWidth;
      Bmp.Height:=ih.biHeight;
      Bmp.PixelFormat:=pf24bit;
      fs.ReadBuffer(Bmp.ScanLine[Bmp.Height-1]^, ih.biSizeImage);
      Result:=True;
    end;
  finally
    fs.Free;
  end;
end;
diese function geht nur bei 24bit Bitmaps, man kann das jedoch noch für andere Farbtiefen anpassen.

mfg

Sko 22. Nov 2006 10:50

Re: Bitmap: falsche Farben
 
Hallo, danke, ich hab auch was gebastelt, was auf dem ersten Code basiert, war doch einfacher als gedacht, ich hatte nur vergessen die Position des Streams auf 0 zu setzen vor dem Laden :oops:

Das sieht so aus:
Delphi-Quellcode:
unit BMPLaden;

interface

uses Windows, Classes, SysUtils, GR32, Graphics;

procedure BitmapLaden(Datei: TFileName; Bitmap: TBitmap); overload;
procedure BitmapLaden(Datei: TFileName; Bitmap: TBitmap32); overload;

implementation

function BitmapVerify(FileName: TFileName): TMemoryStream;
var
  fh: TBitmapFileHeader;
  ih: TBitmapInfoHeader;
  Offset: DWORD;
  Buffer: Pointer;
begin
  result := TMemoryStream.Create;
  result.LoadFromFile(FileName);
  try
    result.Position:=0;
    result.ReadBuffer(fh, SizeOf(fh));
    result.ReadBuffer(ih, SizeOf(ih));
    Offset:=fh.bfOffBits-(SizeOf(TBitmapFileHeader)+SizeOf(TBitmapInfoHeader));
    if Offset>0 then begin
      GetMem(Buffer, ih.biSizeImage);
      try
        result.Position:=fh.bfOffBits;
        result.ReadBuffer(Buffer^, ih.biSizeImage);
        fh.bfSize:=fh.bfSize-Offset;
        fh.bfOffBits:=fh.bfOffBits-Offset;
        result.Position:=0;
        result.WriteBuffer(fh, SizeOf(fh));
        result.Position:=fh.bfOffBits;
        result.WriteBuffer(Buffer^, ih.biSizeImage);
        result.Size:=fh.bfSize;
      finally
        FreeMem(Buffer, ih.biSizeImage);
      end;
    end;
  finally
    result.Position := 0; //<---hatte ich vergessen^^
  end;
end;


procedure BitmapLaden(Datei: TFileName; Bitmap: TBitmap);
var
  BitmStream: TMemoryStream;
begin
  BitmStream := BitmapVerify(Datei);
  Bitmap.LoadFromStream(BitmStream);
  FreeAndNil(BitmStream);
end;

procedure BitmapLaden(Datei: TFileName; Bitmap: TBitmap32);
var
  BitmStream: TMemoryStream;
begin
  BitmStream := BitmapVerify(Datei);
  Bitmap.LoadFromStream(BitmStream);
  FreeAndNil(BitmStream);
end;

end.
Ich hab das noch nicht mit anderen Bitmaps testen können, weil ich keine Bitmaps mit weniger als 24 bit habe bei denen das Problem auftaucht.

Vielen Dank nochmal für deine Hilfe :thumb:

Phantom1 22. Nov 2006 11:37

Re: Bitmap: falsche Farben
 
@Sko: Ja so kann man es auch machen. Ich weiß jetzt nicht ob dir die Ladegeschwindigkeit wichtig ist? denn bei deinem code werden unnötige kopiervorgänge im speicher durchgeführt, das habe ich bei meinem code LoadBitmap24 vermieden :zwinker:

mfg

Sko 22. Nov 2006 12:13

Re: Bitmap: falsche Farben
 
Hmm, ich erstelle auch Thumbs damit, also wäre etwas schneller auch nicht schlecht... aber da müsste ich vor dem Laden mit deiner Funktion Herausfinden wieviel Bit das Bitmap hat, und dafür müsste ich es ja wieder in einen Stream laden um das auszulesen, bevor ich´s mit deiner Funktion laden kann, oder? :gruebel:

[Edit]und mit Bitmap32 musses auch gehen und da hab ich kein Pixelformat :gruebel: [/Edit]

[Edit2]Ok, das mit den Bits hat sich erledigt, habs übersehen, das steht ja da:
Delphi-Quellcode:
if ih.biBitCount=24 then begin
...
[/Edit2]

Phantom1 22. Nov 2006 13:09

Re: Bitmap: falsche Farben
 
Für TBitmap32 könnte es so aussehen:
Delphi-Quellcode:
function LoadBitmap32(FileName: TFileName; var Bmp32: TBitmap32): Boolean;
var
  Bmp24: TBitmap;
begin
  Bmp24:=TBitmap.Create;
  try
    LoadBitmap24(FileName, Bmp24);
    Bmp32.Assign(Bmp24);
  finally
    Bmp24.Free;
  end;
end;
Habs zwar nicht getestet, aber müsste gehen.

mfg

Sko 22. Nov 2006 13:43

Re: Bitmap: falsche Farben
 
Stimmt, danke, ich hab mal wieder zu kompliziert gedacht :wink:

Sko 3. Dez 2006 13:00

Re: Bitmap: falsche Farben
 
hier noch die ein-Zeilen-Variante :wink: , danke Sunlight7 :thumb:


Alle Zeitangaben in WEZ +1. Es ist jetzt 19:12 Uhr.

Powered by vBulletin® Copyright ©2000 - 2022, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2021 by Daniel R. Wolf