Autor Beitrag
Laluna
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 28

Win XP
Delphi 2006
BeitragVerfasst: Do 03.05.07 12:53 
Hallo

ich habe ein 16bit tiff in Graustufen mit Hilfe der libTiffDelphi und einer gefundenen Funktion (siehe Code) eingelesen und als Bitmap umgewandelt und abgespeichert.

ausblenden Delphi-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:
function ReadTiffIntoBitmap(FileName: string): TBitmap;
var
 OpenTiff: PTiff;
 FirstPageWidth, FirstPageHeight:Cardinal;
 FirstPageBitmap: TBitmap;
begin
  OpenTiff:=TIFFOpen(Filename,'r');   // 'r' = reading
  if OpenTiff=nil then ShowMessage('Datei ' + Filename + ' kann nicht geöffent werden');
  TIFFGetField(OpenTiff,TIFFTAG_IMAGEWIDTH,@FirstPageWidth);
  TIFFGetField(OpenTiff,TIFFTAG_IMAGELENGTH,@FirstPageHeight);
  FirstPageBitmap:=nil;
  try
    FirstPageBitmap:=TBitmap.Create;
    FirstPageBitmap.PixelFormat:=pf32bit;
    FirstPageBitmap.Width:=FirstPageWidth;
    FirstPageBitmap.Height:=FirstPageHeight;
  except
    if FirstPageBitmap<>nil then FirstPageBitmap.Destroy;
    TIFFClose(OpenTiff);
    ShowMessage ('TBitmap Puffer konnte nicht erstellt werden');
  end;
  TIFFReadRGBAImage(OpenTiff,FirstPageWidth,FirstPageHeight,
               FirstPageBitmap.Scanline[FirstPageHeight-1],0);
  TIFFClose(OpenTiff);
  TIFFReadRGBAImageSwapRB(FirstPageWidth,FirstPageheight,
               FirstPageBitmap.Scanline[FirstPageHeight-1]);
  Result:=FirstPageBitmap;
  FirstPageBitmap.SaveToFile('Bitmap original.bmp');
end;


Meine Frage:
Soll ich das Bitmap auch als pf16bit und nicht als pf32bit wie im obigen Code abspeichern oder habe ich dann Datenverlust?
Sind im Bitmap auch nur Graustufen oder habe ich da pro Pixel drei Bytes (Rot,Blau,Grün)?
Was ich brauche ist der identische Graustufenwert, der auch im tiff gespeichert ist.

Vielen Dank!
Lossy eX
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1048
Erhaltene Danke: 4



BeitragVerfasst: Do 03.05.07 13:30 
Ich denke da muss man zwischen internem und externem Gebrauch unterscheiden.

Extern ist alles das was dein die Untiefen deines Programmes verlässt. Also Bildschirm, Festplatte etc. Dabei wirst du mit einem TBitmap nicht weit kommen. Denn BMPs können nur maximal 8 Bit pro Kanal haben. Das sind dann normal aber RGB mit 24 Bit. Ein 16 Bit BMP besitzt eines der folgenden Shemata. Rot (5 Bit) Grün (6 Bit) Blau (5 Bit) oder Rot (5 Bit) Grün (5 Bit) Blau (5 Bit) Das letzte Bit bleibt ungenutzt.

Intern ist alles was du für die Verarbeitung in deinem Programm benötigst. Also du ließt das TIFF ein und machst mit den Daten irgendwas. Dazu benötigst du ja richtige 16 Bit Werte.

Wenn es nur intern ist, dann kannst du ein Bitmap auch als pf16bit benutzen. Was du mit dem Speicher der Scanlines machst ist ja dir überlassen. Aber dann kannst du auch genau so gut einen eigenen Speicherbereich mit GetMem erstellen und dort alles reinpacken. Dann musst du dich wenigsten nicht mit der GDI rumschlagen. Da würde sich je nach dem auch eine kleine schlanke Klasse anbieten. Zum Darstellen müsstest du dann das Bild deine Daten wieder in ein TBitmap kopieren und die Daten auf 8 Bit runter rechnen.

Für Graustufen BMPs mit 8 Bit schau mal in dem Beitrag.

Sollte das deine Frage nicht beantworten dann wären ein paar Hintergrundinfos nicht schlecht. Also was du wie wo mit den 16 Bit Daten alles machen möchtest.

_________________
Nur die Menschheit ist arrogant genug, um zu glauben sie sei die einzige intelligente Lebensform im All. Wo nicht mal das nachhaltig bewiesen wurde.
Laluna Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 28

Win XP
Delphi 2006
BeitragVerfasst: Do 03.05.07 15:12 
Leider habe ich das nichts so ganz verstanden bzw. es beantwortet meine Frage nicht so richtig.
Hier ein paar Hintergrundinfos:

