小工具的设计与实现------选四张照片拼成一张照片。
很经典的应用情景,市面上有很多类似的小软件,特别是手机应用。为了方便学习巩固PowerShell,今天笔者使用它来实现。
【设计思路】
- 选择四张符合要求的照片或图片[.jpg] [.png]
- 准备画布,计算其子区域(画布四分之一)宽高比例 $subAspectRatio,然后与每张照片宽高比 $imgAspectRatio 作对比,在比例不变(不拉伸变形)的情况下尽可能铺满。
- 缩放照片,并拼合在一起
- 保存该画布,导出成图片格式存入硬盘中。
【设计要点】
计算子画布(子图区域),也就是四分之一画布大小的宽高比,与待拼合的照片的宽高比,两者进行比较。即subAspectRatio和imgAspectRatio
- 如果照片较宽,则按宽度缩放
- 如果照片较高,则按高度缩放
如下图所示:
如果理想状态,每张照片能铺满子图区域,如下图:
而有一种特殊情况,子区域是见方的(1:1宽高), 而每张图片也是见方的:
这两种情况直接等比缩放即可,而更多的情况是,子区域宽高比和每张照片的宽高比都不同,比如:
会发现有很多空白区域,没错,正是做了缩放处理。
算法实现:
# 计算子图宽高度
子图宽度 = 最终图片宽度 / 2
子图高度 = 最终图片高度 / 2
# 计算绘制位置
子图x坐标 = (每张照片[标号0 1 2 3] % 2) * 子图宽度
子图y坐标 = [math]::Floor(每张照片[标号0 1 2 3] / 2) * 子图高度
# 计算图片的宽高比
照片的宽高比 = 照片宽度 / 照片高度
子图的宽高比 = 子图宽度 / 子图高度
if (照片的宽高比 > 子图的宽高比) {
# 图片较宽,按宽度缩放
相比比例 = 子图宽度 / 照片宽度
待绘制图片宽度 = 子图宽度
待绘制图片高度 = [int](照片高度 * 相比比例)
待绘制图片y坐标 = 子图y坐标 + (子图宽度 - 待绘制图片高度) / 2
待绘制图片x坐标 = 子图x坐标
}
else {
# 图片较高,按高度缩放
相比比例 = 子图宽度 / 照片高度
待绘制图片高度 = 子图高度
待绘制图片宽度 = [int](照片宽度 * 相比比例)
待绘制图片x坐标 = 子图x坐标 + (子图宽度 - 待绘制图片宽度) / 2
待绘制图片y坐标 = 子图y坐标
}
# 创建缩放后的矩形区域
destRect = (
待绘制图片x坐标,
待绘制图片y坐标,
待绘制图片宽度,
待绘制图片高度
)
#缩放绘制
[将img即每张照片绘制到destRect区域内!]
【实际脚本】
- 导入程序集 System.Drawing ,负责绘制任务
- 定义参数,如文件夹地址、输出文件名、最终图片宽度和高度
- 获取文件夹内的照片(四张jpg或png)
- 创建目标画布
- 读取每张照片[遍历],按照上述算法进行计算,绘制在目标画布上
- 保存目标画布,导出成.jpg格式的照片保存至文件夹内
示例1:
给出四张示例照片或图片:
目标照片大小:2000 * 2000
将四张照片放入一个文件夹,然后将上述脚本保存成 .ps1 也放入其中,右键 - 使用PowerShell运行,之后得到同文件夹下的新照片:
示例2:
给出四张示例照片或图片:
目标照片大小:1600* 800
将四张照片放入一个文件夹,然后将上述脚本保存成 .ps1 也放入其中,右键 - 使用PowerShell运行,之后得到同文件夹下的新照片:
示例3:
给出四张示例照片或图片:
目标照片大小:2000 * 1450
将四张照片放入一个文件夹,然后将上述脚本保存成 .ps1 也放入其中,右键 - 使用PowerShell运行,之后得到同文件夹下的新照片:
示例4:
给出四张示例照片或图片:
目标照片大小:2000 * 2000
将四张照片放入一个文件夹,然后将上述脚本保存成 .ps1 也放入其中,右键 - 使用PowerShell运行,之后得到同文件夹下的新照片:
示例5:
给出四张示例照片或图片(四张规格大小一致,都是见方1:1):
目标照片大小:1600 * 1600
将四张照片放入一个文件夹,然后将上述脚本保存成 .ps1 也放入其中,右键 - 使用PowerShell运行,之后得到同文件夹下的新照片:
【结尾】
还是挺方便的,如果没有其他工具在手的话。当然,还有很多点值得优化,如:
- 图片的格式问题,支持更多格式
- 拼合的顺序,可以让用户自定义
- 可以让用户看到运行状态,方便调试修改
- 设配置文件,如目标照片大小、文件夹地址、生成文件类型等参数,可以更好的管理
总之,这是一次很好的开发经历,虽然脚本不算复杂,但是很实用,能充分体现脚本灵活易修改维护的特点。PowerShell,一直伴随你左右。。。
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |