Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   physikalische Kopie einer Bitmap (https://www.delphipraxis.net/203349-physikalische-kopie-einer-bitmap.html)

bernhard_LA 10. Feb 2020 12:31

physikalische Kopie einer Bitmap
 
wir wollen von einer TBitmap in eine andere Bitmap kopieren und verwenden das assign commando
Aktuelle Fehler : das Bitmap zeigt ein anderes Muster, wir könnnen und den Inhalt nicht erklären



Delphi-Quellcode:
bitmap1.assign (bitmap2) ;



hat oft funktioniert, aktuell jedoch nicht. Speziell wenn das Bitmap zwischen div. Funktionsaufrufen so hin und her bewegen

Gyrospeter 10. Feb 2020 13:02

AW: physikalische Kopie einer Bitmap
 
Schon mit einem CopyRect probiert, ob es dann den Fehler dort auch gibt?

zb.
Code:
SR := Rect(0,0,Bitmap1.Width,Bitmap1.Height);
DR := Rect(0,0,Bitmap2.Width,Bitmap2.Height);

Bitmap2.Canvas.CopyRect(DR,Bitmap1.Canvas,SR);

bernhard_LA 10. Feb 2020 13:09

AW: physikalische Kopie einer Bitmap
 
ist dieses Problem bekannt für Delphi, bug in der assign function ?

Rollo62 10. Feb 2020 13:12

AW: physikalische Kopie einer Bitmap
 
Zitat:

Zitat von bernhard_LA (Beitrag 1457045)
ist dieses Problem bekannt für Delphi, bug in der assign function ?

Eventuell zu große Bitmaps / Speicherprobleme ?

dummzeuch 10. Feb 2020 13:18

AW: physikalische Kopie einer Bitmap
 
Zitat:

Zitat von bernhard_LA (Beitrag 1457043)
wir wollen von einer TBitmap in eine andere Bitmap kopieren und verwenden das assign commando
Aktuelle Fehler : das Bitmap zeigt ein anderes Muster, wir könnnen und den Inhalt nicht erklären



Delphi-Quellcode:
bitmap1.assign (bitmap2) ;



hat oft funktioniert, aktuell jedoch nicht. Speziell wenn das Bitmap zwischen div. Funktionsaufrufen so hin und her bewegen

Eigentlich sollte das immer funktionieren. Wenn es nicht klappt, und es sich um multithreaded Code handelt hilft meist ein
Delphi-Quellcode:
MyBitmap.Canvas.Lock.
bzw.
Delphi-Quellcode:
MyBitmap.Canvas.Unlock.

himitsu 10. Feb 2020 14:55

AW: physikalische Kopie einer Bitmap
 
Assign kopiert nicht den Bildinhalt.
Es kopiert nur die Referenz auf das interne TBitmapImage und die Eigenschaften Transparent, TransparentColor, TransparentMode, PixelFormat und AlphaFormat.
Vor allem bei Multithread oder wenn in den Bitmaps nachher noch was geändert wird, dann können schon komische Dinge rauskommen.
Delphi-Quellcode:
  TBitmapImage = class(TSharedImage)
  private
    FHandle: HBITMAP;    // DDB or DIB handle, used for drawing
    FMaskHandle: HBITMAP; // DDB handle
    FPalette: HPALETTE;
    FDIBHandle: HBITMAP; // DIB handle corresponding to TDIBSection
    FDIB: TDIBSection;
    FSaveStream: TMemoryStream; // Save original RLE stream until image is modified
    FHalftone: Boolean;  // FPalette is halftone; don't write to file
    ...
  end;
Bei Draw, CopyRect und Dergleichen passiert sowas nicht, da dort nur der Bildinhalt kopiert wird, aber der Rest nicht.

dummzeuch 10. Feb 2020 15:34

AW: physikalische Kopie einer Bitmap
 
Zitat:

Zitat von himitsu (Beitrag 1457063)
Assign kopiert nicht den Bildinhalt.
Es kopiert nur die Referenz auf das interne TBitmapImage und die Eigenschaften Transparent, TransparentColor, TransparentMode, PixelFormat und AlphaFormat.
Vor allem bei Multithread oder wenn in den Bitmaps nachher noch was geändert wird, dann können schon komische Dinge rauskommen.
Delphi-Quellcode:
  TBitmapImage = class(TSharedImage)
  private
    FHandle: HBITMAP;    // DDB or DIB handle, used for drawing
    FMaskHandle: HBITMAP; // DDB handle
    FPalette: HPALETTE;
    FDIBHandle: HBITMAP; // DIB handle corresponding to TDIBSection
    FDIB: TDIBSection;
    FSaveStream: TMemoryStream; // Save original RLE stream until image is modified
    FHalftone: Boolean;  // FPalette is halftone; don't write to file
    ...
  end;

Ich mag ja falsch liegen, aber folgendes Testprogramm:

Delphi-Quellcode:
procedure test;
var
  bmp1: TBitmap;
  bmp2: TBitmap;
  ScanLine1: Integer;
  ScanLine2: Integer;
begin
  bmp1 := TBitmap.Create;
  bmp1.SetSize(20, 20);
  bmp2 := TBitmap.Create;
  bmp2.Assign(bmp1);
  ScanLine1 := Integer(bmp1.ScanLine[0]);
  ScanLine2 := Integer(bmp2.ScanLine[0]);
  if Scanline1 <> Scanline2 then
    WriteLn('Unterschiedlich')
  else
    WriteLn('gleich');
end.

Liefert mir unter Delphi 2007 "unterschiedlich".

bernhard_LA 10. Feb 2020 15:40

AW: physikalische Kopie einer Bitmap
 
d.h. eine stabile Copyfunktion , ich will nachher zwei physikalische Bitmaps haben geht dann so


Delphi-Quellcode:
procedure CLoneBitmaps ( Bitmap1, Bitmap2 : TBitmap);

begin

SR := Rect(0,0,Bitmap1.Width,Bitmap1.Height);
DR := Rect(0,0,Bitmap2.Width,Bitmap2.Height);

Bitmap2.Canvas.Lock;
Bitmap2.Canvas.CopyRect(DR,Bitmap1.Canvas,SR);
Bitmap2.Canvas.Unlock;

end;

ist dies der richtige Weg ?

himitsu 10. Feb 2020 16:16

AW: physikalische Kopie einer Bitmap
 
Lock/Unlock brauchst vor allem bei Multithread, damit nicht zwei Zeichenoperationen gleichzeitig auf dem Bitmap arbeiten.

Delphi-Quellcode:
R := Rect(0, 0, Bitmap1.Width,Bitmap1.Height); // deine Rects sind ja gleich, da brauchst dann nur Eins
//Bitmap2.PixelFormat := Bitmap1.PixelFormat;
Bitmap2.SetSize(Bitmap1.Width, Bitmap1.Height);
Bitmap2.Canvas.CopyRect(R, Bitmap1.Canvas, R);

// bzw.

//Bitmap2.PixelFormat := Bitmap1.PixelFormat;
Bitmap2.SetSize(Bitmap1.Width, Bitmap1.Height);
Bitmap2.Canvas.Draw(0, 0, Bitmap1);

@dummzeuch: Hmmm, hab hier grad eben nur 'nen XE am Laufen, (glaub aber kaum, dass am TBitmap in den letzten Jahrzehnten viel geändert wurde)
aber
Delphi-Quellcode:
procedure TBitmap.Assign(Source: TPersistent);
kopiert da nirgendwo irgendwas
und selbst das
Delphi-Quellcode:
TBitmap(Source).FImage.Reference;
darin macht am Ende nichts.
Delphi-Quellcode:
procedure TSharedImage.Reference;
begin
  Inc(FRefCount);
end;
Aber vielleicht wird erst beim Zugriff auf die Pixels die Referenz dann aufgelöst, damit es dort dann keine weitere Referenz auf den Bildspeicher gibt.


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