Search results for 'TImage'

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;

저작자 표시 비영리 동일 조건 변경 허락
신고
크리에이티브 커먼즈 라이선스
Creative Commons License

험프리.김현수 험프리.김현수 파이어몽키 , , ,

  1. Blog Icon
    epilogs

    빌드해보니 아래와 같은 오류가 발생하네요.
    뭔가 설치를 추가로 해야하나보군요..^^

    [dcc32 Fatal Error] Unit3.pas(27): F1026 File not found: 'C:\Users\홍길동\Downloads\BitmapUrl\FMX.Devgear.Extentsions.dcu'

  2. 폼의 유닛에서 uses에서 오타가 있었습니다.
    다시 올렸구요. uses 절에 FMX.Devgear.Extensions;로 변경하시면 됩니다^^

  3. Blog Icon
    8비트24비트

    BitmapUrlDemo 소스로 테스트해본 결과

    안드로이드 환경에서는 가져오는 이미지가 8비트 형식일때 그림이 제대로 불러와지지 않네요
    ex) http://img.naver.net/static/www/u/2013/0731/nmms_224940510.gif

    24비트(jpeg)는 잘 보여지구요. (예제로 쓰인 그림도 이 경우더군요)

    윈도우에서는 잘만되니 모바일에서는 무언가 더 설정이 필요한건가요??

  4. 본문 하단의 내용을 참고하세요.