九宫格贴图是我用duilib界面库和一个开源的MingQQ 里面封装的图片处理看到的,开始不知道怎么会事情,然后百度一下发现对应知识比较少,感觉就是拉伸图片变形会好一些。
贴一下介绍知识
看到
论坛有很多想问九宫格图的问题,在此我给大家讲一讲这个九宫格 九宫格是利用一张很小的图片来绘制大区域图片的技术,用户可以制作九宫格图片,并设置拉伸的位置,图片会在贴图时只拉伸中心的部分,边角却不会被拉伸,这样只要设计时图片中心的颜色是纯色,那即使拉伸的再大也会保持原有的效果。
正常情况下九宫格绘制会遵循下面的规则: a. 保持4个角部分不变形 b. 单向拉伸4条边(即在4个角两两之间的边,比如上边,只做横向拉伸) c. 双向拉伸中间部分(即九宫格的中间部分,横向,纵向同时拉伸,PS:拉伸比例不一定相同)
也许大家看过上图之后对九宫格一定有一定的认识了,让我们来结合CocoStudio编辑器来讲一讲。 每一个可以设置图片的控件都能都设定九宫格属性,配置窗如下
引用地址:http://www.cocoachina.com/bbs/read.phptid-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;
};
#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);