3

この方法で画像を処理しているのですが、1000×1000ピクセル以上の高解像度画像が含まれていると、画像処理に非常に時間がかかり、アプリがしばらく応答しなくなる原因となります。

高解像度の画像を処理すると、画像のように応答なしのメッセージが常に表示されます。ここに画像の説明を入力

type
   TRGBArray = array[0..0] of TRGBTriple;
   pRGBArray = ^TRGBArray;

var
   ARL, ALL, AOL : pRGBarray;
   TOGfx, TRGfx, TLGfx : TBitmap;


procedure TFZN.GfXColorProcessor;
var
   X, Y : integer;
begin
   TOGfx.Assign(TRGfx);
for Y := 0 to TRGfx.Height - 1 do
begin
   ARL := TOGfx.Scanline[Y];
   AOL := TLGfx.Scanline[Y];
//-------------------------
for x := 0 to TRGfx.Width - 1 do
begin
   ARL[x].RGBtRed := AOL[X].RGBtRed;
   IBG.Picture.bitmap.Assign(TOGfx);
end;

end;

end;
4

3 に答える 3

3

TLama が提案したように、ScanLine() を使用する必要があります。画像の処理にまだ時間がかかる場合は、コードをスレッド化してアプリケーションの通常のフローを続行するか、進行状況バーを表示してユーザーを強制的に待機させることができます。メイン スレッドの外で VCL コントロールを操作するのはスレッド セーフではないことに注意してください。そのため、処理が完了するまで待機する必要があることをユーザーに通知するのがおそらく最善です。

処理を行う単純なスレッドのサンプル コードを次に示します。

unit uImageProcessingThread;

interface

uses
  Winapi.Windows, System.Classes, Vcl.Graphics;

type
  TImageProcessingThread = class(TThread)
  private
    FBitmap: TBitmap;

  protected
    procedure Execute; override;

  public
    constructor Create(const ABitmap: TBitmap);

  end;

implementation

constructor TImageProcessingThread.Create(const ABitmap: TBitmap);
begin
  inherited Create(TRUE);

  FBitmap := ABitmap;
end;

procedure TImageProcessingThread.Execute;
var
  GC  : LongInt;
  H, W: Integer;
begin
  for H := 0 to FBitmap.Height do
  begin
    for W := 0 to FBitmap.Width do
    begin
      GC := ColorToRGB(FBitmap.Canvas.Pixels[W, H]);
      FBitmap.Canvas.Pixels[W, H] := RGB(GC, GC, GC);
    end;
  end;
end;

end.
于 2013-05-11T19:56:20.997 に答える
0

この問題を解決するための非常に簡単な方法は、ループ内でApplication.ProcessMessagesを呼び出すことです。このメソッドにより、ウィンドウは保留中のすべてのメッセージを処理してから、コードに戻ります。

メッセージの処理中に、イベントが発生します。たとえば、クリックが発生します。これらのクリックの 1 つは、プロセスを中止する必要があることを示す変数を設定するために使用されるボタンで発生する場合があります。

これが役立つことを願っています。

于 2013-07-17T18:38:01.197 に答える