zoukankan      html  css  js  c++  java
  • Wince PNG贴图类

    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

  • 相关阅读:
    helix matrix 螺旋矩阵
    利用基数排序生成100个1000以内顺序排列的随机数
    第三次随笔
    gSoap: How to add info to SOAP Header using gSOAP(转)
    sizeof empty class object
    C++基础回顾字符串地址比较
    (转)RVA相对虚拟地址解释
    团队建设历史经验回顾
    C++全局变量的生老病死
    C++基础回顾强制类型转换
  • 原文地址:https://www.cnblogs.com/mythou/p/3133606.html
Copyright © 2011-2022 走看看