Ich lese aus einem Scanner ein tiff-Bild aus. Auf diesem Bild ist ein zweidimensionales Streubild abgebildet, was ich in eine eindimensionale Kurve umrechnen möchte. Der Ursprung dieser Kurve ist in jeder Pixelzeile immer der Punkt, der den höchsten Grauwert hat. Wenn ich den Grauwert habe, muss ich den dann in einem nächsten Schritt über die Scannerkennlinie (ist eine einfache Gleichung) in einen anderen Kennwert umrechnen.

Wie ich herausgefunden habe, ist es wohl einfacher bitmaps zu verarbeiten. Daher habe ich das tiff zunächst in ein Bitmap umgewandelt.
Mein tiff ist wie schon gesagt ein 16bit Graubild, d.h. wenn ich es richtig verstanden habe, hat jeder Pixel ein Grauwert zwischen 0 und 65536 und genau diese Werte möchte ich auslesen. Kann ich das auch so aus dem Bitmap? Oder ist da nicht jedem Pixel ein Wert zwischen 0 und 65536 zugeschrieben? Wie bekomme ich jetzt meinen Grauwert? (ScanLine....) ABER sind in meinem Bitmap überhaupt die Grauwerte gespeichert?
Gausi
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 8548
Erhaltene Danke: 477

Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
BeitragVerfasst: Do 03.05.07 15:29 
Ich glaube kaum, dass du tatsächlich ein 16Bit-Graustufen-Bild hast. Ein Graustufenbild hat in der Regel ne Farbtiefe von 8Bit (d.h. 256 Graustufen). Mehr kann das Auge auch nicht wirklich unterscheiden. In speziellen Anwendungen (z.B. der Medizin) nimmt man manchmal auch feinere Abstufungen - ich habe in dem Zusammenhang mal von 12Bit-Grauwertbildern gehört.

Frage also: Ist dein Tiff wirklich so fein strukturiert, oder ist das nur aufgebläht auf 16 Bit?

_________________
We are, we were and will not be.
Laluna Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 28

Win XP
Delphi 2006
BeitragVerfasst: Do 03.05.07 16:10 
Mein tiff ist wirklich so fein, ich habe Grauwerte von 0 bis 65536.
Das ist so fein, weil es in der Röntgentechnik eingesetzt wird und ich diese hohe Auflösung brauche.

Wenn ich es als bitmap abspeichere, dann habe ich Datenverlust, oder?
Ich brauche wirklich genau den gleichen Grauwert.

Wie ist das möglich????
Bin gerade am Verzweifeln.
Lossy eX
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1048
Erhaltene Danke: 4



BeitragVerfasst: Do 03.05.07 17:02 
Also dass du irgendwie am Verzweifeln bist merke ich. Denn du erzeugst gerade übel viele Beiträge mit dem selbem Inhalt. Es wäre nett, wenn du dich auf EIN Thema beschränkst.


Mit einem BMP wirst du nicht weiter kommen! Entweder du bleibst beim TIFF oder du musst dir etwas eigenes ausdenken. Die Datenhaltung deiner gelesenen Datei solltest du auch selber übernehmen. Also die Daten des TIFFs würde ich nicht in ein TBitmap lesen, da es nur über tricks überhaupt möglich ist. Du musst dir einen Speicherbereich geben lassen (GetMem) der Höhe * Breite * SizeOf(WORD) groß ist. Den Übergibst du beim Einlesen des TIFFs. Und wenn du dann auf einzelne Pixel zugreifen möchtest, dann musst du dir eben Berechnen wo du zugreifen musst.

Praktischerweise solltest du dieses Handling in eine Klasse packen, damit der Code übersichtlicher und strukturierter wird. Die Pointer auf die Anfänge einzelner Zeilen kannst du dir in einem Array ablegen und damit sollte der Zugriff schneller und einfacher werden. Den Zugriff würde ich nur über ein PWORD machen. Denn dann bekommst du genau einen vorzeichenlose 16 Bit Wert.

Abspeichern musst du das entweder wiederrum in einem TIFF oder du machst dir ein eigenes Format. Ein Header/Dateikennung (bei BMP ist das BM). Eine Höhe, Eine Breite und die Daten und mehr brauchste ja nicht.

Zur Darstellung dieses Bildes auf dem Bildschirm musst du es in ein Bitmap konvertieren. Dazu kannst du aber nur das obere Byte des WORDs benutzen. Und das musst du dann mittels Scanline in ein Bitmap kopieren. Wie du mit Scanline umzugehen hast wurde hier schon tausendfach gefragt und sa hilft die Suche.

_________________
Nur die Menschheit ist arrogant genug, um zu glauben sie sei die einzige intelligente Lebensform im All. Wo nicht mal das nachhaltig bewiesen wurde.