如何在VB.NET中生成A4尺寸双面(2×5)的多图像合并输出
VB.NET 实现A4页面2列5行多图合并(单页10张+双面支持)
核心思路
- 基于96DPI定义A4页面像素尺寸(宽827px、高1169px,可按需调整DPI)
- 划分2列5行网格,扣除边距和间距后计算单个图片单元格的大小
- 按每10张图片为一组分页,逐页绘制内容
- 双面模式下,偶数页反转列顺序,保证翻页后内容阅读逻辑一致
完整实现代码
Imports System.Drawing Imports System.Drawing.Drawing2D Imports System.Collections.Generic Imports System.IO Public Class ImageMerger ' A4参数(96DPI),300DPI可改为2480×3508 Private Const A4Width As Integer = 827 Private Const A4Height As Integer = 1169 ' 布局固定参数 Private Const Columns As Integer = 2 Private Const Rows As Integer = 5 Private Const PageImageCount As Integer = Columns * Rows ' 单页10张 Private Const Margin As Integer = 20 ' 页面边距 Private Const Spacing As Integer = 10 ' 图片间距 ''' <summary> ''' 生成符合A4布局的页面集合 ''' </summary> ''' <param name="imagePaths">待合并的图片路径列表</param> ''' <param name="isDoubleSided">是否启用双面布局</param> ''' <returns>页面Bitmap列表</returns> Public Function MergeImagesToA4Pages(imagePaths As List(Of String), isDoubleSided As Boolean) As List(Of Bitmap) Dim pages As New List(Of Bitmap) If imagePaths.Count = 0 Then Return pages ' 计算单个图片单元格的尺寸 Dim cellWidth As Integer = (A4Width - Margin * 2 - Spacing * (Columns - 1)) \ Columns Dim cellHeight As Integer = (A4Height - Margin * 2 - Spacing * (Rows - 1)) \ Rows ' 按每页10张分组处理 For pageIndex As Integer = 0 To (imagePaths.Count - 1) \ PageImageCount Dim startIdx = pageIndex * PageImageCount Dim endIdx = Math.Min(startIdx + PageImageCount - 1, imagePaths.Count - 1) Dim currentPageImgs As New List(Of Image) ' 加载当前页图片,失败时用空白图兜底 For i = startIdx To endIdx Try currentPageImgs.Add(Image.FromFile(imagePaths(i))) Catch currentPageImgs.Add(New Bitmap(cellWidth, cellHeight)) End Try Next ' 创建A4页面画布 Dim pageBmp As New Bitmap(A4Width, A4Height) Using g As Graphics = Graphics.FromImage(pageBmp) g.Clear(Color.White) g.SmoothingMode = SmoothingMode.HighQuality g.InterpolationMode = InterpolationMode.HighQualityBicubic ' 绘制当前页所有图片 For imgIdx = 0 To currentPageImgs.Count - 1 Dim row = imgIdx \ Columns Dim col = imgIdx Mod Columns ' 双面模式下偶数页反转列顺序 If isDoubleSided AndAlso pageIndex Mod 2 = 1 Then col = Columns - 1 - col End If ' 计算图片绘制坐标 Dim x = Margin + col * (cellWidth + Spacing) Dim y = Margin + row * (cellHeight + Spacing) ' 按比例缩放图片并居中绘制 Dim img = currentPageImgs(imgIdx) Dim scale = Math.Min(cellWidth / img.Width, cellHeight / img.Height) Dim drawWidth = CInt(img.Width * scale) Dim drawHeight = CInt(img.Height * scale) Dim drawX = x + (cellWidth - drawWidth) \ 2 Dim drawY = y + (cellHeight - drawHeight) \ 2 g.DrawImage(img, drawX, drawY, drawWidth, drawHeight) Next End Using ' 释放当前页图片资源 For Each img In currentPageImgs img.Dispose() Next pages.Add(pageBmp) Next Return pages End Function ''' <summary> ''' 保存生成的页面到指定目录 ''' </summary> ''' <param name="pages">页面Bitmap列表</param> ''' <param name="outputDir">输出目录路径</param> Public Sub SavePages(pages As List(Of Bitmap), outputDir As String) If Not Directory.Exists(outputDir) Then Directory.CreateDirectory(outputDir) End If For i = 0 To pages.Count - 1 pages(i).Save(Path.Combine(outputDir, $"Page_{i + 1}.png"), Imaging.ImageFormat.Png) pages(i).Dispose() Next End Sub End Class ' 使用示例 ' Dim merger As New ImageMerger() ' Dim imgPaths As New List(Of String) From {"img1.jpg", "img2.jpg", "img3.jpg", ...} ' Dim resultPages = merger.MergeImagesToA4Pages(imgPaths, isDoubleSided:=True) ' merger.SavePages(resultPages, "C:\ImageOutput")
关键细节说明
- 分辨率调整:如果需要更高打印精度,可替换A4尺寸为300DPI对应的2480×3508像素
- 图片适配:通过计算最小缩放比例保证图片不变形,同时居中对齐单元格
- 双面逻辑:偶数页反转列索引,解决双面打印时背面内容顺序颠倒的问题
- 资源管理:所有
Image和Bitmap对象使用后必须调用Dispose,避免内存泄漏
内容的提问来源于stack exchange,提问作者dlaksmi




