A scene
The UI provides a background image, but the size of the window control is not fixed, how to achieve the effect?
For example, the background image is as follows:
(.png 22*34)
The background effects are as follows:
Second realization
1. Ideas
First of all, it is inappropriate to directly scale the background image to the size of the window control. The image is deformed and the pixels are blurred, and the experience is poor.
The optimization scheme is to zoom locally to enhance the experience: split the background image (such as the tic-tac-toe) and draw them to the corresponding parts of the window control .
Mainly rely on QPainter's drawImage overloaded function:
void drawImage(int x, int y, const QImage &image, int sx = 0, int sy = 0, int sw = -1,
int sh = -1, Qt::ImageConversionFlags flags = Qt::AutoColor)
2. Background image split
typedef unsigned int _uint;
// 拆分"模具"
struct _uint_rect
{
_uint_rect(_uint l, _uint t, _uint r, _uint b)
: left(l), top(t), right(r), bottom(b) {}
_uint left, top, right, bottom;
};
// 可以理解为井字格的左上右下数值
// 拆分原则是尽量将背景图片拆分为规则图案和非规则图案
// 尽量缩放背景图片规则部分,不规则部分不缩放
For (.png, 22*34), the split mold options are:
_uint_rect rPadding(8, 13, 10, 8); // 拆分为9部分
For (.png, 25*5, half-arc at both ends), the split mold selection is:
_uint_rect rPadding(6, 0, 6, 0); // 拆分为3部分
3. Paint logic
void drawPixmap(QPainter& painter, const QPixmap& pixmap,
const QRect& rect, const _uint_rect& scaleGrid)
{
int cxPixmap = pixmap.width();
int cyPixmap = pixmap.height();
int cxMidSrc = cxPixmap - scaleGrid.left - scaleGrid.right;
int cyMidSrc = cyPixmap - scaleGrid.top - scaleGrid.bottom;
int cxMidDest = rect.right() - rect.left() - scaleGrid.left - scaleGrid.right;
int cyMidDest = rect.bottom() - rect.top() - scaleGrid.top - scaleGrid.bottom;
// middle
painter.drawPixmap(rect.left() + scaleGrid.left, rect.top() + scaleGrid.top,
cxMidDest, cyMidDest, pixmap,
scaleGrid.left, scaleGrid.top, cxMidSrc, cyMidSrc);
// left-top
if( scaleGrid.left > 0 && scaleGrid.top > 0 )
{
painter.drawPixmap(rect.left(), rect.top(), scaleGrid.left, scaleGrid.top,
pixmap, 0, 0, scaleGrid.left, scaleGrid.top);
}
// top
if( scaleGrid.top > 0 )
{
painter.drawPixmap(rect.left() + scaleGrid.left, rect.top(), cxMidDest, scaleGrid.top,
pixmap, scaleGrid.left, 0, cxMidSrc, scaleGrid.top);
}
// right-top
if( scaleGrid.right > 0 && scaleGrid.top > 0 )
{
painter.drawPixmap(rect.right() - scaleGrid.right, rect.top(), scaleGrid.right, scaleGrid.top,
pixmap, cxPixmap - scaleGrid.right, 0, scaleGrid.right, scaleGrid.top);
}
// right
if( scaleGrid.right > 0 )
{
painter.drawPixmap(rect.right() - scaleGrid.right, rect.top() + scaleGrid.top, scaleGrid.right, cyMidDest,
pixmap, cxPixmap - scaleGrid.right, scaleGrid.top, scaleGrid.right, cyMidSrc);
}
// right-bottom
if( scaleGrid.right > 0 && scaleGrid.bottom > 0 )
{
painter.drawPixmap(rect.right() - scaleGrid.right, rect.bottom() - scaleGrid.bottom,
scaleGrid.right, scaleGrid.bottom, pixmap,
cxPixmap - scaleGrid.right, cyPixmap - scaleGrid.bottom, scaleGrid.right, scaleGrid.bottom);
}
// bottom
if( scaleGrid.bottom > 0 )
{
painter.drawPixmap(rect.left() + scaleGrid.left, rect.bottom() - scaleGrid.bottom, cxMidDest, scaleGrid.bottom,
pixmap, scaleGrid.left, cyPixmap - scaleGrid.bottom, cxMidSrc, scaleGrid.bottom);
}
// left-bottom
if( scaleGrid.left > 0 && scaleGrid.bottom > 0 )
{
painter.drawPixmap(rect.left(), rect.bottom() - scaleGrid.bottom, scaleGrid.left,
scaleGrid.bottom, pixmap,
0, cyPixmap - scaleGrid.bottom, scaleGrid.left, scaleGrid.bottom);
}
// left
if( scaleGrid.left > 0 )
{
painter.drawPixmap(rect.left(), rect.top() + scaleGrid.top, scaleGrid.left, cyMidDest,
pixmap, 0, scaleGrid.top, scaleGrid.left, cyMidSrc);
}
}