Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   PByteArray - Scanline für große Bilder (https://www.delphipraxis.net/196776-pbytearray-scanline-fuer-grosse-bilder.html)

bernhard_LA 19. Jun 2018 06:38

PByteArray - Scanline für große Bilder
 
ich verwende PByteArray und scanline um große Bilder zu bearbeiten. Wenn aber die Pixelanzahl*3 >32767 ist bekomme ich einen Range Check error. Kann ich die Größe von TByteArray dynamisch an meine Bildgröße anpassen ?




Delphi-Quellcode:
unit System.SysUtils;


  PByteArray = ^TByteArray;
  TByteArray = array[0..32767] of Byte;


Delphi-Quellcode:
procedure MeineBildverarbeitung(..........);


    ByteLine : pbyteArray;
    i, j : Integer;
    xmax : Integer;
    ymax : Integer;

  begin

    aBmp.pixelformat := pf24bit;

    for j := ystart to ymax do
      begin

        ByteLine := aBmp.ScanLine[ j ];




            BValueArray[ i - xstart, j - ystart ] := ByteLine[ 3 * i ];
            GValueArray[ i - xstart, j - ystart ] := ByteLine[ 3 * i + 1 ];
            RvalueArray[ i - xstart, j - ystart ] := ByteLine[ 3 * i + 2 ]; //  range error kommt hier

Schokohase 19. Jun 2018 08:05

AW: PByteArray - Scanline für große Bilder
 
Nein, das Array hat eine statische Länge und die kann eben nicht geändert werden.

Du kannst den Range-Check aber gezielt für diesen Part ausschalten:

Delphi-Quellcode:

procedure MeineBildverarbeitung(..........);
  type
    PScanline: ^TScanline;
    TScaneline: array[0..0] of byte; // JEDES statisch definierte Array erfüllt prinzipiell die Anforderung
  var
    ByteLine : PScanline;
    i, j : Integer;
    xmax : Integer;
    ymax : Integer;

  begin

    aBmp.pixelformat := pf24bit;

    for j := ystart to ymax do
      begin

        ByteLine := aBmp.ScanLine[ j ];
{$R-} // Rangecheck AUS
            BValueArray[ i - xstart, j - ystart ] := ByteLine[ 3 * i ];
            GValueArray[ i - xstart, j - ystart ] := ByteLine[ 3 * i + 1 ];
            RvalueArray[ i - xstart, j - ystart ] := ByteLine[ 3 * i + 2 ];
{$R+} // Rangecheck EIN

CHackbart 19. Jun 2018 08:15

AW: PByteArray - Scanline für große Bilder
 
Sauberer wäre es, wenn du auf PByteArray verzichtest und PByte nutzt:

Delphi-Quellcode:
procedure MeineBildverarbeitung(..........);
  type
    PScanline: ^TScanline;
    TScaneline: array[0..0] of byte; // JEDES statisch definierte Array erfüllt prinzipiell die Anforderung
  var
    dst : PByte;
    i, j: Integer;
    xmax : Integer;
    ymax : Integer;

  begin

    aBmp.pixelformat := pf24bit;

    for j := ystart to ymax do
      begin

        dst := aBmp.ScanLine[ j ];
        inc(dst, xstart*3);
        for i := 0 to xmax-xstart do
        begin
            BValueArray[i, j - ystart ] := dst^; inc(dst);
            GValueArray[i, j - ystart ] := dst^; inc(dst);
            RvalueArray[i, j - ystart ] := dst^; inc(dst);

himitsu 19. Jun 2018 09:46

AW: PByteArray - Scanline für große Bilder
 
Ich war mal davon ausgegangen, dass Delphi bei
Delphi-Quellcode:
 array[0..0] of ...
die Bereichsprüfungen deaktiviert,
aber dem ist leider nicht so.

Also sollte man sort, wo man solche Pointer auf solche Arrays verwendet, selbst dafür sorgen, dass sie nicht aktiv ist.

Oder man nimmt einen Zeiger auf
Delphi-Quellcode:
array[0..WasGroßes] of ...
.
Delphi-Quellcode:
array[0..High(NativeInt) div SizeOf(DerTyp) div 256 - 2 * SizeOf(NativeInt)] of DerTyp

Dennis07 19. Jun 2018 12:17

AW: PByteArray - Scanline für große Bilder
 
Prinzipiell lässt es sich auch mit einem dynamischen Array lösen (hatte das mal so gemacht früher), ist allerdings etwas komplizierter. Hatte dafür
Delphi-Quellcode:
TArray<TRgbTriple>
verwendet.

bernhard_LA 19. Jun 2018 22:31

AW: PByteArray - Scanline für große Bilder
 
habe jetzt diese verwendet


Delphi-Quellcode:
type

  PLargeByteArray = ^TLargeByteArray;
  TLargeByteArray = array of Byte;

und dann in der Funktion


Delphi-Quellcode:
   
   aScanLineARRAY : TLargeByteArray ;
    ysize : Integer ;
   

  begin

    aBmp.pixelformat := pf24bit;

    ysize := round (aBMP.Width *3) ;

    setlength( aScanLineARRAY, ysize );

    ....
           ByteLine := aBmp.ScanLine[ j ];



            BValueArray[ i - xstart, j - ystart ] := aScanLineARRAY[ 3 * i ];
            GValueArray[ i - xstart, j - ystart ] := aScanLineARRAY[ 3 * i + 1 ];
            RvalueArray[ i - xstart, j - ystart ] := aScanLineARRAY[ 3 * i + 2 ];

    ..


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