Lorsque vous travaillez avec le traitement d’image dans .NET, une nécessité commune est de fusionner plusieurs images – souvent de différentes tailles – dans une seule sortie. cas d’utilisation typiques comprennent des collages, des feuilles de sprite, les panneaux de contact, ou des bannières de marketing. Ce tutoriel montre comment fuser des images en utilisant Aspose.Imaging pour .Net avec un contrôle précis sur le layout: axe (horizontal/vertical), alignement (top/center/bottom et gauche/centre/droit), placement extérieur, et espace entre les images. Nous couvrirons également une approche sécurisée, cross-platform qui repose sur Aspose Graphics Le feu.

Ce que vous construirez

    • Layout : horizontal ou vertical
    • L’affichage : *
  • Layout horizontal à l’alignement vertical : Top, Middle, Bottom

  • Layout verticale à l’alignement horizontal : Left, Center, Right

  • Padding: outer padding et inter-item spacing

  • Background: Fille de couleur solide

  • Formats: Formats mélangés de charge (JPG, PNG, etc.), à l’exception de P NG/JPEG

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

Guide étape par étape

Étape 1 : Télécharger les images

Téléchargez toutes les images avec Image.Load(path)Gardez-les vivants jusqu’à ce qu’ils soient dessinés, puis disparaissez.

Étape 2 : Déterminer la taille de la sortie

  • Layout horizontal: largeur = somme de largeurs + espaces + couverture extérieure; hauteur = hauteur max + Couvertures extérieures.
  • Layout verticale: hauteur = somme des hauteurs + espaces + plafond extérieur; largeur = width max + plongée extérieure.

Étape 3 : Créer le canvas de sortie

Créer en utilisant Image.Create(new PngOptions(), width, height) (ou JpegOptions si vous préférez la sortie de perte). clair avec une couleur de fond.

Étape 4 : Configurer Alignment & Padding

  • Fusion horizontale → calculer Y par Top / Middle / Bottom.
  • Fusion verticale → calculer X par Left / Center / Right.
  • Apply outerPadding et spacing de manière cohérente.

Étape 5 : dessiner chaque image

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

Étape 6 : Sauver le résultat

Choisissez l’encodateur en fonction de la extension de nom de fichier de sortie (par exemple, .pngPngOptions, .jpgJpegOptions { Quality = … }).

Migliori pratiche

  • Normalisez les formats: Si vous avez besoin de fonds transparents, sauvez en tant que PNG. Pour les fichiers plus petits sans transparence, utilisez JPEG et tune Quality.
  • Guardrails: Valider la liste d’entrée, gérer les fichiers manquants et prendre en compte les dimensions maximales du canvas pour éviter OOM.
    • Disponible pour : Image, Graphics Disponible - Utilisation using ou try/finally.
  • Consistance des couleurs: Si les entrées ont des types de couleurs mixtes, dépendez des défauts Aspose ou convertez explicitement lorsque nécessaire.
  • Batching: Pour les grands ensembles, fluctuez les sorties lorsque vous allez ou créez plusieurs panneaux/pages.

More in this category