เมื่อทํางานกับการประมวลผลภาพใน .NET ความต้องการทั่วไปคือการผสมภาพหลายภาพ - มักจะมีขนาดที่แตกต่างกัน - into a single output. กรณีการใช้งานทั่วไปรวมถึง collages, sprite sheets, contacts sheet, หรือ marketing banners. This tutorial shows how to merge images using Aspose.Imaging for .Net with precise control over layout: axis (horizontal/vertical), alignment (top/center/bottom and left/centry/right), extern padding, and spacing between images. We will also cover a safe, cross-platform approach that relies on Aspose’s Graphics ไฟ

สิ่งที่คุณจะสร้าง

  • **การจัดตั้ง: **แนวนอนหรือแนวตั้ง

  • *การเชื่อมโยง: *

  • การจัดตั้งแนวนอน → การปรับแนวตั้ง: Top, Middle, Bottom

  • การจัดตั้งแนวตั้ง → การปรับแนวนอน: Left, Center, Right

  • Padding: การวางภายนอกและการวางพื้นที่ระหว่างรายการ

  • **พื้นหลัง: * สีที่แข็งแกร่ง

  • รูปแบบ: โหลดรูปแบบผสม (JPG, PNG, ฯลฯ) นอกเหนือจาก P NG / JPEG

ตัวอย่างที่สมบูรณ

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

คู่มือขั้นตอน

ขั้นตอนที่ 1: ดาวน์โหลดภาพ

ดาวน์โหลดภาพเข้าทั้งหมดด้วย Image.Load(path). เก็บพวกเขาสดจนกว่าหลังจากวาดแล้วละลาย

ขั้นตอนที่ 2: การกําหนดขนาดการออก

  • การตั้งค่าแนวนอน: ความกว้าง = จํานวนความกว้าง + พื้นที่ + การวางภายนอก; ความสูง = สูงสุด + เคล็ดด้านนอก
  • การตั้งค่าแนวตั้ง: ความสูง = จํานวนความสูง + พื้นที่ + แผ่นภายนอก; ความกว้าง = ความหนาสูงสุด + เคล็ดด้านนอก

ขั้นตอนที่ 3: สร้างช่องออก

สร้างใช้ Image.Create(new PngOptions(), width, height) (หรือ JpegOptions ถ้าคุณชอบการส่งออกที่สูญเสีย) สว่างด้วยสีพื้นหลัง

ขั้นตอนที่ 4: การกําหนดค่าการสอดคล้อง & Padding

  • การเชื่อมโยงแนวนอน→คํานวณ Y โดย Top / Middle / Bottom.
  • การเชื่อมต่อแนวตั้ง → การคํานวณ X โดย Left / Center / Right.
  • Apply outerPadding และ spacing ทั่วไป

ขั้นตอน 5: การวาดภาพแต่ละภาพ

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

ขั้นตอนที่ 6: เก็บผล

เลือกตัวเข้ารหัสตามการขยายชื่อไฟล์ออก (เช่น .pngPngOptions, .jpgJpegOptions { Quality = … }).

แนวทางที่ดีที่สุด

  • รูปแบบมาตรฐาน: หากคุณต้องการพื้นหลังที่โปร่งใสให้บันทึกเป็น PNG สําหรับไฟล์ขนาดเล็กโดยไม่มีการเปิดเผยใช้ JPEG และ Tune Quality.
  • Guardrails: ตรวจสอบรายการป้อนการจัดการไฟล์ที่หายไปและพิจารณาขนาดช่องสูงสุดเพื่อหลีกเลี่ยง OOM
    • มีบริการ *: Image, Graphics สามารถใช้ได้ - ใช้ได้ using หรือ try/finally.
  • ความสม่ําเสมอของสี: หากรายการมีประเภทสีผสมขึ้นอยู่กับข้อกําหนดของ Aspose หรือแปลงอย่างชัดเจนเมื่อจําเป็น
  • Batching: สําหรับชุดขนาดใหญ่ส่งออกเมื่อคุณไปหรือสร้างแผ่น / หน้าหลาย

More in this category