Atunci când lucrează cu prelucrarea imaginii în .NET, o necesitate comună este de a combina mai multe imagini – adesea de diferite dimensiuni – într-o singură ieșire. cazuri de utilizare tipice includ collage, frunze sprite, panouri de contact sau bannere de marketing. Acest tutorial arată cum să combinați imaginile folosind Aspose.Imagining pentru .Net cu control precis asupra layout-ului: axis (orizontal/vertical), aliniere (top/center/bottom și stânga/centrul/dreapta), exterior padding, și spațiu între imagine. Graphics
şi focul.
Ce vei construi
*Layout: orizontal sau vertical
• Alimentare: *
Layout orizontal → aliniere verticală:
Top
,Middle
,Bottom
Layout vertical – aliniere orizontală:
Left
,Center
,Right
Padding: exterior pading și inter-item spacing
Background: încărcătura de culoare solidă
Formate: formate amestecate de încărcare (JPG, PNG, etc.), cu excepția formatelor Png/JPEG
Exemplu complet
using System;
using System.Collections.Generic;
using System.IO;
using Aspose.Imaging;
using Aspose.Imaging.ImageOptions;
namespace ImagingMergeDemo
{
public enum MergeAxis { Horizontal, Vertical }
public enum VAlign { Top, Middle, Bottom }
public enum HAlign { Left, Center, Right }
public static class ImageMerger
{
/// <summary>
/// Merges input images into a single image with alignment and padding.
/// </summary>
/// <param name="inputPaths">List of source image file paths.</param>
/// <param name="axis">Horizontal or Vertical stacking.</param>
/// <param name="outerPadding">Padding around the whole collage (in pixels).</param>
/// <param name="spacing">Spacing between images (in pixels).</param>
/// <param name="bgColor">Background color for the canvas.</param>
/// <param name="verticalAlign">Only used when axis == Horizontal (Top/Middle/Bottom inside the row).</param>
/// <param name="horizontalAlign">Only used when axis == Vertical (Left/Center/Right inside the column).</param>
/// <param name="outputPath">Destination file path. Extension determines encoder (e.g., .png, .jpg).</param>
public static void Merge(
IReadOnlyList<string> inputPaths,
MergeAxis axis,
int outerPadding,
int spacing,
Color bgColor,
VAlign verticalAlign,
HAlign horizontalAlign,
string outputPath)
{
if (inputPaths is null || inputPaths.Count == 0)
throw new ArgumentException("No input images provided.");
// Load all images first so we can compute canvas size.
var loaded = new List<Image>(inputPaths.Count);
try
{
foreach (var p in inputPaths)
{
var img = Image.Load(p);
loaded.Add(img);
}
// Compute canvas size.
// For horizontal axis: width = sum(widths) + spacings + 2*outerPadding
// height = max(heights) + 2*outerPadding
// For vertical axis: height = sum(heights) + spacings + 2*outerPadding
// width = max(widths) + 2*outerPadding
int totalWidth, totalHeight;
if (axis == MergeAxis.Horizontal)
{
int sumWidths = 0, maxH = 0;
for (int i = 0; i < loaded.Count; i++)
{
sumWidths += loaded[i].Width;
maxH = Math.Max(maxH, loaded[i].Height);
}
totalWidth = sumWidths + ((loaded.Count - 1) * spacing) + 2 * outerPadding;
totalHeight = maxH + 2 * outerPadding;
}
else
{
int sumHeights = 0, maxW = 0;
for (int i = 0; i < loaded.Count; i++)
{
sumHeights += loaded[i].Height;
maxW = Math.Max(maxW, loaded[i].Width);
}
totalHeight = sumHeights + ((loaded.Count - 1) * spacing) + 2 * outerPadding;
totalWidth = maxW + 2 * outerPadding;
}
// Create canvas (use PNG by default for lossless output; you can switch to JPEGOptions)
using var canvas = Image.Create(new PngOptions(), totalWidth, totalHeight);
// Draw on canvas
using var g = new Graphics(canvas);
g.Clear(bgColor);
int cursorX = outerPadding;
int cursorY = outerPadding;
for (int i = 0; i < loaded.Count; i++)
{
var img = loaded[i];
int drawX, drawY;
if (axis == MergeAxis.Horizontal)
{
// X flows left -> right
drawX = cursorX;
// Y depends on vertical alignment vs tallest height
drawY = verticalAlign switch
{
VAlign.Top => outerPadding,
VAlign.Middle => outerPadding + (totalHeight - 2 * outerPadding - img.Height) / 2,
VAlign.Bottom => outerPadding + (totalHeight - 2 * outerPadding - img.Height),
_ => outerPadding
};
// Draw and move X cursor
g.DrawImage(img, new Rectangle(drawX, drawY, img.Width, img.Height));
cursorX += img.Width + spacing;
}
else
{
// Y flows top -> bottom
drawY = cursorY;
// X depends on horizontal alignment vs widest width
drawX = horizontalAlign switch
{
HAlign.Left => outerPadding,
HAlign.Center => outerPadding + (totalWidth - 2 * outerPadding - img.Width) / 2,
HAlign.Right => outerPadding + (totalWidth - 2 * outerPadding - img.Width),
_ => outerPadding
};
// Draw and move Y cursor
g.DrawImage(img, new Rectangle(drawX, drawY, img.Width, img.Height));
cursorY += img.Height + spacing;
}
}
// Save with encoder that matches extension
SaveByExtension(canvas, outputPath);
}
finally
{
// Dispose loaded images
foreach (var img in loaded)
img.Dispose();
}
}
private static void SaveByExtension(Image image, string outputPath)
{
var ext = Path.GetExtension(outputPath).ToLowerInvariant();
ImageOptionsBase opts = ext switch
{
".jpg" or ".jpeg" => new JpegOptions { Quality = 90 },
".png" => new PngOptions(),
_ => new PngOptions() // default to PNG
};
image.Save(outputPath, opts);
}
}
// Example usage
public class Program
{
public static void Main()
{
var inputs = new List<string>
{
"image1.jpg",
"image2.png",
"image3.jpg"
};
// Horizontal strip, vertically centered, with padding/spacing
ImageMerger.Merge(
inputPaths: inputs,
axis: MergeAxis.Horizontal,
outerPadding: 20,
spacing: 10,
bgColor: Color.White,
verticalAlign: VAlign.Middle,
horizontalAlign: HAlign.Center, // ignored for horizontal axis
outputPath: "merged_horizontal.png"
);
// Vertical stack, horizontally right-aligned
ImageMerger.Merge(
inputPaths: inputs,
axis: MergeAxis.Vertical,
outerPadding: 20,
spacing: 12,
bgColor: Color.FromArgb(255, 245, 245, 245),
verticalAlign: VAlign.Middle, // ignored for vertical axis
horizontalAlign: HAlign.Right,
outputPath: "merged_vertical.jpg"
);
}
}
}
Ghidul pas cu pas
Pasul 1: Încărcați imagini
Încărcați toate imaginile cu Image.Load(path)
Păstrați-le în viață până după desenare, apoi eliminați.
Pasul 2: Determinați dimensiunea de ieșire
- Layout-ul orizontal: lățime = sumă de widths + spații + padding exterior; înălțimea = înaltă maxă + Padding exterior.
- Layout vertical: înălțime = sumă de înaltăți + spații + padding exterior; latitudine = max width + outer padding.
Pasul 3: Creați canvasul de ieșire
Creați folosind Image.Create(new PngOptions(), width, height)
(sau JpegOptions
dacă preferați o ieșire pierdută). clar cu o culoare de fundal.
Pasul 4: Configurați Alignment & Padding
- Furnizarea orizontală se calculează prin
Top / Middle / Bottom
. - Combinarea verticală se calculează prin
Left / Center / Right
. - Apply
outerPadding
şispacing
în mod consecvent.
Pasul 5: Descrieți fiecare imagine
Utilizarea Graphics.DrawImage(image, new Rectangle(x, y, image.Width, image.Height))
.
Pasul 6: Salvați rezultatul
Selectați coderul bazat pe extinderea denumirii de ieșire (de exemplu, .png
→ PngOptions
, .jpg
→ JpegOptions { Quality = … }
).
Cele mai bune practici
- Formate normalizate: Dacă aveți nevoie de fundal transparent, salvați ca PNG. Pentru fișierele mai mici fără transparență, utilizați JPEG și tune
Quality
. - Guardrails: Validați lista de intrări, gestionați fișierele lipsite și luați în considerare dimensiunile maxime ale canvasului pentru a evita OOM.
- *Disponibilă pentru:
Image
,Graphics
sunt disponibile - utilizareusing
sautry/finally
. - Color consistență: În cazul în care intrările au tipuri de culori mixte, se bazează pe defectele Aspose sau se convertează explicit atunci când este necesar.
- Batching: Pentru seturi mari, flux outputs pe măsură ce mergeți sau creați mai multe plăci / pagini.
More in this category
- Optimizarea GIF-urilor animate în .NET folosind Aspose.Imaging
- Optimizarea TIFF-urilor multi pagini pentru arhivare în .NET cu Aspose
- Animații cu date în .NET cu Aspose.Imaging
- Compararea pierderii vs. compresia imaginii fără pierderi în .NET folosind Aspose.Imaging
- Compresia imaginii fără pierderi și de calitate în .NET cu Aspose.Imaging