Wince PNG贴图类

Wince PNG贴图类

Posted on 2013-06-13 10:31 泡泡糖 阅读( 588) 评论( 0) 编辑 收藏

Wince下支持PNG贴图类,工作项目需要,需要在wince应用开发里面使用PNG图片,主要是做半透明的效果。这个是去年年初写的,最近打算写几篇在Wince上实现类似Android/iPhone的Launcher的博文,主要是实现滑动、图标交换、图标分层归类的功能。需要用到PNG贴图,这是早期的一个版本,解码和Alpha混合都是使用了微软的IImage库。

Alpha混合主要是使用了微软的AlphaBlend(...)接口,后期我会写一篇使用自己写的Alpha混合算法的博文,因为微软的AlphaBlend速度实在不是很高,使用自己编写的Alpha算法会快一些。

给有需要的朋友参考一下,头文件的接口都写了详细的注释,类文件实现也写了必要的注释,如果有问题可以留言,大家讨论一下。

复制代码
/*************************************************
2012, Apical. Co., Ltd.
Edited by OWL
Class name:    CPngBitBlt    

Description:    
实现PNG贴图

*************************************************/

#pragma once

#include "./CtrlConfig.h"

class CPngBitBlt
{
public:
    CPngBitBlt(void);
    ~CPngBitBlt(void);


public:

    /*
    Function:加载PNG图片
    filename:png图片路径
    hbit:返回的png图片句柄
    */
    BOOL LoadPngImage(LPCTSTR filename,HBITMAP * hbit);

    /*
    Function:把png图片贴到DC上面
    pDC:目标dc
    pSrDC:图片dc
    dRc:目标贴图区域
    sRc:源图片区域
    Alpha:透明度(0~255)
    */
    void BiltPNG(CDC* pDC,CDC* pSrDC,CRect dRc,CRect sRc,int Alpha);

    /*
    Function:把png图片贴到DC上面
    pDC:目标dc
    pSrDC:图片dc
    X: 目标X坐标
    Y:目标Y坐标
    width:目标图片宽度
    Heigth:目标图片高度
    Alpha:透明度(0~255)
    */
    void BiltPNG(CDC* pDC, CDC* pSrDC, int X, int Y, int Width, int Height, int Alpha);

    /**********************************************************************   
    函数名:  DrawImage   
    功能:    从文件中加载图片并绘制到DC     
    参数:   
    [in]hdc:              目标DC 
    [in]iconPath:         图片的路径   
    [in]rect              绘制区域   
    返回值:  无  
    说明:    支持bmp、jpg、png、gif等主流类型图片 ,IImage支持这几种图片解码
    **********************************************************************/    
    void DrawImage2DC(HDC hdc,LPCWSTR iconPath,RECT rect);
};
复制代码

 

 

复制代码
#include "StdAfx.h"
#include "PngBitBlt.h"

#include <imaging.h>
#include <initguid.h>
#include <imgguids.h>
#include <wingdi.h>

#pragma comment(lib,"Imaging.lib")
#pragma comment(lib,"uuid.lib")

CPngBitBlt::CPngBitBlt(void)
{
}

CPngBitBlt::~CPngBitBlt(void)
{
}


