• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            我的玻璃盒子

            一個圖片加載與繪制類(使用GDI輸出圖片)【補充】

            《一個圖片加載與繪制類(使用GDI輸出圖片)》中我公布了基本的圖片加載和繪制類,我們可以再根據這個類派生一些我們需要的新的繪制類,來針對某些特殊情況的繪制和使用,下面我再公布一個這樣的類,作為樣例。其中部分代碼來源于互聯網。

            一、頭文件(CImageLoader.h)

            #include "EnBitmap.h"

            class CImageLoader : public CEnBitmap  
            {
            public:
                BOOL DrawImage(CEnBitmap
            & bmp, int nX, int nY, int nCol, int nRow);
                CImageLoader();
                
            virtual ~CImageLoader();

                BOOL Draw( CDC 
            *pDC, LPRECT r);
                
            //draw sub bmp to special point
                BOOL Draw( CDC *pDC, int x, int y, LPRECT sr );
                BOOL Draw( CDC 
            *pDC, int x, int y, LPRECT sr, COLORREF colTrans, BOOL bTrans );
                BOOL DrawByHeight(CDC
            * pDC, int x, int y, int sx, int sy, LPRECT sr, int nHeight);
                
                
            int     Width()return GetWidth(); }
                
            int     Height()return GetHeight(); }
                
                
            void Attach(HBITMAP hbmp) { CBitmap::Attach(hbmp); }
                
                BOOL LoadBitmap(UINT nResName, HMODULE hInst
            =NULL, COLORREF crBack=0
                

                    
            if(m_hBitmap) DeleteObject();
                    
            return LoadImage(nResName,RT_BITMAP,hInst,crBack);
                }

                BOOL LoadBitmap(LPCTSTR lpctImagePath, COLORREF crBack
            =0
                

                    
            if(m_hBitmap) DeleteObject();
                    
            return LoadImage(lpctImagePath,crBack);
                }

                
                BOOL DrawTransparent(CDC 
            * pDC, int x, int y, COLORREF crColour);    
                HRGN CreateRgnFromFile( COLORREF color );

                BOOL DrawImageByIndex(CDC
            * pDC, CRect rect, int nIndex, COLORREF clrTrans, BOOL bTrans);
            }
            ;

            二、源文件(CImageLoader.cpp)
            #include "stdafx.h"
            #include 
            "GnetImageLoader.h"

            /**///////////////////////////////////////////////////////////////////////
            // Construction/Destruction
            /**///////////////////////////////////////////////////////////////////////

            CImageLoader::CImageLoader()
            {

            }


            CImageLoader::
            ~CImageLoader()
            {

            }


            BOOL CImageLoader::Draw( CDC 
            *pDC, int x, int y, LPRECT sr, COLORREF colTrans, BOOL bTrans )
            {
                
            if ( !bTrans )
                    Draw( pDC ,x, y, sr );
                
            else
                
            {
                    MyTransparentBlt( pDC
            ->m_hDC, x, y, sr->right - sr->left, sr->bottom - sr->top, 
                        m_hBitmap, sr
            ->left, sr->top, colTrans, NULL );
                }

                
            return TRUE;
            }


            //draw sub bmp to special point
            BOOL CImageLoader::Draw( CDC *pDC, int x, int y, LPRECT sr )
            {
                CDC dc;
                dc.CreateCompatibleDC( pDC
            ->m_hDC );
                HBITMAP bmp 
            = dc.SelectBitmap( m_hBitmap );    
                
            if ( sr != NULL)
                    pDC
            ->BitBlt( x, y, sr->right - sr->left, sr->bottom - sr->top, dc.m_hDC, 
                        sr
            ->left, sr->top,  SRCCOPY );
                
            else
                    pDC
            ->BitBlt( x, y, Width(), Height(), dc.m_hDC, 
                        
            00,  SRCCOPY );
                dc.SelectBitmap( bmp );
                
                
            if(dc.m_hDC) ::DeleteDC(dc.Detach());
                
                
            return TRUE;
            }


            BOOL CImageLoader::DrawByHeight(CDC
            * pDC, int x, int y, int sx, int sy, LPRECT sr, int nHeight)
            {
                CDC dc;
                dc.CreateCompatibleDC(pDC
            ->m_hDC);
                HBITMAP hBitmap 
            = dc.SelectBitmap(m_hBitmap);

                
            if(sr == NULL)
                    pDC
            ->BitBlt(x, y, Width(), Height(), dc.m_hDC, 00, SRCCOPY);
                
            else
                
            {
                    
            int nSrcWidth = sr->right - sr->left;
                    
            int nSrcHeight = sr->bottom - sr->top;

                    
            if(nSrcHeight == nHeight)
                        pDC
            ->BitBlt(x, y, nSrcWidth, nSrcHeight, dc.m_hDC, sr->left, sr->top, SRCCOPY);
                    
            else
                    
            {
                        
            //高度不同,需要拉伸繪制(根據指定的高度值:nHeight)
                        pDC->StretchBlt(x, y, sr->right-sr->left, nHeight, dc.m_hDC, sx, sy, nSrcWidth, nSrcHeight, SRCCOPY);
                    }

                }


                dc.SelectBitmap(hBitmap);
                ::DeleteDC(dc.Detach());

                
            return TRUE;
            }


            BOOL CImageLoader::Draw(CDC 
            *pDC, LPRECT r)
            {
                CDC dc;
                dc.CreateCompatibleDC( pDC
            ->m_hDC );
                HBITMAP bmp 
            = dc.SelectBitmap( m_hBitmap );    
                pDC
            ->BitBlt( r->left, r->top, r->right - r->left, r->bottom - r->top, dc.m_hDC, 00 ,
                      SRCCOPY );

                dc.SelectBitmap( bmp );

                
            if(dc.m_hDC) ::DeleteDC(dc.Detach());
                
                
            return TRUE;
            }



            /**////HOWTO: Drawing Transparent Bitmaps
            //see: Microsoft Knowledge Base Article - Q79212
            BOOL CImageLoader::DrawTransparent(CDC * pDC, int x, int y, COLORREF crColour)
            {
                MyTransparentBlt( pDC
            ->m_hDC, x, y, GetWidth(), GetHeight(), m_hBitmap, 00, crColour, NULL );

                
            return TRUE;
            }
                


            HRGN CImageLoader::CreateRgnFromFile( COLORREF color )
            {
                HBITMAP hBmp 
            = m_hBitmap;

                
            // get image properties
                BITMAP bmp = 0 };
                ::GetObject( hBmp, 
            sizeof(BITMAP), &bmp );
                
            // allocate memory for extended image information
                LPBITMAPINFO bi = (LPBITMAPINFO) new BYTE[ sizeof(BITMAPINFO) + 8 ];
                memset( bi, 
            0sizeof(BITMAPINFO) + 8 );
                bi
            ->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
                
            // set window size
                int m_dwWidth    = bmp.bmWidth;        // bitmap width
                int m_dwHeight    = bmp.bmHeight;        // bitmap height
                
            // create temporary dc
                HDC dc = CreateIC( "DISPLAY",NULL,NULL,NULL );
                
            // get extended information about image (length, compression, length of color table if exist, )
                DWORD res = ::GetDIBits( dc, hBmp, 0, bmp.bmHeight, 0, bi, DIB_RGB_COLORS );
                
            // allocate memory for image data (colors)
                LPBYTE pBits = new BYTE[ bi->bmiHeader.biSizeImage + 4 ];
                
            // allocate memory for color table
                if ( bi->bmiHeader.biBitCount == 8 )
                
            {
                    
            // actually color table should be appended to this header(BITMAPINFO),
                    
            // so we have to reallocate and copy it
                    LPBITMAPINFO old_bi = bi;
                    
            // 255 - because there is one in BITMAPINFOHEADER
                    bi = (LPBITMAPINFO)new charsizeof(BITMAPINFO) + 255 * sizeof(RGBQUAD) ];
                    memcpy( bi, old_bi, 
            sizeof(BITMAPINFO) );
                    
            // release old header
                    delete old_bi;
                }

                
            // get bitmap info header
                BITMAPINFOHEADER& bih = bi->bmiHeader;
                
            // get color table (for 256 color mode contains 256 entries of RGBQUAD(=DWORD))
                LPDWORD clr_tbl = (LPDWORD)&bi->bmiColors;
                
            // fill bits buffer
                res = ::GetDIBits( dc, hBmp, 0, bih.biHeight, pBits, bi, DIB_RGB_COLORS );
                DeleteDC( dc );

                BITMAP bm;
                ::GetObject( hBmp, 
            sizeof(BITMAP), &bm );
                
            // shift bits and byte per pixel (for comparing colors)
                LPBYTE pClr = (LPBYTE)&color;
                
            // swap red and blue components
                BYTE tmp = pClr[0]; pClr[0= pClr[2]; pClr[2= tmp;
                
            // convert color if curent DC is 16-bit (5:6:5) or 15-bit (5:5:5)
                if ( bih.biBitCount == 16 )
                
            {
                    
            // for 16 bit
                    color = ((DWORD)(pClr[0& 0xf8>> 3|
                            ((DWORD)(pClr[
            1& 0xfc<< 3|
                            ((DWORD)(pClr[
            2& 0xf8<< 8);
                    
            // for 15 bit
            //        color = ((DWORD)(pClr[0] & 0xf8) >> 3) |
            //                ((DWORD)(pClr[1] & 0xf8) << 2) |
            //                ((DWORD)(pClr[2] & 0xf8) << 7);
                }


                
            const DWORD RGNDATAHEADER_SIZE    = sizeof(RGNDATAHEADER);
                
            const DWORD ADD_RECTS_COUNT        = 40;            // number of rects to be appended
                                                                
            // to region data buffer

                
            // BitPerPixel
                BYTE    Bpp = bih.biBitCount >> 3;                // bytes per pixel
                
            // bytes per line in pBits is DWORD aligned and bmp.bmWidthBytes is WORD aligned
                
            // so, both of them not
                DWORD m_dwAlignedWidthBytes = (bmp.bmWidthBytes & ~0x3+ (!!(bmp.bmWidthBytes & 0x3<< 2);
                
            // DIB image is flipped that's why we scan it from the last line
                LPBYTE    pColor = pBits + (bih.biHeight - 1* m_dwAlignedWidthBytes;
                DWORD    dwLineBackLen 
            = m_dwAlignedWidthBytes + bih.biWidth * Bpp;    // offset of previous scan line
                                                                
            // (after processing of current)
                DWORD    dwRectsCount = bih.biHeight;            // number of rects in allocated buffer
                INT        i, j;                                    // current position in mask image
                INT        first = 0;                                // left position of current scan line
                                                                
            // where mask was found
                bool    wasfirst = false;                        // set when mask has been found in current scan line
                bool    ismask;                                    // set when current color is mask color

                
            // allocate memory for region data
                
            // region data here is set of regions that are rectangles with height 1 pixel (scan line)
                
            // that's why first allocation is <bm.biHeight> RECTs - number of scan lines in image
                RGNDATAHEADER* pRgnData = 
                    (RGNDATAHEADER
            *)new BYTE[ RGNDATAHEADER_SIZE + dwRectsCount * sizeof(RECT) ];
                
            // get pointer to RECT table
                LPRECT pRects = (LPRECT)((LPBYTE)pRgnData + RGNDATAHEADER_SIZE);
                
            // zero region data header memory (header  part only)
                memset( pRgnData, 0, RGNDATAHEADER_SIZE + dwRectsCount * sizeof(RECT) );
                
            // fill it by default
                pRgnData->dwSize    = RGNDATAHEADER_SIZE;
                pRgnData
            ->iType        = RDH_RECTANGLES;

                
            for ( i = 0; i < bih.biHeight; i++ )
                
            {
                    
            for ( j = 0; j < bih.biWidth; j++ )
                    
            {
                        
            // get color
                        switch ( bih.biBitCount )
                        
            {
                        
            case 8:
                            ismask 
            = (clr_tbl[ *pColor ] != color);
                            
            break;
                        
            case 16:
                            ismask 
            = (*(LPWORD)pColor != (WORD)color);
                            
            break;
                        
            case 24:
                            ismask 
            = ((*(LPDWORD)pColor & 0x00ffffff!= color);
                            
            break;
                        
            case 32:
                            ismask 
            = (*(LPDWORD)pColor != color);
                        }

                        
            // shift pointer to next color
                        pColor += Bpp;
                        
            // place part of scan line as RECT region if transparent color found after mask color or
                        
            // mask color found at the end of mask image
                        if ( wasfirst )
                        
            {
                            
            if ( !ismask )
                            
            {
                                
            // save current RECT
                                pRects[ pRgnData->nCount++ ] = CRect( first, i, j, i + 1 );
                                
            // if buffer full reallocate it with more room
                                if ( pRgnData->nCount >= dwRectsCount )
                                
            {
                                    dwRectsCount 
            += ADD_RECTS_COUNT;
                                    
            // allocate new buffer
                                    LPBYTE pRgnDataNew = new BYTE[ RGNDATAHEADER_SIZE + dwRectsCount * sizeof(RECT) ];
                                    
            // copy current region data to it
                                    memcpy( pRgnDataNew, pRgnData, RGNDATAHEADER_SIZE + pRgnData->nCount * sizeof(RECT) );
                                    
            // delte old region data buffer
                                    delete pRgnData;
                                    
            // set pointer to new regiondata buffer to current
                                    pRgnData = (RGNDATAHEADER*)pRgnDataNew;
                                    
            // correct pointer to RECT table
                                    pRects = (LPRECT)((LPBYTE)pRgnData + RGNDATAHEADER_SIZE);
                                }

                                wasfirst 
            = false;
                            }

                        }

                        
            else if ( ismask )        // set wasfirst when mask is found
                        {
                            first 
            = j;
                            wasfirst 
            = true;
                        }

                    }


                    
            if ( wasfirst && ismask )
                    
            {
                        
            // save current RECT
                        pRects[ pRgnData->nCount++ ] = CRect( first, i, j, i + 1 );
                        
            // if buffer full reallocate it with more room
                        if ( pRgnData->nCount >= dwRectsCount )
                        
            {
                            dwRectsCount 
            += ADD_RECTS_COUNT;
                            
            // allocate new buffer
                            LPBYTE pRgnDataNew = new BYTE[ RGNDATAHEADER_SIZE + dwRectsCount * sizeof(RECT) ];
                            
            // copy current region data to it
                            memcpy( pRgnDataNew, pRgnData, RGNDATAHEADER_SIZE + pRgnData->nCount * sizeof(RECT) );
                            
            // delte old region data buffer
                            delete pRgnData;
                            
            // set pointer to new regiondata buffer to current
                            pRgnData = (RGNDATAHEADER*)pRgnDataNew;
                            
            // correct pointer to RECT table
                            pRects = (LPRECT)((LPBYTE)pRgnData + RGNDATAHEADER_SIZE);
                        }

                        wasfirst 
            = false;
                    }


                    pColor 
            -= dwLineBackLen;
                }

                
            // release image data
                delete pBits;
                delete bi;

                
            // create region
                HRGN hRgn = ExtCreateRegion( NULL, RGNDATAHEADER_SIZE + pRgnData->nCount * sizeof(RECT), (LPRGNDATA)pRgnData );
                
            // release region data
                delete pRgnData;

                
            return hRgn;
            }


            BOOL CImageLoader::DrawImage(CEnBitmap 
            &bmp, int nX, int nY, int nCol, int nRow)
            {
                nX 
            -= 1;
                nY 
            -= 1;
                
            int w = GetWidth()/nCol;
                
            int h = GetHeight()/nRow;
                
                HBITMAP hOldBmp;
                CDC memDC;
                CClientDC dc(
            0);
                
                memDC.CreateCompatibleDC(dc.m_hDC);
                bmp.CreateCompatibleBitmap(dc.m_hDC, w, h);
                
                hOldBmp 
            = memDC.SelectBitmap(bmp.m_hBitmap);
                StretchDraw( 
            &memDC, CRect( 00, w, h ),
                    CRect(GetWidth()
            *nX/nCol, GetHeight()*nY/nRow, GetWidth()*nX/nCol+w ,GetHeight()*nY/nRow+h ) );
                memDC.SelectBitmap(hOldBmp);
                
                
            //dc.DeleteDC();
                memDC.DeleteDC();
                ::DeleteObject(hOldBmp);
                hOldBmp 
            = NULL;
                
                
            return TRUE;
            }


            /**///////////////////////////////////////////////////////////////////////////
            ///
            ///    @param [in] pDC    Device context
            ///    @param [in] x    
            ///    @param [in] y
            ///    @param [in] rect
            ///    @param [in] state    Button state
            ///    - 0 : Normal
            ///    - 1 : Pressed
            ///    - 2 : Hover
            ///    - 3 : Disabled
            ///    @param [in] clrTrans
            ///    @param [in] bTrans                    
            ///
            //////////////////////////////////////////////////////////////////////////

            BOOL CImageLoader::DrawImageByIndex(CDC* pDC, CRect rect, int nIndex, COLORREF clrTrans, BOOL bTrans)
            {
                
            if(m_hBitmap == NULL) return FALSE;
                
                Draw(pDC, rect.left, rect.top, CRect(nIndex
            *rect.Width(), 0, (nIndex+1)*rect.Width(), GetHeight()), clrTrans, bTrans);
                
                
            return TRUE;
            }

            posted on 2008-01-17 22:04 深藍色系統 閱讀(784) 評論(0)  編輯 收藏 引用 所屬分類: GDI/GDI+

            導航

            <2025年6月>
            25262728293031
            1234567
            891011121314
            15161718192021
            22232425262728
            293012345

            統計

            常用鏈接

            留言簿(75)

            隨筆分類

            隨筆檔案

            文章分類

            文章檔案

            搜索

            最新評論

            閱讀排行榜

            評論排行榜

            99蜜桃臀久久久欧美精品网站 | 亚洲Av无码国产情品久久| 无码国内精品久久人妻蜜桃| 久久久久国产| 日韩中文久久| 久久久精品日本一区二区三区 | 九九精品99久久久香蕉| 77777亚洲午夜久久多人| 国产成年无码久久久免费| 无码人妻少妇久久中文字幕| 色99久久久久高潮综合影院| 人妻精品久久久久中文字幕| 亚洲国产精品成人AV无码久久综合影院 | 精品久久综合1区2区3区激情| 精品久久一区二区三区| 狠狠干狠狠久久| 久久乐国产精品亚洲综合| 久久这里有精品视频| 2021国内精品久久久久久影院| 久久婷婷五月综合97色直播| 久久久久亚洲精品日久生情| 久久久久久久亚洲Av无码| 99久久99这里只有免费的精品| 久久亚洲高清观看| 久久午夜综合久久| 午夜精品久久久久久毛片| 精品久久久久久久| 香蕉99久久国产综合精品宅男自 | 久久强奷乱码老熟女网站| 久久国产精品99精品国产| 9191精品国产免费久久| 国产 亚洲 欧美 另类 久久| 久久精品夜色噜噜亚洲A∨ | 久久久久亚洲AV片无码下载蜜桃| 国产成人精品免费久久久久| 精品久久久久久久久久久久久久久| 国产精品中文久久久久久久| 久久精品国产91久久综合麻豆自制 | 久久影视国产亚洲| 久久国产精品成人影院| 热久久最新网站获取|