Khi làm việc với xử lý hình ảnh trong .NET, một nhu cầu phổ biến là để kết hợp nhiều bức ảnh - thường có kích thước khác nhau - vào một sản phẩm duy nhất. trường hợp sử dụng thông thường bao gồm collages, sprite sheets, contact sheet, hoặc marketing banners. hướng dẫn này cho thấy làm thế nào để hòa hợp hình dung bằng cách sửطة Aspose.Imaging for .Net với kiểm soát chính xác về bố trí: axis (horizontal/vertical), alignment (top/center/bottom và left/central/right), bên ngoài padding, và spacing giữa các bức tranh. Chúng tôi cũng sẽ bao phủ một cách tiếp cận an toàn, cross-platform dựa trên Aspose Graphics Lửa

Những gì bạn sẽ xây dựng

    • Layout: * ngang hoặc dọc
    • Đánh giá: *
  • Layout horizontal → kết hợp dọc: Top, Middle, Bottom

  • Layout ngang → định hướng ngang: Left, Center, Right

  • Padding: outer padding và inter-item spacing

  • Background: đầy màu sắc vững chắc

  • ** Định dạng:** tải các định dạng hỗn hợp (JPG, PNG, v.v.), ngoại trừ Png/JPEG

Một ví dụ đầy đủ

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

Hướng dẫn Step-by-Step

Bước 1: tải hình ảnh

tải tất cả các hình ảnh nhập với Image.Load(path)Giữ chúng sống cho đến khi sau khi vẽ, sau đó tháo rời.

Bước 2: Xác định kích thước xuất khẩu

  • Horizontal layout: width = sum of widts + spacings + outer padding; cao = max height + outside paddding.
  • Layout dọc*: chiều cao = tổng số độ cao + không gian + cổng bên ngoài; chiều rộng = bề rộng tối đa + Cổng Bên ngoài.

Bước 3: Tạo Canvas Output

Tạo sử dụng Image.Create(new PngOptions(), width, height) (hoặc JpegOptions nếu bạn thích output lossy). rõ ràng với một màu nền.

Bước 4: Cài đặt Alignment & Padding

  • Horizontal merge → tính toán Y by Top / Middle / Bottom.
  • Vertical merge → tính toán X by Left / Center / Right.
  • Apply outerPaddingspacing liên tục .

Bước 5: Sẽ mỗi hình ảnh

Sử dụng Graphics.DrawImage(image, new Rectangle(x, y, image.Width, image.Height)).

Bước 6: Tiết kiệm kết quả

Chọn mã hóa dựa trên phần mở rộng tên tệp xuất khẩu (ví dụ: .pngPngOptions, .jpgJpegOptions { Quality = … }).

Thực hành tốt nhất

  • Normalize formats: Nếu bạn cần nền minh bạch, hãy lưu nó như PNG. Đối với các tệp nhỏ hơn mà không có độ sáng, sử dụng JPEG và tune Quality.
  • Guardrails: Chứng nhận danh sách nhập, xử lý các tập tin bị mất, và xem xét kích thước canvas tối đa để tránh OOM.
    • Có sẵn *: Image, Graphics Có thể sử dụng - Use using hoặc try/finally.
    • Màu sắc nhất quán**: Nếu nhập có các loại màu pha trộn, hãy dựa vào mặc định Aspose hoặc chuyển đổi rõ ràng khi cần thiết.
  • Batching: Đối với các bộ lớn, stream outputs khi bạn đi hoặc tạo nhiều tấm / trang.

More in this category