zoukankan      html  css  js  c++  java
  • 贴图:CImage VS Bitmap

      为了比较小的资源占用和比较快速的贴图速度,使用BitBlt自然是最佳方式,这是为数不多的软渲染GDI APIs里面有硬件加速的API之一,以前看到国外测试速度,不同的硬件下BitBlt比Graphics::DrawImage快100-1w倍,测试很简单就不说了,直接贴图100w张比执行时间。

      为了使用BitBlt,需要HBITMAP数据,初始化CImage后调用CImage::Detach可以直接获得,该HBITMAP是DIBSECTION类型,各数据跟CImage一致,后面的Bitmap就出问题了。

    CImage::Load

    inline HRESULT CImage::Load( LPCTSTR pszFileName ) throw()
    {
    if( !InitGDIPlus() )
    {
    return( E_FAIL );
    }

    Gdiplus::Bitmap bmSrc( (CT2W)pszFileName );
    if( bmSrc.GetLastStatus() != Gdiplus::Ok )
    {
    return( E_FAIL );
    }

    return( CreateFromGdiplusBitmap( bmSrc ) );
    }

    CImage::Detach不再释放内部HBITMAP

    inline HBITMAP CImage::Detach() throw()
    {
    HBITMAP hBitmap;
    ATLASSUME( m_hBitmap != NULL );
    ATLASSUME( m_hDC == NULL );
    hBitmap = m_hBitmap;
    m_hBitmap = NULL;
    m_pBits = NULL;
    m_nWidth = 0;
    m_nHeight = 0;
    m_nBPP = 0;
    m_nPitch = 0;
    m_iTransparentColor = -1;
    m_bHasAlphaChannel = false;
    m_bIsDIBSection = false;
    return( hBitmap );
    }

    CImage::LoadFromResource 使用仅支持bmp的API

    inline void CImage::LoadFromResource( HINSTANCE hInstance, LPCTSTR pszResourceName ) throw()
    {
    HBITMAP hBitmap;

    hBitmap = HBITMAP( ::LoadImage( hInstance, pszResourceName, IMAGE_BITMAP, 0,
    0, LR_CREATEDIBSECTION ) );

    Attach( hBitmap );
    }

    CImage从资源载入图片,只能识别.bmp文件,其他文件将初始化失败导致断言失败ATLASSERT(m_hBitmap != 0),从文件路径载入调用Gdiplus::Bitmap,看来这个CImage只是对GDI+的轻量封装,贴图封装的是::BitBlt和::AlphaBlend。

    GDI+全部操作都是自己实现。

    Bitmap::FromResource

    inline Bitmap::Bitmap(
    IN HINSTANCE hInstance,
    IN const WCHAR *bitmapName
    )
    {
    GpBitmap *bitmap = NULL;

    lastResult = DllExports::GdipCreateBitmapFromResource(hInstance,
    bitmapName,
    &bitmap);

    SetNativeImage(bitmap);
    }

    Bitmap::FromFile

    inline Bitmap::Bitmap(
    IN const WCHAR *filename,
    IN BOOL useEmbeddedColorManagement
    )
    {
    GpBitmap *bitmap = NULL;

    if(useEmbeddedColorManagement)
    {
    lastResult = DllExports::GdipCreateBitmapFromFileICM(filename, &bitmap);
    }
    else
    {
    lastResult = DllExports::GdipCreateBitmapFromFile(filename, &bitmap);
    }

    SetNativeImage(bitmap);
    }

    Bitmap是自力更生,从Bitmap::GetHBITMAP貌似性能比调用Bitmap的CImage高,但是GetHBITMAP第一个参数要求Gdiplus::Color,GDI+的Color是32位的,所以这个将导致最后的HBITMAP变成32位,::GetObject DIBSECTION BITMAPINFOHEADER biBitCount可以看到,因此可以断定其内部实现:创建内存兼容DC和32位图,再BitBlt。所以用CImage::Detach获得HBITMAP是最好的,源码中找不到这个m_hBitmap怎么初始化的,不然可以不用构造CImage对象了。

    2011.12.9 找到CImage得到HBITMAP的方法:

    hBitmap = ::CreateDIBSection( NULL, pbmi, DIB_RGB_COLORS, &m_pBits, NULL,
    0 );
    if( hBitmap == NULL )
    {
    return( FALSE );
    }

    Attach( hBitmap, (nHeight < 0) ? DIBOR_TOPDOWN : DIBOR_BOTTOMUP );

    if( dwFlags&createAlphaChannel )
    {
    m_bHasAlphaChannel = true;
    }




     

  • 相关阅读:
    spring mvc配置完后实现下载功能
    表单中Readonly和Disabled的区别(转载)
    EL表达式中fn函数 (转载)
    Spring mvc中@RequestMapping 6个基本用法小结(转载)
    web开发,关于jsp的常见问题,重复提交,防止后退。
    JQuery页面加载
    解决 spring mvc 3.0 结合 hibernate3.2 使用<tx:annotation-driven>声明式事务无法提交的问题(转载)
    数据库设计原则(转载)
    dhtmlxTree介绍(转载)
    主键索引
  • 原文地址:https://www.cnblogs.com/asight/p/2258602.html
Copyright © 2011-2022 走看看