VC编程之九宫格贴图
小标 2018-08-14 来源 : 阅读 1175 评论 0

摘要:本文主要向大家介绍了VC编程之九宫格贴图,通过具体的内容向大家展示,希望对大家学习VC编程有所帮助。

本文主要向大家介绍了VC编程之九宫格贴图,通过具体的内容向大家展示,希望对大家学习VC编程有所帮助。

九宫格贴图是我用duilib界面库和一个开源的MingQQ 里面封装的图片处理看到的,开始不知道怎么会事情,然后百度一下发现对应知识比较少,感觉就是拉伸图片变形会好一些。

 

贴一下介绍知识

 

看到论坛有很多想问九宫格图的问题,在此我给大家讲一讲这个九宫格 九宫格是利用一张很小的图片来绘制大区域图片的技术,用户可以制作九宫格图片,并设置拉伸的位置,图片会在贴图时只拉伸中心的部分,边角却不会被拉伸,这样只要设计时图片中心的颜色是纯色,那即使拉伸的再大也会保持原有的效果。


正常情况下九宫格绘制会遵循下面的规则: a. 保持4个角部分不变形 b. 单向拉伸4条边(即在4个角两两之间的边,比如上边,只做横向拉伸) c. 双向拉伸中间部分(即九宫格的中间部分,横向,纵向同时拉伸,PS:拉伸比例不一定相同)

也许大家看过上图之后对九宫格一定有一定的认识了,让我们来结合CocoStudio编辑器来讲一讲。 每一个可以设置图片的控件都能都设定九宫格属性,配置窗如下

 

引用地址://www.cocoachina.com/bbs/read.php?tid-158657-page-1.html

 

我喜欢用MingQQ里面的简单封装的CImageEx 已经含有贴九宫格的方法了,同时也含有了PNG透明处理,MFC 类CImage 默认不支持的。

void SetNinePart(const RECT * lpNinePart);

这里rect 这里作者的意思不是矩形,根据上面知识和代码发现是4个线来确定的,就距离左边和距离上面和距离右边和距离底边。

 

我把MIngQQ里面的CImageEx单独丢出来吧,推荐大家可以看一下作者的webqq还是写的非常有水平。


#pragma once

 

#include

 

class CImageEx : public CImage

{

public:

    CImageEx(void);

    virtual ~CImageEx(void);

 

public:

    BOOL LoadFromFile(LPCTSTR pszFileName);

    BOOL LoadFromIStream(IStream* pStream);

    BOOL LoadFromBuffer(const BYTE* lpBuf, DWORD dwSize);

    BOOL LoadFromResource(HINSTANCE hInstance, LPCTSTR pszResourceName, LPCTSTR pszResType);

    BOOL LoadFromResource(HINSTANCE hInstance, UINT nIDResource, LPCTSTR pszResType);

 

    void SetNinePart(const RECT * lpNinePart);

    BOOL Draw2(HDC hDestDC, const RECT& rectDest);

 

    void GrayScale();   // 图像灰度化

 

private:

    BOOL AlphaPremultiplication();  // Alpha预乘

    BOOL DrawNinePartImage(int pleft, int ptop, int pright, int pbottom,

        HDC hDC, int height, int width, int left, int top, int right, int bottom);

    BOOL DrawNinePartImage(HDC hDC, int x, int y, int cx, int cy,

        int nLeft, int nTop, int nRight, int nBottom);

    int GetFileType(LPCTSTR lpszFileName);

 

private:

    BOOL m_bIsNinePart;

    RECT m_rcNinePart;

};

</atlimage.h>

    

#include "StdAfx.h"

#include "ImageEx.h"

 

CImageEx::CImageEx(void)

{

    m_bIsNinePart = FALSE;

    ::SetRectEmpty(&m_rcNinePart);

}

 

CImageEx::~CImageEx(void)

{

}

 

BOOL CImageEx::LoadFromFile(LPCTSTR pszFileName)

{

    HRESULT hr = CImage::Load(pszFileName);

    if (hr == S_OK)

    {

        if (GetFileType(pszFileName) == 0)  // png

            AlphaPremultiplication();

        return TRUE;

    }

    else

    {

        return FALSE;

    }

}

 

