عند العمل مع معالجة الصور في .NET ، فإن الحاجة الشائعة هي دمج العديد من الصور - غالبًا ما تكون من أحجام مختلفة - في إصدار واحد. وتشمل حالات الاستخدام النموذجية الكولاج أو أوراق الشريط أو ورقات الاتصال أو علامات التسويق. يظهر هذا الدليل كيفية دمجه الصور باستخدام Aspose.Imaging for .Net مع التحكم الدقيق في التصميم: محور (الأفقية / العمودية) ، التوافق (الوسط / الأسفل واليسار / المركز / اليمين) و الرفع الخارجي ، والمرحلة بين الصور. Graphics النار

ماذا ستبني

    • ترتيب: * أفقية أو عمودية
    • تخصيص : *
  • التخطيط الأفقي للتصحيح العمودي: Top, Middle, Bottom

  • التخطيط الرأسي هو التوافق الأفقي: Left, Center, Right

  • الإضافة: الإضافة الخارجية والإضافة بين العناصر

    • الخلفية: * ملء اللون الصلب
  • الشكلات: الشحن النماذج المختلطة (JPG، PNG، إلخ)، باستثناء لPNG/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"
            );
        }
    }
}

دليل خطوة بخطوة

الخطوة الأولى: تحميل الصور

قم بتحميل جميع الصور مع Image.Load(path)الحفاظ عليها على قيد الحياة حتى بعد رسمها ، ثم إزالتها.

الخطوة 2: تحديد حجم الخروج

  • الترتيب الأفقي: العرض = إجمالي الأوساط + المساحات + الطابق الخارجي؛ الارتفاع = الحد الأقصى للطابق الخلفي.
  • الترتيب الرأسي: ارتفاع = مجموع الارتفاعات + المساحات + الرفع الخارجي ؛ العرض = الحد الأقصى للعرض الخلفي.

الخطوة 3: إنشاء قناة الخروج

خلق باستخدام Image.Create(new PngOptions(), width, height) (أو JpegOptions إذا كنت تفضل الخروج الخسارة) واضح مع لون الخلفية.

الخطوة 4: إعداد التكيف والضغط

  • الترابط الأفقي → حساب 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.
  • الشرائح: تأكيد قائمة الإدخالات، والتعامل مع الملفات المفقودة، وتفكر في أقصى حجم من الحوض لتجنب OOM.
    • متوفرة * : Image, Graphics قابلة للاستخدام - تستخدم using أو try/finally.
  • التوافق بين الألوان: إذا كانت الإدخالات لها أنواع ملونة مختلطة، تعتمد على عيوب Aspose، أو تحويل صراحة عند الحاجة.
  • Batching: بالنسبة للمجموعات الكبيرة، تدفق النتائج أثناء الذهاب أو إنشاء العديد من الألواح / الصفحات.

More in this category