BOOL CPngBitBlt::LoadPngImage(LPCTSTR filename,HBITMAP * hbit)   
{   
    IImagingFactory* pImageFactory = 0;   
    IImage* pImage = 0;   
    ImageInfo imageInfo;   
    CoInitializeEx(0, COINIT_MULTITHREADED);   
    HBITMAP hBitmap = 0;   
    LPBYTE lpByte;   
  //COM库初始化
    if (SUCCEEDED(CoCreateInstance(CLSID_ImagingFactory, 0, CLSCTX_INPROC_SERVER, IID_IImagingFactory, (void**)&pImageFactory)))   
    {   
        if (SUCCEEDED(pImageFactory->CreateImageFromFile(filename, &pImage))&& SUCCEEDED(pImage->GetImageInfo(&imageInfo)))   
        {   
            //HDC bmpDC = CreateCompatibleDC(hdc);   
            //LPBYTE lpByte;   
            BITMAPINFO *pbinfo ;   
            pbinfo = (BITMAPINFO *)calloc(1, sizeof(BITMAPINFO) + 4 * sizeof(INT)) ;   
            if(!pbinfo)   
                return FALSE ;   
            pbinfo->bmiHeader.biSize = sizeof (BITMAPINFOHEADER);   
            pbinfo->bmiHeader.biWidth = imageInfo.Width ;   
            pbinfo->bmiHeader.biHeight = imageInfo.Height ;   
            pbinfo->bmiHeader.biPlanes = 1;   
            pbinfo->bmiHeader.biBitCount = 32;   
            pbinfo->bmiHeader.biCompression = BI_ALPHABITFIELDS;   
            pbinfo->bmiHeader.biSizeImage = 0 ;   
            pbinfo->bmiHeader.biXPelsPerMeter = 11811;   
            pbinfo->bmiHeader.biYPelsPerMeter = 11811;   
            pbinfo->bmiHeader.biClrUsed = 0;   
            pbinfo->bmiHeader.biClrImportant = 0;   
            int *pMask = (int*)&(pbinfo->bmiColors[0]) ;   
            *pMask++ = 0x00FF0000 ;   
            *pMask++ = 0x0000FF00 ;   
            *pMask++ = 0x000000FF ;   
            *pMask++ = 0xFF000000 ;   
            hBitmap = CreateDIBSection(NULL, pbinfo, DIB_RGB_COLORS, (void **)&lpByte, NULL, 0) ;   
            free(pbinfo) ;   
            if(!hBitmap || !lpByte)   
                return FALSE ;   
            RECT rect = {0, 0, imageInfo.Width, imageInfo.Height};   
            IBitmapImage *pBitmapImage;   
            BitmapData bitmapData;   
            bitmapData.Width = imageInfo.Width;   
            bitmapData.Height = imageInfo.Height;   
            bitmapData.PixelFormat = imageInfo.PixelFormat;   
            pBitmapImage = NULL;   
            pImageFactory->CreateBitmapFromImage(pImage, imageInfo.Width, imageInfo.Height, PIXFMT_32BPP_ARGB,   
                InterpolationHintDefault, &pBitmapImage);   
            pBitmapImage->LockBits(&rect, ImageLockModeRead,PIXFMT_32BPP_ARGB, &bitmapData);   
            //transferring the pixels   
            memcpy(lpByte, bitmapData.Scan0, imageInfo.Width * imageInfo.Height * 4);   
            pBitmapImage->UnlockBits(&bitmapData);   
            pBitmapImage->Release();   
            pImage->Release();   
            // DeleteDC(bmpDC);   
        }   
        pImageFactory->Release();   
    }   
    CoUninitialize();   
    //ProcessThePixelsWithAlphaChannel Here        
    // vertical flip and ProcessThePixelsWithAlphaChannel here   
    for (UINT y=0; y<imageInfo.Height/2; y++)   
    {   
        BYTE * pPixel = (BYTE *) lpByte + imageInfo.Width * 4 * y;   
        BYTE * pDstPixel = (BYTE*) lpByte + imageInfo.Width * 4 * (imageInfo.Height-y-1);    
        for (UINT x=0; x<imageInfo.Width; x++)   
        {   
            pPixel[0] = pPixel[0] * pPixel[3] / 255;   
            pPixel[1] = pPixel[1] * pPixel[3] / 255;   
            pPixel[2] = pPixel[2] * pPixel[3] / 255;   
            pDstPixel[0] = pDstPixel[0] * pDstPixel[3] / 255;   
            pDstPixel[1] = pDstPixel[1] * pDstPixel[3] / 255;   
            pDstPixel[2] = pDstPixel[2] * pDstPixel[3] / 255;   
            INT* pOrigin = (INT*)pPixel;   
            INT* pDst    = (INT*)pDstPixel;   
            INT temp = *pOrigin;   
            *pOrigin = *pDst;   
            *pDst = temp;   
            pPixel += 4;   
            pDstPixel += 4;   
        }   
    }   
    *hbit= hBitmap;   
    if (!hbit)
    {
        return FALSE;
    }
    return TRUE;
}


void CPngBitBlt::BiltPNG(CDC* pDC,CDC* pSrDC,CRect dRc,CRect sRc,int Alpha)
{
    BLENDFUNCTION blendFunction = {0};
    blendFunction.AlphaFormat = AC_SRC_ALPHA;
    blendFunction.BlendFlags = 0;
    blendFunction.BlendOp = AC_SRC_OVER;
    blendFunction.SourceConstantAlpha = Alpha;
    AlphaBlend(pDC->m_hDC,dRc.left, dRc.top, dRc.Width(), dRc.Height(),pSrDC->m_hDC,sRc.left,sRc.top, sRc.Width(), sRc.Height(),blendFunction);
}


void CPngBitBlt::BiltPNG(CDC* pDC, CDC* pSrDC, int X, int Y, int Width, int Height, int Alpha)
{
    CRect dRc = CRect(X, Y, X+Width, Y+Height);
    CRect sRc = CRect(0, 0, Width, Height);
  //初始化BLENDFUNCTION结构体,主要是Alpha混合类型和相关参数
    BLENDFUNCTION blendFunction = {0};
    blendFunction.AlphaFormat = AC_SRC_ALPHA;
    blendFunction.BlendFlags = 0;
    blendFunction.BlendOp = AC_SRC_OVER;
    blendFunction.SourceConstantAlpha = Alpha;
    AlphaBlend(pDC->m_hDC,dRc.left, dRc.top, dRc.Width(), dRc.Height(),pSrDC->m_hDC,sRc.left,sRc.top, sRc.Width(), sRc.Height(),blendFunction);
}


void CPngBitBlt::DrawImage2DC(HDC hdc,LPCWSTR iconPath,RECT rect)  
{  
    IImage * m_pImage=NULL;  
    IImagingFactory * m_pImagingFactory=NULL;  

    HRESULT hr;  

    // COM初始化  
    if (FAILED(hr = CoInitializeEx(NULL, COINIT_MULTITHREADED)))  
    {    
        goto END;  
    }  

    // 创建COM实例  
    if(FAILED(hr = CoCreateInstance(CLSID_ImagingFactory,NULL,CLSCTX_INPROC_SERVER,IID_IImagingFactory,(void**) &m_pImagingFactory)))  
    {  
        goto END;  
    }  

    // 从文件中创建图片  
    if(FAILED(hr = m_pImagingFactory->CreateImageFromFile(iconPath, &m_pImage)))  
    {  
        goto END;  
    }  
    // 绘制图片  
    if(FAILED(hr = m_pImage->Draw(hdc,&rect,NULL)))  
    {  
        goto END;  
    }  

END:  
    // 释放资源  

    if(m_pImage != NULL)  
    {  
        m_pImage->Release();  
        m_pImage = NULL;  
    }  

    if(m_pImagingFactory != NULL)  
    {  
        m_pImagingFactory->Release();  
        m_pImagingFactory = NULL;  
    }  

    CoUninitialize();  
}  
复制代码

有需要的朋友可以参考一下,有问题也可以留言。

需要转载朋友,请附上原文地址:http://www.cnblogs.com/mythou/archive/2013/06/13/3133606.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值