在WPF中合并多个PNG图像为单个图像

7
我正在寻找一种将多个PNG瓦片图像合并成一个大图像的方法。因此,我进行了搜索并找到了一些链接。这个没有得到恰当的回答。这个不是平铺,它适用于叠加图像和这个不使用WPF。所以我提出了这个问题。 问题定义: 我有4个PNG图像。我想将它们合并成一个单独的PNG图像,就像这样:
-------------------
|        |        |
|  png1  |  png2  |
|        |        |
-------------------
|        |        |
|  png3  |  png4  |
|        |        |
-------------------

问题:

如何以最佳和高效的方式完成此操作(生成的图像必须为PNG格式)?


连接操作是与保存操作相互独立的问题。一旦完成位图连接,您可以将其以任何支持的格式进行保存。 - ChrisF
1个回答

18
// Loads the images to tile (no need to specify PngBitmapDecoder, the correct decoder is automatically selected)
BitmapFrame frame1 = BitmapDecoder.Create(new Uri(path1), BitmapCreateOptions.None, BitmapCacheOption.OnLoad).Frames.First();
BitmapFrame frame2 = BitmapDecoder.Create(new Uri(path2), BitmapCreateOptions.None, BitmapCacheOption.OnLoad).Frames.First();
BitmapFrame frame3 = BitmapDecoder.Create(new Uri(path3), BitmapCreateOptions.None, BitmapCacheOption.OnLoad).Frames.First();
BitmapFrame frame4 = BitmapDecoder.Create(new Uri(path4), BitmapCreateOptions.None, BitmapCacheOption.OnLoad).Frames.First();

// Gets the size of the images (I assume each image has the same size)
int imageWidth = frame1.PixelWidth;
int imageHeight = frame1.PixelHeight;

// Draws the images into a DrawingVisual component
DrawingVisual drawingVisual = new DrawingVisual();
using (DrawingContext drawingContext = drawingVisual.RenderOpen())
{
    drawingContext.DrawImage(frame1, new Rect(0, 0, imageWidth, imageHeight));
    drawingContext.DrawImage(frame2, new Rect(imageWidth, 0, imageWidth, imageHeight));
    drawingContext.DrawImage(frame3, new Rect(0, imageHeight, imageWidth, imageHeight));
    drawingContext.DrawImage(frame4, new Rect(imageWidth, imageHeight, imageWidth, imageHeight));
}

// Converts the Visual (DrawingVisual) into a BitmapSource
RenderTargetBitmap bmp = new RenderTargetBitmap(imageWidth * 2, imageHeight * 2, 96, 96, PixelFormats.Pbgra32);
bmp.Render(drawingVisual);

// Creates a PngBitmapEncoder and adds the BitmapSource to the frames of the encoder
PngBitmapEncoder encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(bmp));

// Saves the image into a file using the encoder
using (Stream stream = File.Create(pathTileImage))
    encoder.Save(stream);

@HosseinNarimaniRad 我决定使用另一种方法。使用 WPF! - Cédric Bignon
@HosseinNarimaniRad 我已经在代码中添加了注释(_无需指定PngBitmapDecoder,正确的解码器会自动选择_) - Cédric Bignon
@HosseinNarimaniRad 我已经在代码末尾将 File.OpenWrite 替换为 _File.Create_。 - Cédric Bignon
这会有很大的区别吗? - Hossein Narimani Rad
顺便提一下,当我合并4个30k-PNG图像时,生成的图像大小为500kb。这是正常的吗? - Hossein Narimani Rad
1
如果文件已经存在,OpenWrite将只用新字节替换它写入的内容(如果先前的文件为500KB,而流只写入了200KB,则文件仍将为500KB)。Create会删除先前文件的内容,然后添加新内容。@HosseinNarimaniRad - Cédric Bignon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接