Einzelnen Beitrag anzeigen

bernhard_LA

Registriert seit: 8. Jun 2009
Ort: Bayern
1.123 Beiträge
 
Delphi 11 Alexandria
 
#1

weniger Scanline aufrufe ... Graustufenbild

  Alt 10. Feb 2024, 17:24
unter https://blog.dummzeuch.de/2019/12/12...lls-in-delphi/
gib es ein code fragment um mit weniger Scanline Zugriffen eine Bild/Bitmap Bearbeitung durch zuführen.
Meine Komplette Umsetzung ist unten eingefügt.

Frage : Diese Methode ist auf Assert(_InBmp.PixelFormat = pf24bit);
also 24bit Bitmaps ausgelegt. Wie würde eine Code Variante aussehen welche pf8bit und pf16 bit auch unterstützt ?






Delphi-Quellcode:
var FImageOut : TBitmap;

begin
     FImageOut := TBitmap.CReate;
     try

        CreateSpecialImage ( FImage , FImageOut, 100 );

        OutImage.Picture.Bitmap.Assign(FImageOut);
     finally
       // FImageOut.Free;
     end;



Delphi-Quellcode:
uses Types, classes, Vcl.Graphics;
type

  TRgbTriple = packed record
    // do not change the order of the fields, do not add any fields
    Blue: Byte;
    Green: Byte;
    Red: Byte;
  end;

  PRgbTriple =^TRgbTriple;

  TRgbTripleArray = packed array[0..MaxInt div SizeOf(TRgbTriple) - 1] of TRgbTriple;
  PRgbTripleArray = ^TRgbTripleArray;


  procedure CreateSpecialImage(const InBmp, OutBmp: TBitmap; Threshold: Byte);


implementation

function AddToPtr(const _Ptr: Pointer; _Offset: NativeInt): Pointer; inline;
begin
  Result := Pointer(NativeInt(_Ptr) + _Offset);
end;

function PtrDiff(const _Ptr1, _Ptr2: Pointer): NativeInt; inline;
begin
  Result := NativeInt(_Ptr1) - NativeInt(_Ptr2);
end;


procedure CreateSpecialImage(const InBmp, OutBmp: TBitmap; Threshold: Byte);

var
  BytesPerPixel: NativeInt;
  InScanLine0: Pointer;
  InBytesPerLine: NativeInt;
  OutBytesPerLine: NativeInt;
  OutScanLine0: Pointer;

  InPixel: PRgbTriple;
  OutPixel: PRgbTriple;
  Pixel: TRgbTriple;
  x, y: Integer;
  Height, Width : Integer;
begin
  Height := inBMP.Height;
  Width := inBmp.Width;
  OutBmp.Width := Width;
  OutBmp.Height := Height;
  InBmp.PixelFormat := pf24bit;
  OutBmp.PixelFormat := pf24bit;

  BytesPerPixel := SizeOf(Pixel);
  InScanLine0 := InBmp.ScanLine[0];
  InBytesPerLine := NativeInt(InBmp.ScanLine[1]) - NativeInt(InScanLine0);
  OutScanLine0 := OutBmp.ScanLine[0];
  OutBytesPerLine := NativeInt( OutBmp.ScanLine[1]) - NativeInt(OutScanLine0);
  OutPixel := OutScanLine0;
  for y := 0 to Height - 1 do begin
    for x := 0 to Width - 1 do begin
      InPixel := AddToPtr(InScanLine0, InBytesPerLine * y + x * BytesPerPixel);
      Pixel := InPixel^;
      ///
      /// doSomething(Pixel);
      ///
      if Pixel.Blue > Threshold then Pixel.Blue := Threshold;
      if Pixel.red > Threshold then Pixel.red := Threshold;
      if Pixel.Green > Threshold then Pixel.Green := Threshold;


      OutPixel := AddToPtr(OutScanLine0, OutBytesPerLine * y + x * BytesPerPixel);
      OutPixel^ := Pixel;
    end;
  end;

end;
  Mit Zitat antworten Zitat