Bij het werken met beeldverwerking in .NET, een gemeenschappelijke behoefte is om meerdere afbeeldingen – vaak van verschillende grootte – in een enkele output te fuseren. Typische gebruik gevallen omvatten collages, sprite bladeren, contactbladeren of marketing banners. Dit tutorial toont hoe om beelden met behulp van Aspose.Imaging voor .Net met nauwkeurige controle over de layout: axis (horizontale/verticale), alignment (top/center/bottom en links/centrum/right), externe padding, en spacing tussen de foto’s. We zullen ook een veilige, cross-platform benadering die gebaseerd is op Aspose Graphics Het vuur.

Wat je zal bouwen

  • *Layout: horizontale of verticale

    • De aanpassing: *
  • Horisontaal layout → verticale aanpassing: Top, Middle, Bottom

  • Verticale layout → horizontale aanpassing: Left, Center, Right

  • Padding: Outer padding en inter-item spacing

    • achtergrond: * vaste kleur vullen
  • Formaten: laden gemengde formaten (JPG, PNG, etc.), met uitzondering van P NG/JPEG

Volledige voorbeeld

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"
            );
        }
    }
}

Step-by-step gids

Stap 1: Afbeeldingen opladen

Laden alle ingebouwde afbeeldingen met Image.Load(path)Houd ze levend tot na het tekenen, vervolgens los.

Stap 2: Het bepalen van de uitlaatgrootte

  • Horizontale layout: breedte = sum van breedten + ruimtes + buiten paddingen; hoogte = max hoogte + buitend padding.
  • Verticale layout: hoogte = sum van hoogte + ruimtes + buiten paddings; breedte = max brede + buitenaard padding.

Stap 3: Creëren van de Output Canvas

Creëer met gebruik Image.Create(new PngOptions(), width, height) (of JpegOptions als je liever lossy output). Clear met een achtergrondkleur.

Stap 4: Configure Alignment & Padding

  • Horizontale fusie → berekenen Y door Top / Middle / Bottom.
  • Verticale fusie → berekenen X door Left / Center / Right.
  • Apply outerPadding en spacing consistent zijn.

Stap 5: Maak elke afbeelding

Gebruik Graphics.DrawImage(image, new Rectangle(x, y, image.Width, image.Height)).

Stap 6: Bespaar het resultaat

Kies de encoder op basis van de output filename uitbreiding (bijv. .pngPngOptions, .jpgJpegOptions { Quality = … }).

Beste praktijken

  • Normale formaten: Als u transparante achtergronden nodig hebt, sla als PNG. Voor kleinere bestanden zonder transparantie, gebruik JPEG en tune Quality.
  • Guardrails: Valideer de invoerlijst, beheer verdwenen bestanden en overwegen de maximale kanvasdimensies om OOM te vermijden.
    • Toegankelijk voor: Image, Graphics beschikbaar - gebruik using of try/finally.
  • Kleurconsistentie: Als de inputs gemengde kleurtypen hebben, vertrouwen op Aspose-default of omschakelen uitdrukkelijk wanneer nodig.
  • Batching: Voor grote sets, stroom uitgangen als je gaat of creëren meerdere plaatjes/pagina’s.

More in this category