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('http://cfile2.uf.tistory.com/image/2353573E529FDAAC032731', 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('http://cfile2.uf.tistory.com/image/2353573E529FDAAC032731'); 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('http://cfile2.uf.tistory.com/image/2353573E529FDAAC032731', 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;
빌드해보니 아래와 같은 오류가 발생하네요.
뭔가 설치를 추가로 해야하나보군요..^^
[dcc32 Fatal Error] Unit3.pas(27): F1026 File not found: 'C:\Users\홍길동\Downloads\BitmapUrl\FMX.Devgear.Extentsions.dcu'
폼의 유닛에서 uses에서 오타가 있었습니다.
다시 올렸구요. uses 절에 FMX.Devgear.Extensions;로 변경하시면 됩니다^^
BitmapUrlDemo 소스로 테스트해본 결과
안드로이드 환경에서는 가져오는 이미지가 8비트 형식일때 그림이 제대로 불러와지지 않네요
ex) http://img.naver.net/static/www/u/2013/0731/nmms_224940510.gif
24비트(jpeg)는 잘 보여지구요. (예제로 쓰인 그림도 이 경우더군요)
윈도우에서는 잘만되니 모바일에서는 무언가 더 설정이 필요한건가요??
본문 하단의 내용을 참고하세요.