(Я в курсе что задача из серии "не бей лежачего" но для начала тестирования возможностей LLM-кодинга она вполне пойдет,
ну и возможно потом будет где-то даже немного полезна ... )
Промт.
Write a function for lazarus (fpc,LCL) to load and scale JPG to TBitmap (from internet and from file with caching to file) which can be used without problems for multithreaded loading. (answer in Russian, with description and comments in Russian )
То бишь:
Напиши функцию для lazarus (fpc,LCL) загрузки и масштабирования JPG в TBitmap(из интернета и из файла с кэшированием в файл ) которую можно без проблем использовать при многопоточной загрузке
(отвечай на русском языке, с описанием и комментариями на русском языке )
LLM grok-2
Было ...
- Код: Выделить всё
uses
Classes, SysUtils, Graphics, FPImage, FPReadJPEG, FPWriteJPEG, LazFileUtils,
fphttpclient, LCLIntf;
...
function LoadAndScaleImage(const URLOrFilePath: string; const TargetWidth, TargetHeight: Integer): TBitmap;
var
Bitmap: TBitmap;
JPEGImage: TFPCustomImage;
JPEGReader: TFPCustomImageReader;
JPEGWriter: TFPCustomImageWriter;
HTTPClient: TFPHttpClient;
CachePath: string;
CacheFilename: string;
MemoryStream: TMemoryStream;
begin
Result := nil;
Bitmap := TBitmap.Create;
try
// Кэширование: проверяем, есть ли файл в кэше
CachePath := GetAppConfigDir(False);
ForceDirectories(CachePath);
CacheFilename := CachePath + ExtractFileName(URLOrFilePath);
if FileExists(CacheFilename) then
begin
// Загрузка из кэша
Bitmap.LoadFromFile(CacheFilename);
end
else
begin
// Загрузка из интернета или файла
if Pos('http', LowerCase(URLOrFilePath)) = 1 then
begin
HTTPClient := TFPHttpClient.Create(nil);
try
MemoryStream := TMemoryStream.Create;
try
HTTPClient.Get(URLOrFilePath, MemoryStream);
MemoryStream.Position := 0;
Bitmap.LoadFromStream(MemoryStream);
finally
MemoryStream.Free;
end;
finally
HTTPClient.Free;
end;
end
else
begin
Bitmap.LoadFromFile(URLOrFilePath);
end;
// Сохраняем в кэш
Bitmap.SaveToFile(CacheFilename);
end;
// Масштабирование изображения
JPEGImage := TFPMemoryImage.Create;
try
JPEGReader := TFPReaderJPEG.Create;
try
JPEGImage.LoadFromBitmap(Bitmap.Handle, Bitmap.MaskHandle);
finally
JPEGReader.Free;
end;
Bitmap.SetSize(TargetWidth, TargetHeight);
Bitmap.Canvas.StretchDraw(Bitmap.Canvas.ClipRect, JPEGImage);
finally
JPEGImage.Free;
end;
Result := Bitmap;
except
on E: Exception do
begin
FreeAndNil(Bitmap);
raise Exception.CreateFmt('Ошибка при загрузке и масштабировании изображения: %s', [E.Message]);
end;
end;
end;
Стало ... (Первая пробная но условно-рабочая версия )
- Код: Выделить всё
uses
Classes, SysUtils, Forms, Controls, Graphics, Dialogs,
FPImage, FPCanvas, FPImgCanv, FPWriteBMP, LazFileUtils,
fphttpclient, LCLIntf, ExtCtrls, StdCtrls;
function LoadAndScaleImage(const URLOrFilePath: string; const TargetWidth, TargetHeight: Integer): TBitmap;
var
Bitmap,B: TBitmap;
JPEGImage: TFPCustomImage;
HTTPClient: TFPHttpClient;
CachePath: string;
CacheFilename: string;
MST, MemoryStream: TMemoryStream;
FCanvas : TFPcustomCAnvas ;
writer : TFPCustomImageWriter;
begin
Result := nil;
Bitmap := TBitmap.Create;
try
// Кэширование: проверяем, есть ли файл в кэше
CachePath := ExtractFilePath( ExpandFileName(ParamStr(0)));
CacheFilename := CachePath + ExtractFileName(URLOrFilePath);
JPEGImage := TFPMemoryImage.create(0,0);
if FileExists(CacheFilename) then
begin
// Загрузка из кэша
// Bitmap
JPEGImage.LoadFromFile(CacheFilename);
end
else
begin
// Загрузка из интернета или файла
if Pos('http', LowerCase(URLOrFilePath)) = 1 then
begin
HTTPClient := TFPHttpClient.Create(nil);
try
MemoryStream := TMemoryStream.Create;
try
HTTPClient.Get(URLOrFilePath, MemoryStream);
MemoryStream.Position := 0;
//Bitmap.
JPEGImage. LoadFromStream(MemoryStream);
finally
MemoryStream.Free;
end;
finally
HTTPClient.Free;
end;
end
else
begin
// Bitmap
JPEGImage.LoadFromFile(URLOrFilePath);
end;
// Сохраняем в кэш
JPEGImage.SaveToFile(CacheFilename);
end;
Bitmap.SetSize(TargetWidth, TargetHeight);
B := Bitmap;
//Конверсия в TBitmap
FCanvas := TFPImageCanvas.Create (JPEGImage);
Writer := TFPWriterBMP.Create;
MST:=TMemoryStream.Create;
Writer.ImageWrite(Mst,JPEGImage);
Writer.Free;
MST.Seek(0,soBeginning);
b.LoadFromStream(MST);
Mst.Free;
//=========================
Bitmap.Canvas.StretchDraw(Rect(0,0,TargetWidth, TargetHeight),B);
FCanvas .Free;
finally
JPEGImage.Free;
end;
Result := Bitmap;
end;
Вопросы :
1 Можно ли "Конверсию в TBitmap" сделать как-то менее громоздко ?
2 Зачем нужен JPEGReader если TFPMemoryImage все читает без него ?