BOOL CImageEx::LoadFromIStream(IStream* pStream)

{

    HRESULT hr = CImage::Load(pStream);

    if (hr == S_OK)

    {

        AlphaPremultiplication();

        return TRUE;

    }

    else

    {

        return FALSE;

    }

}

 

BOOL CImageEx::LoadFromBuffer(const BYTE* lpBuf, DWORD dwSize)

{

    if (NULL == lpBuf || dwSize <= 0)

        return FALSE;

 

    HGLOBAL hGlobal = ::GlobalAlloc(GHND, dwSize);

    if (NULL == hGlobal)

        return FALSE;

 

    LPVOID lpBuffer = ::GlobalLock(hGlobal);

    if (NULL == lpBuffer)

    {

        ::GlobalFree(hGlobal);

        return FALSE;

    }

 

    memcpy(lpBuffer, lpBuf, dwSize);

    ::GlobalUnlock(hGlobal);

 

    LPSTREAM lpStream = NULL;

    HRESULT hr = ::CreateStreamOnHGlobal(hGlobal, TRUE, &lpStream);

    if (hr != S_OK)

    {

        ::GlobalFree(hGlobal);

        return FALSE;

    }

     

    BOOL bRet = LoadFromIStream(lpStream);

    lpStream->Release();

 

    return bRet;

}

 

BOOL CImageEx::LoadFromResource(HINSTANCE hInstance, LPCTSTR pszResourceName, LPCTSTR pszResType)

{

    HRSRC hRsrc = ::FindResource(hInstance, pszResourceName, pszResType);

    if (NULL == hRsrc)

        return FALSE;

 

    DWORD dwSize = ::SizeofResource(hInstance, hRsrc);

    if (0 == dwSize)

        return FALSE;

 

    HGLOBAL hGlobal = ::LoadResource(hInstance, hRsrc);

    if (NULL == hGlobal)

        return FALSE;

 

    LPVOID pBuffer = ::LockResource(hGlobal);

    if (NULL == pBuffer)

    {

        ::FreeResource(hGlobal);

        return FALSE;

    }

 

    HGLOBAL hGlobal2 = ::GlobalAlloc(GHND, dwSize);

    if (NULL == hGlobal2)

    {

        ::FreeResource(hGlobal);

        return FALSE;

    }

 

    LPVOID pBuffer2 = ::GlobalLock(hGlobal2);

    if (NULL == pBuffer2)

    {

        ::GlobalFree(hGlobal2);

        ::FreeResource(hGlobal);

        return FALSE;

    }

 

    memcpy(pBuffer2, pBuffer, dwSize);

    ::GlobalUnlock(hGlobal2);

 

    LPSTREAM pStream = NULL;

    HRESULT hr = ::CreateStreamOnHGlobal(hGlobal2, TRUE, &pStream);

    if (hr != S_OK)

    {

        ::GlobalFree(hGlobal2);

        ::FreeResource(hGlobal);

        return FALSE;

    }

 

    BOOL bRet = LoadFromIStream(pStream);

 

    if (pStream)

        pStream->Release();

 

    ::FreeResource(hGlobal);

 

    return bRet;

}

 

BOOL CImageEx::LoadFromResource(HINSTANCE hInstance, UINT nIDResource, LPCTSTR pszResType)

{

    return LoadFromResource(hInstance, MAKEINTRESOURCE(nIDResource), pszResType);

}

 

void CImageEx::SetNinePart(const RECT * lpNinePart)

{

    if ((NULL == lpNinePart) || (0 == lpNinePart->left && 0 == lpNinePart->top

        && 0 == lpNinePart->right && 0 == lpNinePart->bottom))

    {

        m_bIsNinePart = FALSE;

        ::SetRectEmpty(&m_rcNinePart);

    }

    else

    {

        m_bIsNinePart = TRUE;

        m_rcNinePart = *lpNinePart;

    }

}

 

BOOL CImageEx::Draw2(HDC hDestDC, const RECT& rectDest)

