Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Delphi Nicht-weißen-Bereich ausschneiden (https://www.delphipraxis.net/113778-nicht-weissen-bereich-ausschneiden.html)

Flips 14. Mai 2008 15:55


Nicht-weißen-Bereich ausschneiden
 
Liste der Anhänge anzeigen (Anzahl: 2)
Hi.
Mit folgender Procedure wollte ich aus einem Bild den "nicht-weißen"-Bereich ausschneiden. Das Beispiel verdeutlicht das hoffentlich.
Delphi-Quellcode:
//Aufruf im Bsp: ArrangeSymbol(buf); buf -> Bitmap
procedure ArrangeSymbol(aSource: TBitmap; Width: Integer = -1;Height : Integer = -1;threshold: Byte = 254);
var h,w : integer;
b : ^TRGBTriple;
start, last : TPoint;
buffer : TBitmap;
begin
last.X := 0;
last.Y := 0;
start.X := 1000;
start.Y := 1000;
buffer := TBitmap.Create;
try
  buffer.Assign(aSource);
  for h := 0 to buffer.Height -1 do
    begin
      b := buffer.ScanLine[h];
      for w := 0 to buffer.Width -1 do
        begin
          if (b^.rgbtBlue <= threshold) and (b^.rgbtRed <= threshold) and (b^.rgbtGreen <= threshold) then
            begin
              if w < start.X then
                start.X := w;
              if h < start.Y then
                start.Y := h;
              if w > last.X then
                last.X := w;
              if h > last.Y then
                last.Y := h;
            end;

          inc(b);
        end;
    end;
  //Bild soll nur so groß sein, wie auch der Bereich ist -> SIEHE BEISPIEL
  if (Width = -1) or (Height = -1) then
    begin
      aSource.Width := abs(last.X-start.X);
      aSource.Height := abs(last.Y-start.Y);
    end
  //Bild soll vorgegebene Größe haben
  else
    begin
      aSource.Width := Width;
      aSource.Height := Height;
    end;
  aSource.Canvas.FillRect(aSource.Canvas.ClipRect);
  BitBlt(aSource.Canvas.Handle,0,0,aSource.Width,aSource.Height,buffer.Canvas.Handle,start.X,start.Y,SRCCOPY);
  finally
    buffer.Free;
  end;
end;
Wieso geht das nicht / wieso siehts so aus wie im Beispiel?
In Beispiel 2 sieht man deutlich, dass er (wie in Beispiel 1) zu viel kopiert. Wieso?

Phantom1 14. Mai 2008 17:57

Re: Nicht-weißen-Bereich ausschneiden
 
Den einzigsten fehler den ich gefunden habe ist hier zu finden:

Delphi-Quellcode:
aSource.Width := abs(last.X-start.X);
aSource.Height := abs(last.Y-start.Y);
die breite bzw die höhe ist falsch berechnet, es muss ein pixel dazu addiert werden, also so hier:

Delphi-Quellcode:
aSource.Width := abs(last.X-start.X)+1;
aSource.Height := abs(last.Y-start.Y)+1;
ansonsten funktioniert der code perfekt, hab ihn selbst getestet.

Flips 14. Mai 2008 18:09

Re: Nicht-weißen-Bereich ausschneiden
 
Ok thx, das hatte ich auchmal gehabt, konnte es nur nicht begründen :-)
Aber das er bei dir perfekt funktioniert...
Könntest du mal ein Beispiel anhängen? :-)

Flips 14. Mai 2008 18:14

Re: Nicht-weißen-Bereich ausschneiden
 
OK...wie immer...
Schuld war mal wieder das berühmte Pixelformat -> pf24Bit
So sollte es dann stimmen:
Delphi-Quellcode:
procedure ArrangeSymbol(aSource: TBitmap; Width: Integer = -1;Height : Integer = -1;threshold: Byte = 254);
var h,w : integer;
b : ^TRGBTriple;
start, last : TPoint;
buffer : TBitmap;
begin
last.X := 0;
last.Y := 0;
start.X := 1000;
start.Y := 1000;
buffer := TBitmap.Create;
try
  buffer.Assign(aSource);
  buffer.PixelFormat := pf24Bit;
  for h := 0 to buffer.Height -1 do
    begin
      b := buffer.ScanLine[h];
      for w := 0 to buffer.Width -1 do
        begin
          if (b^.rgbtBlue <= threshold) and (b^.rgbtRed <= threshold) and (b^.rgbtGreen <= threshold) then
            begin
              if w < start.X then
                start.X := w;
              if h < start.Y then
                start.Y := h;
              if w > last.X then
                last.X := w;
              if h > last.Y then
                last.Y := h;
            end;

          inc(b);
        end;
    end;
  if (Width = -1) or (Height = -1) then
    begin
      aSource.Width := abs(last.X-start.X)+1;
      aSource.Height := abs(last.Y-start.Y)+1;
    end
  else
    begin
      aSource.Width := Width;
      aSource.Height := Height;
    end;
  aSource.Canvas.FillRect(aSource.Canvas.ClipRect);
  BitBlt(aSource.Canvas.Handle,0,0,aSource.Width,aSource.Height,buffer.Canvas.Handle,start.X,start.Y,SRCCOPY);
  finally
    buffer.Free;
  end;
end;

Phantom1 14. Mai 2008 18:25

Re: Nicht-weißen-Bereich ausschneiden
 
Zitat:

Zitat von Flips
OK...wie immer...
Schuld war mal wieder das berühmte Pixelformat -> pf24Bit
So sollte es dann stimmen:
....

ich hatte nur 24bit bilder probiert, deshalb gings bei mir auch ^^


Alle Zeitangaben in WEZ +1. Es ist jetzt 22:15 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