最近有人问我是否有办法制作一个程序,可以输出一个包含来自源目录的图像网格的图像,其中自定义的列数应该确定行数。
起初,我在许多免费的照片编辑平台上完成了这个概念,但是在详细解释了这种情况之后,我认为这可能值得花30分钟来写它只是为了他们自己的理智和时间节省。
答案 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