{

    if (m_bIsNinePart)

    {

        int nWidth = rectDest.right - rectDest.left;

        int nHeight = rectDest.bottom - rectDest.top;

        if (GetWidth() != nWidth || GetHeight() != nHeight)

        {

            return DrawNinePartImage(hDestDC, rectDest.left, rectDest.top, nWidth, nHeight,

                m_rcNinePart.left, m_rcNinePart.top, m_rcNinePart.right, m_rcNinePart.bottom);

        }

    }

     

    return Draw(hDestDC, rectDest);

}

 

// 图像灰度化

void CImageEx::GrayScale()

{

    int nWidth = GetWidth();

    int nHeight = GetHeight();

 

    BYTE* pArray = (BYTE*)GetBits();

    int nPitch = GetPitch();

    int nBitCount = GetBPP() / 8;

 

    for (int i = 0; i < nHeight; i++)

    {

        for (int j = 0; j < nWidth; j++)

        {

            int grayVal = (BYTE)(((*(pArray + nPitch * i + j * nBitCount) * 306)

                + (*(pArray + nPitch * i + j * nBitCount + 1) * 601)

                + (*(pArray + nPitch * i + j * nBitCount + 2) * 117) + 512 ) >> 10);  // 计算灰度值

 

            *(pArray + nPitch * i + j * nBitCount) = grayVal;                           // 赋灰度值

            *(pArray + nPitch * i + j * nBitCount + 1) = grayVal;

            *(pArray + nPitch * i + j * nBitCount + 2) = grayVal;

        }

    }

}

 

// Alpha预乘

BOOL CImageEx::AlphaPremultiplication()

{

    LPVOID pBitsSrc = NULL;

    BYTE * psrc = NULL;

    BITMAP stBmpInfo;

 

    HBITMAP hBmp = (HBITMAP)*this;

 

    ::GetObject(hBmp, sizeof(BITMAP), &stBmpInfo);

 

    // Only support 32bit DIB section

    if (32 != stBmpInfo.bmBitsPixel || NULL == stBmpInfo.bmBits)

        return FALSE;

 

    psrc = (BYTE *) stBmpInfo.bmBits;

 

    // Just mix it

    for (int nPosY = 0; nPosY < abs(stBmpInfo.bmHeight); nPosY++)

    {

        for (int nPosX = stBmpInfo.bmWidth; nPosX > 0; nPosX--)

        {

            BYTE alpha  = psrc[3];

            psrc[0] = (BYTE)((psrc[0] * alpha) / 255);

            psrc[1] = (BYTE)((psrc[1] * alpha) / 255);

            psrc[2] = (BYTE)((psrc[2] * alpha) / 255);

            psrc += 4;

        }

    }

 

    return TRUE;

}

 

BOOL CImageEx::DrawNinePartImage(int pleft, int ptop, int pright, int pbottom,

                       HDC hDC, int height, int width, int left, int top, int right, int bottom)

