九宫格放缩算法

参考别人的代码实现了一个QImage版,这个版本较QPixmap版修了几个bug,而且最后是使用拼接的方式合成图片,而不是使用QPainter,这样带来的好处就是最后合成的图片效果更好

原理:

9宫格缩放规则如下:

  1. 将一张图分割成9块
  2. 四个角(1,3,7,9)在缩放的时候是保持大小不变
  3. 图块2,8仅当宽度变化时缩放宽度。
  4. 图块4,6仅当高度变化时缩放高度。
  5. 图块5当图片大小发生变化,宽度和高度都进行缩放。

在这里插入图片描述

/*
**  功能							: 九宫格图处理
**  picName						: 图片名字
**  iHorzSplit					: 四个角上格子的宽度
**  iVertSplit					: 四个角上格子的高度
**  dstWidth					: 整个图片缩放的宽度
**  dstWidth					: 整个图片缩放的高度
**  mode						: 放缩模式,默认快速放缩,可以指定平滑放缩
**  返回值						: 处理完成的图片
*/


QImage AlgCommon::NinePatch(const QImage& srcImg, int iHorzSplit, int iVertSplit, int dstWidth, int dstHeight,
	Qt::TransformationMode mode = Qt::FastTransformation)
{
	int width = srcImg.width();
	int height = srcImg.height();

	if (2 * iVertSplit > height || 2 * iHorzSplit > width) return QImage();
	if (2 * iVertSplit > dstHeight || 2 * iHorzSplit > dstWidth) return QImage();

	QImage pix_1 = srcImg.copy(0, 0, iHorzSplit, iVertSplit);

	QImage pix_2 =
		srcImg.copy(iHorzSplit, 0, width - iHorzSplit * 2, iVertSplit);
	QImage pix_3 = srcImg.copy(width - iHorzSplit, 0, iHorzSplit, iVertSplit);

	QImage pix_4 =
		srcImg.copy(0, iVertSplit, iHorzSplit, height - iVertSplit * 2);
	QImage pix_5 = srcImg.copy(iHorzSplit, iVertSplit, width - iHorzSplit * 2,
		height - iVertSplit * 2);
	QImage pix_6 = srcImg.copy(width - iHorzSplit, iVertSplit, iHorzSplit,
		height - iVertSplit * 2);

	QImage pix_7 = srcImg.copy(0, height - iVertSplit, iHorzSplit, iVertSplit);
	QImage pix_8 = srcImg.copy(iHorzSplit, height - iVertSplit,
		width - iHorzSplit * 2, iVertSplit);
	QImage pix_9 = srcImg.copy(width - iHorzSplit, height - iVertSplit,
		iHorzSplit, iVertSplit);

	pix_2 = pix_2.scaled(dstWidth - iHorzSplit * 2, iVertSplit,
		Qt::IgnoreAspectRatio, mode);  //保持高度拉宽
	pix_4 = pix_4.scaled(iHorzSplit, dstHeight - iVertSplit * 2,
		Qt::IgnoreAspectRatio, mode);  //保持宽度拉高
	pix_5 = pix_5.scaled(dstWidth - iHorzSplit * 2, dstHeight - iVertSplit * 2,
		Qt::IgnoreAspectRatio, mode);  //宽高都缩放
	pix_6 = pix_6.scaled(iHorzSplit, dstHeight - iVertSplit * 2,
		Qt::IgnoreAspectRatio, mode);  //保持宽度拉高
	pix_8 = pix_8.scaled(dstWidth - iHorzSplit * 2, iVertSplit, 
		Qt::IgnoreAspectRatio, mode);  //保持高度拉宽

	QImage resultImg(dstWidth, dstHeight, srcImg.format());

	auto func = [&resultImg](int x, int y, const QImage& img) {
		int width = img.width();
		int height = img.height();
		int byteSize = img.depth() / 8;

		for (int j = 0; j < height; ++j) {
			memcpy(resultImg.scanLine(j + y) + x * byteSize, img.scanLine(j),
				width * byteSize);
		}
	};

	func(0, 0, pix_1);
	func(iHorzSplit, 0, pix_2);
	func(dstWidth - iHorzSplit, 0, pix_3);

	func(0, iVertSplit, pix_4);
	func(iHorzSplit, iVertSplit, pix_5);
	func(dstWidth - iHorzSplit, iVertSplit, pix_6);

	func(0, dstHeight - iVertSplit, pix_7);
	func(iHorzSplit, dstHeight - iVertSplit, pix_8);
	func(dstWidth - iHorzSplit, dstHeight - iVertSplit, pix_9);

	return resultImg;
}

参考链接:https://blog.csdn.net/caoshangpa/article/details/53391230

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值