The task is to create a collage of several images and save it in a separate folder using WPF. I could only think of this. How to make the gluing of all images from Image [], I did not understand, as well as creating an array of images using Bitmap.

I would like to see a sample code.

public int Counter = 0; public Image[] Img = new Image[25]; public BitmapImage[] Images = new BitmapImage[25]; private void LoadClick(object sender, RoutedEventArgs e) { OpenFileDialog openDialog = new OpenFileDialog(); if (openDialog.ShowDialog() == true) { this.Image.Source = new BitmapImage(new Uri(openDialog.FileName)); Img[Counter] = this.Image; Counter++; CountImage.Text = Convert.ToString(Counter); } } private void MakeCollag(object sender, RoutedEventArgs e) { } 

    2 answers 2

    You can use the RenderTargetBitmap :

     private void MakeCollage(IEnumerable<string> imageFilenames, string outputFilename) { var collage = new Grid(); foreach (var filename in imageFilenames) { collage.Children.Add(new Image { Source = LoadBitmapImage(filename), HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Center, }); } collage.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity)); collage.Arrange(new Rect(0d, 0d, collage.DesiredSize.Width, collage.DesiredSize.Height)); var bitmap = new RenderTargetBitmap((int)collage.DesiredSize.Width, (int)collage.DesiredSize.Height, 96, 96, PixelFormats.Default); bitmap.Render(collage); bitmap.SaveAsPng(outputFilename); } 

    If you need to line up the images:

      var collage = new StackPanel { Orientation = Orientation.Horizontal }; foreach (var filename in imageFilenames) { collage.Children.Add(new Image { Source = LoadBitmapImage(filename), VerticalAlignment = VerticalAlignment.Center, Margin = new Thickness(4, 0, 0, 0) }); } 

    In general, these are ordinary controls, you can arrange everything as you like. Just in case, my version of LoadBitmapImage() :

     private static BitmapImage LoadBitmapImage(string filename) { var bi = new BitmapImage(); bi.BeginInit(); bi.CreateOptions = BitmapCreateOptions.IgnoreImageCache; bi.CacheOption = BitmapCacheOption.OnLoad; bi.UriSource = new Uri(filename); bi.EndInit(); bi.Freeze(); return bi; } 
    • If you are given an exhaustive answer, mark it as correct (a daw opposite the selected answer). - Nicolas Chabanovsky ♦
    • one
      THANKS, thanks for bi.CreateOptions = BitmapCreateOptions.IgnoreImageCache; ! I almost lost my mind while I was looking for why my program was not updating the image. I could not even guess that this klyaty BitmapImage has a bunch of caches. And again, thanks. - Ilya
    • @ Ilya, glad that helped. If you suddenly need, by the way, to display a lot of pictures from the disk, I can throw off the homemade control code - it loads asynchronously, without any converters, with a small cache (taking into account the file change date) and all that. - Surfin Bird

    Another method with RenderTargetBitmap that does not use the Grid and layout manager:

     var drawingVisual = new DrawingVisual(); using (DrawingContext drawingContext = drawingVisual.RenderOpen()) { int imageNumber = 0; int gap = 5; // расстояниС ΠΌΠ΅ΠΆΠ΄Ρƒ ΠΊΠ°Ρ€Ρ‚ΠΈΠ½ΠΊΠ°ΠΌΠΈ foreach (var image in images) { int x = imageNumber % numberOfColumns, y = imageNumber / numberOfColumns; drawingContext.DrawImage( image, new System.Windows.Rect( (pixelWidth + gap) * x, (pixelHeight + gap) * y, pixelWidth, pixelHeight)); i++; } } var bmp = new RenderTargetBitmap( (pixelWidth + gap) * numberOfColumns - gap, (pixelHeight + gap) * numberOfRows - gap, 96, 96, PixelFormats.Pbgra32); bmp.Render(drawingVisual);