{

    // 左上

    {

        CRect rcDest(pleft, ptop, pleft+left, ptop+top);

        CRect rcSrc(0, 0, left, top);

        if (!rcDest.IsRectEmpty() && !rcSrc.IsRectEmpty())

            Draw(hDC, rcDest, rcSrc);

    }

 

    // 左边

    {

        CRect rcDest(pleft, top+ptop, pleft+left, top+(height-top-bottom-ptop-pbottom));

        CRect rcSrc(0, top, left, top+(GetHeight()-top-bottom));

        if (!rcDest.IsRectEmpty() && !rcSrc.IsRectEmpty())

            Draw(hDC, rcDest, rcSrc);

    }

 

    // 上边

    {

        CRect rcDest(left+pleft, ptop, (left+pleft)+(width-left-right-pleft-pright), ptop+top);

        CRect rcSrc(left, 0, left+(GetWidth()-left-right), top);

        if (!rcDest.IsRectEmpty() && !rcSrc.IsRectEmpty())

            Draw(hDC, rcDest, rcSrc);

    }

 

    // 右上

    {

        CRect rcDest(width- right-pright, ptop, (width- right-pright)+right, ptop+top);

        CRect rcSrc(GetWidth()-right, 0, (GetWidth()-right)+right, top);

        if (!rcDest.IsRectEmpty() && !rcSrc.IsRectEmpty())

            Draw(hDC, rcDest, rcSrc);

    }

 

    // 右边

    {

        CRect rcDest(width-right-pright, top+ptop, (width-right-pright)+right, (top+ptop)+(height-top-bottom-ptop-pbottom));

        CRect rcSrc(GetWidth()-right, top, (GetWidth()-right)+right, top+(GetHeight()-top-bottom));

        if (!rcDest.IsRectEmpty() && !rcSrc.IsRectEmpty())

            Draw(hDC, rcDest, rcSrc);

    }

 

    // 下边

    {

        CRect rcDest(left+pleft, height-bottom-pbottom, (left+pleft)+(width-left-right-pleft-pright), (height-bottom-pbottom)+bottom);

        CRect rcSrc(left, GetHeight()-bottom, left+(GetWidth()-left-right), (GetHeight()-bottom)+bottom);

        if (!rcDest.IsRectEmpty() && !rcSrc.IsRectEmpty())

            Draw(hDC, rcDest, rcSrc);

    }

 

    // 右下

    {

        CRect rcDest(width-right-pright, height-bottom-pbottom, (width-right-pright)+right, (height-bottom-pbottom)+bottom);

        CRect rcSrc(GetWidth()-right, GetHeight()-bottom, (GetWidth()-right)+right, (GetHeight()-bottom)+bottom);

        if (!rcDest.IsRectEmpty() && !rcSrc.IsRectEmpty())

            Draw(hDC, rcDest, rcSrc);

    }

 

    // 左下

    {

        CRect rcDest(pleft, height-bottom-pbottom, pleft+left, (height-bottom-pbottom)+bottom);

        CRect rcSrc(0, GetHeight()-bottom, left, (GetHeight()-bottom)+bottom);

        if (!rcDest.IsRectEmpty() && !rcSrc.IsRectEmpty())

            Draw(hDC, rcDest, rcSrc);

    }

 

    // 中间

    {

        CRect rcDest(left+pleft, top+ptop, (left+pleft)+(width-left-right-pleft-pright), (top+ptop)+(height-top-bottom-ptop-pbottom));

        CRect rcSrc(left, top, left+(GetWidth()-left-right), top+(GetHeight()-top-bottom));

        if (!rcDest.IsRectEmpty() && !rcSrc.IsRectEmpty())

            Draw(hDC, rcDest, rcSrc);

    }

 

    return TRUE;

}

 

BOOL CImageEx::DrawNinePartImage(HDC hDC, int x, int y, int cx, int cy,

                                 int nLeft, int nTop, int nRight, int nBottom)

