Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Delphi Schwarzer Bereich aus Bitmap entfernen (https://www.delphipraxis.net/36033-schwarzer-bereich-aus-bitmap-entfernen.html)

dinosaur 14. Dez 2004 22:10


Schwarzer Bereich aus Bitmap entfernen
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo,

Ich habe ein Bitmap, bei dem sehr viel schwarz um die eigentliche "Zeichnung" herum ist.
Meine Frage ist nun, wie ich den schwarzen Teil wegschneiden kann, sodass nur noch ein Bild mit dem Tatsächlichen Inhalt da ist?

beim angehängten Beispiel möchte ich also nur den rot eingeramten bereich haben, der rest soll wegfallen

Nikolas 14. Dez 2004 22:21

Re: Schwarzer Bereich aus Bitmap entfernen
 
Du könntest per Delphi-Referenz durchsuchencopyrect den Kasten rausschneiden, wenn du weisst, wo er ist. Du kannst dabei aber auch eine Farbe festlegen, die dann transparent wird. Ich glaube, du müsstest nach Delphi-Referenz durchsuchencopymode schauen.

dinosaur 14. Dez 2004 22:26

Re: Schwarzer Bereich aus Bitmap entfernen
 
Mein Problem ist, dass ich eben nicht weiss, wo genau der "Kasten" und wie gross er ist, da das bild veränderbar ist (verschiedene grössen / inhalt / position)

dizzy 14. Dez 2004 22:31

Re: Schwarzer Bereich aus Bitmap entfernen
 
Dann "scanne" das Bild linienweise von oben, unten, links und rechts an in Richtung mitte ab, und sobald eine andere Farbe als Schwarz auftaucht, hast du die gesuchte Begrenzung. Dann mit einer der vielen Copy-Möglichkeiten auschneiden (CopyRect, BitBlt müsste auch gehen, etc.)

UND: Herzlich wilkommen an Board! :dp:

dinosaur 14. Dez 2004 22:34

Re: Schwarzer Bereich aus Bitmap entfernen
 
danke für die begrüssung :-D

Ich werde morgen versuchen eine Funktion zu machen.. Wenn ich mir das so überlege, muss ich mit scanline von oben nach unten, dann von unten nach oben, von links nach rechts und von rechts nach links durchgehen.. gibts auch ne einfachere Variante oder muss ich das so machen ? :cyclops:

Das eigentlich e Ausschneiden ist nicht das problem, sondern möglichst einfache finden der koordinaten

DerDan 14. Dez 2004 22:39

Re: Schwarzer Bereich aus Bitmap entfernen
 
Du möchtest das Bild automatisch verkleinern ?

dann kannst du etwa so vorgehen:


Delphi-Quellcode:
pPixelLine := Bmp.ScanLine [0];
BackColor := pPixelLine^.[0];

// oberste BMP Zeile suchen die nicht einfarbig ist:
Top := -1;
for Y := 0 to Bmp.Height do
begin
  pPixelLine = Bmp.ScanLine [y];
  for x := 0 to bmp.Width do
  begin
    if BakcColor <> pPixelLine^.[0] then
    begin
       Top := y;
       break;
    end;
    if Top >= 0 then begin
      break;
    end;
  end;
end;
dann suchst du noch
von unten nach oben,
von rechts nach links und
von links nach rechts
um alle vier Kanten
deines neuen Rechtecks zu ermitteln.

dann noch ausschneiden -> fertig

die Typen von
BackColor und pPixelLine
sind davon abhängig in welchem Format deine Bmp daherkommt.

das kann man mit bmp.PixelFormat abfragen


DerDan

dinosaur 16. Dez 2004 10:11

Re: Schwarzer Bereich aus Bitmap entfernen
 
Von oben-nach-unten und von unten-nach-oben Geht ja schon gut, Kriege es aber im moment nicht auf die Reihe

von links nach rechts zu suchen und umgekehrt.. Scanline nimmt ja immer eine Horizontale Zeile

Delphi-Quellcode:
function TForm1.RemoveBlack(Picture: TBitmap): TBitmap;
type
  PixArray = Array [1..3] of Byte;
var
  p: ^PixArray;
  FirstTop,FirstLeft, FirstBottom, FirstRight, h,w: Integer;
  Pic: TBitmap;

begin
  FirstTop:=-1;
  FirstLeft:=-1;
  FirstBottom:=-1;
  FirstRight:=-1;

  Pic:=TBitmap.Create;
  Pic.Assign(Picture);
  Pic.PixelFormat:=pf24bit;

  For h:=0 to Pic.Height-1 do
  begin
    p:= Pic.ScanLine[h];
    For w:=0 to Pic.Width-1 do
    begin
      if (p^[1]<>0) OR (p^[2]<>0) OR (p^[3]<>0) then
      begin
        FirstTop:=h;
        break;
      end;
      inc(p)
    end;
   if (FirstTop >= 0) then break;
  end;

  For h:=Pic.Height-1 downto 0 do
  begin
    p:= Pic.ScanLine[h];
    For w:=0 to Pic.Width-1 do
    begin
      if (p^[1]<>0) OR (p^[2]<>0) OR (p^[3]<>0) then
      begin
        FirstBottom:=h;
        break;
      end;
      inc(p)
    end;
   if (FirstBottom >= 0) then break;
  end;

  Showmessage('Y1:' +inttostr(FirstTop)+'Y2:' +inttostr(FirstBottom));
end;


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