Это мой код, который пытается не блокировать приложение в Android при загрузке одного или нескольких изображений.Delphi Bitmap in Thread
Каждый раз замерзает или не загружается должным образом.
Если кто-то знает способ сделать то, что мне нужно, был бы вам признателен.
Это моя процедура:
uses
System.IOUtils,
System.Threading,
System.SyncObjs,
FMX.Surfaces,
MyTasks;
procedure TForm1.Button1Click(Sender: TObject);
begin
AniIndicator1.Enabled := True;
AniIndicator1.Visible := True;
Button1.Enabled := False;
TTask.Run(
procedure
var
VBitmapSurface: TBitmapSurface;
VFiles: TStringDynArray;
VFilesIndexes: TArray<NativeInt>;
VFile: String;
VIndex: Integer;
VBitmapData: TBitmapData;
VMapped: Boolean;
VCriticalSection: TCriticalSection;
begin
VCriticalSection := TCriticalSection.Create;
VCriticalSection.Acquire;
VFiles := SearchFiles([ TPath.GetPicturesPath, TPath.GetCameraPath, TPath.GetSharedPicturesPath, TPath.GetSharedCameraPath ], [ '*.jpg', '*.jpeg' ]).Value;
VFilesIndexes := Randomizer(Length(VFiles)).Value;
VFile := VFiles[ VFilesIndexes[ 0 ] ];
VBitmapSurface := TBitmapSurface.Create;
try
if TBitmapCodecManager.LoadFromFile(VFile, VBitmapSurface) then
begin
VMapped := False;
TThread.Synchronize(nil,
procedure
begin
Image1.Bitmap.SetSize(VBitmapSurface.Width, VBitmapSurface.Height);
VMapped := Image1.Bitmap.Map(TMapAccess.Write, VBitmapData);
end
);
if VMapped then
try
if VBitmapData.Pitch = VBitmapSurface.Pitch then
Move(VBitmapSurface.Bits^, VBitmapData.Data^, VBitmapSurface.Pitch * VBitmapData.Height)
else
for VIndex := 0 to VBitmapSurface.Height - 1 do
Move(VBitmapSurface.Scanline[ VIndex ]^, Pointer(NativeInt(VBitmapData.Data) + VIndex * VBitmapData.Pitch)^, VBitmapData.Width * VBitmapSurface.BytesPerPixel);
finally
TThread.Synchronize(nil,
procedure
begin
Image1.Bitmap.Unmap(VBitmapData);
end
);
end;
end;
finally
VBitmapSurface.DisposeOf;
end;
VCriticalSection.Release;
VCriticalSection.DisposeOf;
TThread.Synchronize(nil,
procedure
begin
AniIndicator1.Enabled := False;
AniIndicator1.Visible := False;
Button1.Enabled := True;
end
);
end
);
end;
Да, вы можете загрузить растровое изображение в потоке. Однако вы не можете отображать его на своем интерфейсе ** в потоке. Это визуальная часть, которая не является потокобезопасной. Поскольку вы не предоставили никакого кода, практически невозможно сказать вам, почему вы получаете «авария и пустые или черные изображения». –
@KenWhite По-видимому, растровое изображение Delphi VCL не является потокобезопасным, даже если вы его не отобразите. Действительно странно. Похоже, что сторонние библиотеки выглядят так. –
@David: Это FMX, если VCL не был перенесен на Android. (Четвертый абзац.) –