zoukankan      html  css  js  c++  java
  • 如何让 TGPImage 直接从流中加载图片? 回复 "datouxuke " 的问题


    问题来源: http://www.cnblogs.com/del/archive/2009/01/23/1232856.html#post

    方法一:

    Delphi 的 TBitmap 类可以方便地操作流, 如果能让 TGPImage 和 TBitmap 沟通起来就好了;
    TGPImage 有一个子类 TGPBitmap 可以和 TBitmap 沟通... ok 了!

    代码如下:
    uses GDIPOBJ, GDIPAPI;
    
    procedure TForm1.FormPaint(Sender: TObject);
    const
      ImgPath = 'c:\temp\test.bmp';
    var
      img: TGPImage;
      bit: TBitmap;
      g: TGPGraphics;
    begin
      bit := TBitmap.Create;
      bit.LoadFromFile(ImgPath); {因为 TBitmap 操作流特别方便, 这里就没有演示}
    
      img := TGPBitmap.Create(bit.Handle, bit.Palette);
    
      g := TGPGraphics.Create(Canvas.Handle);
      g.DrawImage(img, 0, 0);
    
      g.Free;
      bit.Free;
      img.Free;
    end;
    

    方法二:

    TGPImage 需要的是 IStream 而非 TStream, 直接给它一个 IStream 参数不就完了?
    那怎么实现 IStream 接口呢? Classes 单元下有一个 TStreamAdapter 类就是专门实现 IStream 接口的.
    uses GDIPOBJ, GDIPAPI;
    
    procedure TForm1.FormPaint(Sender: TObject);
    const
      ImgPath = 'c:\temp\test.bmp';
    var
      img: TGPImage;
      MemStream: TMemoryStream;
      MyIStream: TStreamAdapter;
      g: TGPGraphics;
    begin
      MemStream := TMemoryStream.Create;
      MemStream.LoadFromFile(ImgPath);
      MyIStream := TStreamAdapter.Create(MemStream);
      img := TGPImage.Create(MyIStream);
    
      g := TGPGraphics.Create(Canvas.Handle);
      g.DrawImage(img, 0, 0);
    
      g.Free;
      img.Free;
      MemStream.Free;
      MyIStream := nil; {注意这里}
    end;
    

    注意 TStreamAdapter 的本质还是个接口, 只能 MyIStream := nil; 而不能 MyIStream.free;
    如果这样写可能会容易理解一些, 不过要多 uses 一个 ActiveX 单元:
    uses GDIPOBJ, GDIPAPI, ActiveX;
    
    procedure TForm1.FormPaint(Sender: TObject);
    const
      ImgPath = 'c:\temp\test.bmp';
    var
      img: TGPImage;
      MemStream: TMemoryStream;
      MyIStream: IStream; {这里和上面不同}
      g: TGPGraphics;
    begin
      MemStream := TMemoryStream.Create;
      MemStream.LoadFromFile(ImgPath);
      MyIStream := TStreamAdapter.Create(MemStream);
      img := TGPImage.Create(MyIStream);
    
      g := TGPGraphics.Create(Canvas.Handle);
      g.DrawImage(img, 0, 0);
    
      g.Free;
      img.Free;
      MemStream.Free;
      MyIStream := nil;
    end;
    

    TStreamAdapter.Create 方法还有一个 TStreamOwnership 类型的默认参数, 默认值是 soReference;
    如果改为 soOwned, 那连 MyIStream := nil; 也不需要了; 因为和 MyIStream 关联的对象会一同释放它.
    uses GDIPOBJ, GDIPAPI;
    
    procedure TForm1.FormPaint(Sender: TObject);
    const
      ImgPath = 'c:\temp\test.bmp';
    var
      img: TGPImage;
      MemStream: TMemoryStream;
      MyIStream: TStreamAdapter;
      g: TGPGraphics;
    begin
      MemStream := TMemoryStream.Create;
      MemStream.LoadFromFile(ImgPath);
      MyIStream := TStreamAdapter.Create(MemStream, soOwned);
      img := TGPImage.Create(MyIStream);
    
      g := TGPGraphics.Create(Canvas.Handle);
      g.DrawImage(img, 0, 0);
    
      g.Free;
      img.Free;
      MemStream.Free;
    //  MyIStream := nil; {此时如果有这句会出错}
    end;
    

  • 相关阅读:
    一行代码更改博客园皮肤
    fatal: refusing to merge unrelated histories
    使用 netcat 传输大文件
    linux 命令后台运行
    .net core 使用 Nlog 配置文件
    .net core 使用 Nlog 集成 exceptionless 配置文件
    Mysql不同字符串格式的连表查询
    Mongodb between 时间范围
    VS Code 使用 Debugger for Chrome 调试vue
    css权重说明
  • 原文地址:https://www.cnblogs.com/del/p/1380314.html
Copyright © 2011-2022 走看看