파이어몽키
Image URL로 TImage에 이미지 로드
험프리.김현수
2013. 12. 13. 00:37
웹에 있는 이미지를 표시해야 할 것 같아 간단하게 라이브러리 형태로 만들었어요.
TBitmap을 class helper로 확장했습니다.
소스가 몇 줄 되지 않으니 설명은 생략합니다.
iOS(아이폰5), Android(Nexus 7), 윈도우(Windows 7)에서 모두 정상 동작 확인했습니다.
참고하세요^^
사용법
procedure TForm3.Button1Click(Sender: TObject);
var
Size: Int64;
begin
Image1.Bitmap.LoadFromUrl('https://t1.daumcdn.net/cfile/tistory/2353573E529FDAAC03', Size);
Memo1.Lines.Add('1 : ' + Format('W: %d, H: %d, S: %d', [Image1.Bitmap.Width, Image1.Bitmap.Height, Size]))
end;
procedure TForm3.Button2Click(Sender: TObject);
begin
Image1.Bitmap.LoadFromUrl('https://t1.daumcdn.net/cfile/tistory/2353573E529FDAAC03');
Memo1.Lines.Add('2 : ' + Format('W: %d, H: %d', [Image1.Bitmap.Width, Image1.Bitmap.Height]))
end;
procedure TForm3.Button3Click(Sender: TObject);
begin
Image1.Bitmap.LoadThumbnailFromURL('https://t1.daumcdn.net/cfile/tistory/2353573E529FDAAC03', 100, 100);
Memo1.Lines.Add('3 : ' + Format('W: %d, H: %d', [Image1.Bitmap.Width, Image1.Bitmap.Height]))
end;쓰레드로 처리하도록 변경해 사용법의 첫번째 사이즈 정보를 얻어오는 부분은 제외됩니다.
(깃허브의 소스코드를 참고하세요. https://github.com/hjfactory/FMX.Devgear)
구현부
unit FMX.Devgear.HelperClass;
interface
uses
System.Classes, FMX.Graphics;
type
TBitmapHelper = class helper for TBitmap
public
procedure LoadFromUrl(AUrl: string);
procedure LoadThumbnailFromUrl(AUrl: string; const AFitWidth, AFitHeight: Integer);
end;
implementation
uses
System.SysUtils, System.Types, IdHttp, IdTCPClient, AnonThread;
procedure TBitmapHelper.LoadFromUrl(AUrl: string);
var
_Thread: TAnonymousThread;
begin
_Thread := TAnonymousThread.Create(
function: TMemoryStream
var
Http: TIdHttp;
begin
Result := TMemoryStream.Create;
Http := TIdHttp.Create(nil);
try
try
Http.Get(AUrl, Result);
except
Result.Free;
end;
finally
Http.Free;
end;
end,
procedure(AResult: TMemoryStream)
begin
if AResult.Size > 0 then
LoadFromStream(AResult);
AResult.Free;
end,
procedure(AException: Exception)
begin
end
);
end;
procedure TBitmapHelper.LoadThumbnailFromUrl(AUrl: string; const AFitWidth,
AFitHeight: Integer);
var
Bitmap: TBitmap;
scale: Single;
begin
LoadFromUrl(AUrl);
scale := RectF(0, 0, Width, Height).Fit(RectF(0, 0, AFitWidth, AFitHeight));
Bitmap := CreateThumbnail(Round(Width / scale), Round(Height / scale));
try
Assign(Bitmap);
finally
Bitmap.Free;
end;
end;
end. 안드로이드 환경에서 8bit GIF 이미지가 표시되지 않는경우
아래와 같이 FMX.Graphics.Android.pas 파일을 수정하세요. 결과적으로 IsGIFStream 메소드에서 GIF 여부를 파악하는 부분이 잘못되어 있어 8bit GIF 표시에 문제가 있습니다.
class function TBitmapCodecAndroid.IsGIFStream(const Stream: TStream): Boolean;
const
IDCharCount = 3;
type
GIFByteArray = array[0..IDCharCount-1] of Byte;
const
GifBytes: GIFByteArray = ($47, $49, $46); // G I F
var
I: Integer;
PrevPosition: Int64;
ReadBytes: GIFByteArray;
begin
if (Stream = nil) or (Stream.Size < IDCharCount) then
Exit(False);
Result := True;
PrevPosition := Stream.Position;
try
Stream.ReadBuffer(ReadBytes, IDCharCount);
for I := Low(ReadBytes) to High(ReadBytes) do
if ReadBytes[I] <> GifBytes[I] then
Exit(False);
finally
Stream.Position := PrevPosition;
end;
end;
BitmapUrl.zip