如何获取图像目录并在单个图像中输出图像的网格

时间:2015-05-05 01:49:36

标签: c#

最近有人问我是否有办法制作一个程序,可以输出一个包含来自源目录的图像网格的图像,其中自定义的列数应该确定行数。

起初,我在许多免费的照片编辑平台上完成了这个概念,但是在详细解释了这种情况之后,我认为这可能值得花30分钟来写它只是为了他们自己的理智和时间节省。

1 个答案:

答案 0 :(得分:3)

首先,您需要一种方法来阅读图像:

using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Grimager.ImageProcessing
{
    public class ImageReader
    {
        protected string[] Files { get; set; }

        public ImageReader(string path)
        {
            Files = Directory.GetFiles(path);
        }

        public IEnumerable<Image> GetImages()
        {
            foreach (var f in Files.OrderBy(x => x))
            {
                yield return Image.FromFile(f);
            }
        }
    }
}

接下来,图像处理。给定一些列,图像之间的间距,以及一个数字框,说明图像的索引是什么布局可以相当简单地计算:

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Grimager.ImageProcessing
{
    public class ImageProcessor
    {
        protected int Columns { get; set; }

        public ImageProcessor(int columns)
        {
            Columns = columns;
        }

        public string[] ProcessTo(string sourceDirectory, string outputFile)
        {
            var reader = new ImageReader(sourceDirectory);
            int idx = 1;
            var cfg = Settings.Get();
            var images = new List<Image>();
            foreach (var original in reader.GetImages())
            {
                var img = ResizeImage(original, cfg.Width, cfg.Height);
                using (var graphic = Graphics.FromImage(img))
                {
                    graphic.FillRectangle(Brushes.White, new Rectangle(0, 0, cfg.LetterBoxSize, cfg.LetterBoxSize));
                    using (var font = new Font("Arial", cfg.LetterBoxSize - 1))
                    {
                        graphic.DrawString(idx.ToString(), font, Brushes.Red, new PointF(0,0));
                    }
                }
                images.Add(img);
                idx++;
            }

            var totalImages = images.Count();
            var totalRows = (int) Math.Ceiling(totalImages/(double)Columns);
            var totalWidth = Columns*cfg.Width + ((Columns - 1) * cfg.Spacing);
            var totalHeight = totalRows * cfg.Height + ((totalRows-1) * cfg.Spacing);
            var output = new Bitmap(totalWidth, totalHeight);
            var row = 0;
            using (var graphic = Graphics.FromImage(output))
            {
                for (var i = 0; i < totalImages; i++)
                {
                    if (i> 0 && i%Columns == 0)
                        row++;

                    var column = i%Columns;

                    var x = column*cfg.Width;
                    if (column > 0)
                    {
                        x += cfg.Spacing*column;
                    }
                    var y = row*cfg.Height;

                    if (row > 0)
                    {
                        y += cfg.Spacing*row;
                    }

                    graphic.DrawImage(images[i], new Rectangle(new Point(x,y), new Size(cfg.Width, cfg.Height)));
                }
            }

            output.Save(outputFile, ImageFormat.Jpeg);

            return new string[0];
        }

        protected Image ResizeImage(Image image, int width, int height)
        {
            var destRect = new Rectangle(0, 0, width, height);
            var destImage = new Bitmap(width, height);

            destImage.SetResolution(image.HorizontalResolution, image.VerticalResolution);

            using (var graphics = Graphics.FromImage(destImage))
            {
                graphics.CompositingMode = CompositingMode.SourceCopy;
                graphics.CompositingQuality = CompositingQuality.HighQuality;
                graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
                graphics.SmoothingMode = SmoothingMode.HighQuality;
                graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;

                using (var wrapMode = new ImageAttributes())
                {
                    wrapMode.SetWrapMode(WrapMode.TileFlipXY);
                    graphics.DrawImage(image, destRect, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, wrapMode);
                }
            }

            return destImage;
        }
    }
}

不是真正最伟大的&#34;如何&#34;&#34;在堆栈溢出,但决定,因为我被要求写它我会分享,也许可以在那里保存一些其他可怜的灵魂。

完整的源代码可在GitHub的公共域下获得: The Grimager