{

    int cxImage = GetWidth();

    int cyImage = GetHeight();

 

    // 左上

    {

        RECT rcDest = {x, y, x+nLeft, y+nTop};

        RECT rcSrc = {0, 0, nLeft, nTop};

        if (!::IsRectEmpty(&rcDest) && !::IsRectEmpty(&rcSrc))

            Draw(hDC, rcDest, rcSrc);

    }

 

    // 左边

    {

        RECT rcDest = {x, y+nTop, x+nLeft, (y+nTop)+(cy-nTop-nBottom)};

        RECT rcSrc = {0, nTop, nLeft, nTop+(cyImage-nTop-nBottom)};

        if (!::IsRectEmpty(&rcDest) && !::IsRectEmpty(&rcSrc))

            Draw(hDC, rcDest, rcSrc);

    }

 

    // 上边

    {

        RECT rcDest = {x+nLeft, y, (x+nLeft)+(cx-nLeft-nRight), y+nTop};

        RECT rcSrc = {nLeft, 0, nLeft+(cxImage-nLeft-nRight), nTop};

        if (!::IsRectEmpty(&rcDest) && !::IsRectEmpty(&rcSrc))

            Draw(hDC, rcDest, rcSrc);

    }

 

    // 右上

    {

        RECT rcDest = {x+(cx-nRight), y, (x+(cx-nRight))+nRight, y+nTop};

        RECT rcSrc = {cxImage-nRight, 0, (cxImage-nRight)+nRight, nTop};

        if (!::IsRectEmpty(&rcDest) && !::IsRectEmpty(&rcSrc))

            Draw(hDC, rcDest, rcSrc);

    }

 

    // 右边

    {

        RECT rcDest = {x+(cx-nRight), y+nTop, (x+(cx-nRight))+nRight, (y+nTop)+(cy-nTop-nBottom)};

        RECT rcSrc = {cxImage-nRight, nTop, (cxImage-nRight)+nRight, nTop+(cyImage-nTop-nBottom)};

        if (!::IsRectEmpty(&rcDest) && !::IsRectEmpty(&rcSrc))

            Draw(hDC, rcDest, rcSrc);

    }

 

    // 下边

    {

        RECT rcDest = {x+nLeft, y+(cy-nBottom), (x+nLeft)+(cx-nLeft-nRight), (y+(cy-nBottom))+nBottom};

        RECT rcSrc = {nLeft, cyImage-nBottom, nLeft+(cxImage-nLeft-nRight), (cyImage-nBottom)+nBottom};

        if (!::IsRectEmpty(&rcDest) && !::IsRectEmpty(&rcSrc))

            Draw(hDC, rcDest, rcSrc);

    }

 

    // 右下

    {

        RECT rcDest = {x+(cx-nRight), y+(cy-nBottom), (x+(cx-nRight))+nRight, (y+(cy-nBottom))+nBottom};

        RECT rcSrc = {cxImage-nRight, cyImage-nBottom, (cxImage-nRight)+nRight, (cyImage-nBottom)+nBottom};

        if (!::IsRectEmpty(&rcDest) && !::IsRectEmpty(&rcSrc))

            Draw(hDC, rcDest, rcSrc);

    }

 

    // 左下

    {

        RECT rcDest = {x, y+(cy-nBottom), x+nLeft, (y+(cy-nBottom))+nBottom};

        RECT rcSrc = {0, cyImage-nBottom, nLeft, (cyImage-nBottom)+nBottom};

        if (!::IsRectEmpty(&rcDest) && !::IsRectEmpty(&rcSrc))

            Draw(hDC, rcDest, rcSrc);

    }

 

    // 中间

    {

        RECT rcDest = {x+nLeft, y+nTop, (x+nLeft)+(cx-nLeft-nRight), (y+nTop)+(cy-nTop-nBottom)};

        RECT rcSrc = {nLeft, nTop, nLeft+(cxImage-nLeft-nRight), nTop+(cyImage-nTop-nBottom)};

        if (!::IsRectEmpty(&rcDest) && !::IsRectEmpty(&rcSrc))

            Draw(hDC, rcDest, rcSrc);

    }

 

    return TRUE;

}

 

//获取文件类型(通过文件头几个字节获取)

int CImageEx::GetFileType(LPCTSTR lpszFileName)

{

    unsigned char png_head[8] = {0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A};

    unsigned char gif89a_head[6] = {'G','I','F','8','9','a'};

    unsigned char gif87a_head[6] = {'G','I','F','8','7','a'};

    unsigned char jpg_head[2] = {0xFF, 0xD8};

    unsigned char bmp_head[2] = {0x42, 0x4D};

    unsigned char cData[16] = {0};

 

    FILE * fp = _tfopen(lpszFileName, _T("rb"));

    if (NULL == fp)

        return -1;

    fread(cData, sizeof(cData), 1, fp);

    fclose(fp);

 

    if (!memcmp(cData, png_head, 8))

        return 0;

    else if (!memcmp(cData, gif89a_head, 6) || !memcmp(cData, gif87a_head, 6))

        return 1;

    if (!memcmp(cData, jpg_head, 2))

        return 2;

    else if (!memcmp(cData, bmp_head, 2))

        return 3;

    else

        return -1;

}

本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标编程语言VC/MFC频道!  


本文由 @小标 发布于职坐标。未经许可,禁止转载。
喜欢 | 2 不喜欢 | 0
看完这篇文章有何感觉?已经有2人表态,100%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程