Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Delphi 8bit Graustufenbild kopieren mit hilfe von Scanline (https://www.delphipraxis.net/66333-8bit-graustufenbild-kopieren-mit-hilfe-von-scanline.html)

vsh 28. Mär 2006 15:44


8bit Graustufenbild kopieren mit hilfe von Scanline
 
Hallo,

ziel einer procedure ist es zwei bilder mit scanline zu kopieren, was auch sehr gut funktioniert, wenn ich bei beiden bildern zuvor das PixelFormat:=pf24bit setze. Direkt vor dem Abspeichern setzte ich das PixelFormat wieder auf 8bit.

Soweit so gut, aber das Problem ist, dass die Konvertierung auf 24bit prinzipiell sinnlos ist, da sowohl quellebild als auch zielbild nur 8bit haben sollen. jedoch scheint "scanline" nur bei 24bit bildern so richtig zu funktionieren, denn wenn ich scanline auf ein 8bit-Bild anwende und im anschluss das PbyteArray nur bis pic.width (anstelle 3*pic.width wie bei 24bit) durchlaufe und abspeicher kommen total verrückte (ua bunte) Bilder heraus.

In Hoffnung auf Klärung...

vsh

Der_Unwissende 28. Mär 2006 15:51

Re: 8bit Graustufenbild kopieren mit hilfe von Scanline
 
Hi,
8Bit Bitmaps arbeiten einfach gerne mit Farbpaletten. Hier speicherst du einfach <= 256 verschiedene Farben. Wenn du nun das Bitmap lädst, dann werden die einzelnen Byte Werte als Index auf diese Farbtabelle interpretiert und die entsprechenden Farben gesetzt.
Genau genommen besteht deine Bitmap aus zwei Teilen, einer Infostruktur (z.b. ob es sich um eine Farbpalette handelt, die benutzt wird, kompremierung, Größe,..) und den Rohdaten (die du per Scanline abgreifst.
Eine TBitmap stellt dir nur eine Vereinigung dieser Daten zur Verfügung

Gruß Der Unwissende

vsh 28. Mär 2006 16:05

Re: 8bit Graustufenbild kopieren mit hilfe von Scanline
 
hmm, bei 24bit bildern liefert mir der Scanline Befehl (8bit-blau, 8bit-grün, 8bit-rot) sodass ich am Ende die Dreifache Datenmenge meines 8bit Bildes habe.
Wenn ich mein 8Bit Graustufenbild in 24Bit wandle (per PixelFormat), dann dachte ich, es passiert intern nichts anderes, als dass er den Wert des ersten Byte in die 2 neuen Byte schreibt, sodass man am Bild keine Veränderung SEHEN kann. denke ich zumindest.

ich weiss aber nicht, was mir scanline liefert. denn wenn es einfach nur pixelweise ausliest, dann muesste es doch auch bei 8bit gehen, denn ob das byte der grün-wert, oder der nächste Pixel ist, liegt doch nicht am scanline, sondern an der interpretation durch das bildformat, oder?

auf die aussage hin, dass man auch bei 256 werten farbe dabei hat, wie ist die zuordnung? 1-20 rottöne, 21-40 gelb.... ?

vsh 28. Mär 2006 16:12

Re: 8bit Graustufenbild kopieren mit hilfe von Scanline
 
hier der code um den es geht. entscheidend ist die innere for-schleife (i läuft), wo ich 3 zuweisungen machen muss, obwohl eine ausreichend wäre, bei 8bit.


Delphi-Quellcode:
for k:=1 to anzslices do
  begin
    SlicePic.PixelFormat:=pf24bit;
    for l:=1 to anzpulse do
    begin
      TempPic.LoadFromFile(ImgPfad+'Img'+inttostr(l)+'.bmp');
      TempPic.PixelFormat:=pf24bit;
      zeile:=TempPic.ScanLine[k-1];
      zeile2:=SlicePic.ScanLine[l-1];
      for i:=0 to TempPic.width-1 do
      begin
        zeile2^[3*i]:=zeile^[3*i];
        zeile2^[3*i+1]:=zeile^[3*i+1];
        zeile2^[3*i+2]:=zeile^[3*i+2];
      end;
     end;
    SlicePic.PixelFormat:=pf8bit;
    SlicePic.SaveToFile(ImgPfad+'SliceImg'+inttostr(k)+'.bmp');
   end;

Muetze1 28. Mär 2006 21:00

Re: 8bit Graustufenbild kopieren mit hilfe von Scanline
 
a) Du kannst die Bitmaps eigentlich auch einfach per Dateioperation kopieren.

Delphi-Quellcode:
FileCopy(PChar(ImgPfad+'Img'+inttostr(l)+'.bmp'), PChar(ImgPfad+'SliceImg'+inttostr(k)+'.bmp'));
b) Du kannst das Bild auch mit Assign() auf eine andere TBitmap Instanz übertragen lassen.

Delphi-Quellcode:
TempPic.LoadFromFile(ImgPfad+'Img'+inttostr(l)+'.bmp');
SlicePic.Assign(TempPic);
SlicePic.SaveToFile(ImgPfad+'SliceImg'+inttostr(k)+'.bmp');
c) Du hast bei einem PixelFormat von kleiner gleich pf8Bit eine Farbpalette (wie zuvor schon geschrieben). Die ScanLine Daten enthalten keine direkt RGB Farbinformationen mehr!! Die ScanLine Daten ergeben dabei nur einen Index - d.h. welcher Farbe aus der Farbtabelle für den Pixel genommen werden soll. Du musst also neben den Daten auch die Farbtabelle mit kopieren.

Delphi-Quellcode:
for k:=1 to anzslices do
  begin
    for l:=1 to anzpulse do
    begin
      TempPic.LoadFromFile(ImgPfad+'Img'+inttostr(l)+'.bmp');
      zeile:=TempPic.ScanLine[k-1];
      zeile2:=SlicePic.ScanLine[l-1];
      for i:=0 to TempPic.width-1 do
        zeile2^[i] := zeile^[i];
     end;
    SlicePic.Palette := CopyPalette(TempPic.Palette);
    SlicePic.SaveToFile(ImgPfad+'SliceImg'+inttostr(k)+'.bmp');
   end;

vsh 28. Mär 2006 23:16

Re: 8bit Graustufenbild kopieren mit hilfe von Scanline
 
also a) und b) scheiden leider sofort aus, da es ja kein reines kopieren ist, sondern ich aus mehreren Bitmaps immer die gleiche Zeile auslese und zu einem Neuen Bild zusammensetze um sozusagen einen Schnitt zu erzeugen. Daher ist es kein reines Dateikopieren sondern nur ein Kopieren von Bildabschnitten, wodurch ich wieder bei Pixels[] oder Scanline bin und dann eben das bisher beschriebene Problem hatte.
Punkt c) klingt sehr interessant und ich werde es gleich morgen testen und anschliessend einen Status-Bericht abgeben.


Alle Zeitangaben in WEZ +1. Es ist jetzt 00:39 Uhr.

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