图片组合生成最优正方形

任意数量的图片,通过等比例缩放,重新排列生成最接近的正方形。

 

 


interface Item {
	w: number,
	h: number,
	s?: Item[]
}

function getIndex(len: number) {

	let x = 0;
	let y = 0;
	const arrat: Array<{ x: number, y: number }> = [];

	while (x < len) {
		y = 0;
		while (y < len) {

			if (x !== y) {
				arrat.push({ x, y })
			}

			y += 1;
		}
		x += 1;
	}

	return arrat;
}

function sortItem(a: Item, b: Item) {
	if (a.w === b.w) {
		if (a.h === b.h) {
			return 0
		}
		if (a.h < b.h) {
			return 1
		}

		return -1
	}
	if (a.w < b.w) {
		return 1
	}
	return -1
}



function mappedArray(ary: Item[], keys: Map<string, any>) {

	const res: Array<{ w_hs: number, ws_h: number, item: Item[] }> = [];

	getIndex(ary.length).map((v) => {

		const ary1 = ary.filter((k, i) => i !== v.x && i !== v.y);

		return [[...ary1, {
			w: ary[v.x].w * ary[v.y].w,
			h: ary[v.x].h * ary[v.y].w + ary[v.x].w * ary[v.y].h,
			s: [ary[v.x], ary[v.y]]
		}], [...ary1, {
			h: ary[v.x].h * ary[v.y].h,
			w: ary[v.x].w * ary[v.y].h + ary[v.x].h * ary[v.y].w,
			s: [ary[v.x], ary[v.y]]
		}]]
	}).forEach(v => {

		v.forEach(sub => {

			const s2 = sub.sort(sortItem)
			const k = JSON.stringify(s2);

			if (keys.has(k)) {
				return
			}

			if (sub.length > 2) {
				res.push(...mappedArray(sub, keys))
			} else {
				const v4 = [sub[0].w * sub[1].w, sub[0].h * sub[1].w + sub[0].w * sub[1].h, sub[0].w * sub[1].h + sub[0].h * sub[1].w, sub[0].h * sub[1].h];

				res.push({
					item: sub,
					ws_h: Math.min(v4[0], v4[1]) / Math.max(v4[0], v4[1]),
					w_hs: Math.min(v4[2], v4[3]) / Math.max(v4[2], v4[3])
				})
			}
		})
	})

	return res;
}

//宽高比
const items: Item[] = [
	{ w: 1, h: 1 }, 
	{ w: 1, h: 1 },
	{ w: 2, h: 1 }]

console.log(JSON.stringify(items));

const ary2 = mappedArray(items, new Map<string, any>());

const arysorted = ary2.sort((a, b) => Math.max(a.w_hs, a.ws_h) - Math.max(b.w_hs, b.ws_h))

console.log(JSON.stringify(arysorted, null, '\t'));

 生成JSON结果:

[
	{
		"item": [
			{
				"w": 2,
				"h": 1
			},
			{
				"w": 1,
				"h": 2,
				"s": [
					{
						"w": 1,
						"h": 1
					},
					{
						"w": 1,
						"h": 1
					}
				]
			}
		],
		"ws_h": 0.4,
		"w_hs": 0.4
	},
	{
		"item": [
			{
				"w": 2,
				"h": 1
			},
			{
				"w": 1,
				"h": 2,
				"s": [
					{
						"w": 1,
						"h": 1
					},
					{
						"w": 1,
						"h": 1
					}
				]
			}
		],
		"ws_h": 0.4,
		"w_hs": 0.4
	},
	{
		"item": [
			{
				"w": 2,
				"h": 3,
				"s": [
					{
						"w": 1,
						"h": 1
					},
					{
						"w": 2,
						"h": 1
					}
				]
			},
			{
				"w": 1,
				"h": 1
			}
		],
		"ws_h": 0.4,
		"w_hs": 0.6
	},
	{
		"item": [
			{
				"w": 2,
				"h": 3,
				"s": [
					{
						"w": 1,
						"h": 1
					},
					{
						"w": 2,
						"h": 1
					}
				]
			},
			{
				"w": 1,
				"h": 1
			}
		],
		"ws_h": 0.4,
		"w_hs": 0.6
	},
	{
		"item": [
			{
				"w": 2,
				"h": 3,
				"s": [
					{
						"w": 2,
						"h": 1
					},
					{
						"w": 1,
						"h": 1
					}
				]
			},
			{
				"w": 1,
				"h": 1
			}
		],
		"ws_h": 0.4,
		"w_hs": 0.6
	},
	{
		"item": [
			{
				"w": 2,
				"h": 3,
				"s": [
					{
						"w": 2,
						"h": 1
					},
					{
						"w": 1,
						"h": 1
					}
				]
			},
			{
				"w": 1,
				"h": 1
			}
		],
		"ws_h": 0.4,
		"w_hs": 0.6
	},
	{
		"item": [
			{
				"h": 1,
				"w": 3,
				"s": [
					{
						"w": 1,
						"h": 1
					},
					{
						"w": 2,
						"h": 1
					}
				]
			},
			{
				"w": 1,
				"h": 1
			}
		],
		"ws_h": 0.75,
		"w_hs": 0.25
	},
	{
		"item": [
			{
				"h": 1,
				"w": 3,
				"s": [
					{
						"w": 1,
						"h": 1
					},
					{
						"w": 2,
						"h": 1
					}
				]
			},
			{
				"w": 1,
				"h": 1
			}
		],
		"ws_h": 0.75,
		"w_hs": 0.25
	},
	{
		"item": [
			{
				"h": 1,
				"w": 3,
				"s": [
					{
						"w": 2,
						"h": 1
					},
					{
						"w": 1,
						"h": 1
					}
				]
			},
			{
				"w": 1,
				"h": 1
			}
		],
		"ws_h": 0.75,
		"w_hs": 0.25
	},
	{
		"item": [
			{
				"h": 1,
				"w": 3,
				"s": [
					{
						"w": 2,
						"h": 1
					},
					{
						"w": 1,
						"h": 1
					}
				]
			},
			{
				"w": 1,
				"h": 1
			}
		],
		"ws_h": 0.75,
		"w_hs": 0.25
	},
	{
		"item": [
			{
				"w": 2,
				"h": 1
			},
			{
				"h": 1,
				"w": 2,
				"s": [
					{
						"w": 1,
						"h": 1
					},
					{
						"w": 1,
						"h": 1
					}
				]
			}
		],
		"ws_h": 1,
		"w_hs": 0.25
	},
	{
		"item": [
			{
				"w": 2,
				"h": 1
			},
			{
				"h": 1,
				"w": 2,
				"s": [
					{
						"w": 1,
						"h": 1
					},
					{
						"w": 1,
						"h": 1
					}
				]
			}
		],
		"ws_h": 1,
		"w_hs": 0.25
	}
]

最后一个数据分析,

宽:高= 1:1 的两张图片,首先组合生成 宽:高=2:1 的图,然后再跟宽:高=2:1的图片,可组成 正方形。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值