【问题标题】:Merge two images to create a single image in C#.Net在 C#.Net 中合并两个图像以创建单个图像
【发布时间】:2011-09-17 00:12:15
【问题描述】:

我有一个要求,我需要使用 C#.Net 将两个不同的 png/jpeg 图像合并成一个图像。源图像上将定义一个特定位置,我需要在其中插入另一个图像。谁能推荐一些链接?

【问题讨论】:

标签: c# .net image-manipulation


【解决方案1】:
private void Merge _Click(object sender, EventArgs e)
{
}
DirectoryInfo directory=new DirectoryInfo("D:\\Images");
if(directory!=null)
{
    FileInfo[]files = directory.GetFiles();
    MergeImages(Image);
}

private void MergeImages(FileInfo[] Image)
{
    //change the location to store the final image.
    string FImage= @"D:\\Images\\FImage.jpg";
    List imageHeights = new List();
    int nIndex = 0;
    int width = 0;
    foreach (FileInfo file in files)
    {
        Image img = Image.FromFile(file.FullName);
        imageHeights.Add(img.Height);
        width += img.Width;
        img.Dispose();
    }
    imageHeights.Sort();
    int height = imageHeights[imageHeights.Count - 1];
    Bitmap NewImg = new Bitmap(width, height);
    Graphics Gr= Graphics.FromImage(NewImg);
    Gr.Clear(SystemColors.AppWorkspace);
    foreach (FileInfo file in files)
    {
        Image img = Image.FromFile(file.FullName);
        if (nIndex == 0)
        {
            Gr.DrawImage(img, new Point(0, 0));
            nIndex++;
            width = img.Width;
        }
        else
        {
            Gr.DrawImage(img, new Point(width, 0));
            width += img.Width;
        }
            img.Dispose();
    }
    Gr.Dispose();
    NewImg .Save(FImage, System.Drawing.Imaging.ImageFormat.Jpeg);
    NewImg .Dispose();
    imageLocation.Image = Image.FromFile(FImage);
}

【讨论】:

    【解决方案2】:

    我在http://bookingbillboard.com/API 有相应的 api。这个api将结合2张图片。 1 张图片是您的图片/设计/海报,其他图片是广告牌的照片。通过使用 API,您可以在广告牌的照片中看到您的设计/图像/海报的样子

    【讨论】:

      【解决方案3】:

      在这一切之后,我找到了一个新的更简单的方法试试这个..

      它可以将多张照片拼接在一起:

      public static System.Drawing.Bitmap CombineBitmap(string[] files)
      {
          //read all images into memory
          List<System.Drawing.Bitmap> images = new List<System.Drawing.Bitmap>();
          System.Drawing.Bitmap finalImage = null;
      
          try
          {
              int width = 0;
              int height = 0;
      
              foreach (string image in files)
              {
                  //create a Bitmap from the file and add it to the list
                  System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(image);
      
                  //update the size of the final bitmap
                  width += bitmap.Width;
                  height = bitmap.Height > height ? bitmap.Height : height;
      
                  images.Add(bitmap);
              }
      
              //create a bitmap to hold the combined image
              finalImage = new System.Drawing.Bitmap(width, height);
      
              //get a graphics object from the image so we can draw on it
              using (System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(finalImage))
              {
                  //set background color
                  g.Clear(System.Drawing.Color.Black);
      
                  //go through each image and draw it on the final image
                  int offset = 0;
                  foreach (System.Drawing.Bitmap image in images)
                  {
                      g.DrawImage(image,
                        new System.Drawing.Rectangle(offset, 0, image.Width, image.Height));
                      offset += image.Width;
                  }
              }
      
              return finalImage;
          }
          catch (Exception)
          {
              if (finalImage != null)
                  finalImage.Dispose();
              //throw ex;
              throw;
          }
          finally
          {
              //clean up memory
              foreach (System.Drawing.Bitmap image in images)
              {
                  image.Dispose();
              }
          }
      }
      

      【讨论】:

      • 太棒了,感谢您的代码-但永远不要“扔前”-总是只是“扔”。您正在重置堆栈,否则无法进行调试!
      • 这段代码为我生成了一个最终图像,其宽度是原始图像的两倍(高度保持正常)
      • @PabloCosta 是的,如果你看到上面的代码height = bitmap.Height &gt; height ? bitmap.Height : height; 新创建的图像的高度将是所有图像的最大值。
      【解决方案4】:
              String jpg1 = @"c:\images.jpeg";
              String jpg2 = @"c:\images2.jpeg";
              String jpg3 = @"c:\image3.jpg";
      
              Image img1 = Image.FromFile(jpg1);
              Image img2 = Image.FromFile(jpg2);
      
              int width = img1.Width + img2.Width;
              int height = Math.Max(img1.Height, img2.Height);
      
              Bitmap img3 = new Bitmap(width, height);
              Graphics g = Graphics.FromImage(img3);
      
              g.Clear(Color.Black);
              g.DrawImage(img1, new Point(0, 0));
              g.DrawImage(img2, new Point(img1.Width, 0));
      
              g.Dispose();
              img1.Dispose();
              img2.Dispose();
      
              img3.Save(jpg3, System.Drawing.Imaging.ImageFormat.Jpeg);
              img3.Dispose();
      

      【讨论】:

      • 我按照您的方法尝试了类似的方法。我设置了更大的宽度,当我绘制图像时,将显示一个灰色区域。如何将该区域更改为我喜欢的白色或其他纯色?
      【解决方案5】:

      此方法合并两张图片,一张在另一张的顶部,您可以修改代码以满足您的需求:

          public static Bitmap MergeTwoImages(Image firstImage, Image secondImage)
          {
              if (firstImage == null)
              {
                  throw new ArgumentNullException("firstImage");
              }
      
              if (secondImage == null)
              {
                  throw new ArgumentNullException("secondImage");
              }
      
              int outputImageWidth = firstImage.Width > secondImage.Width ? firstImage.Width : secondImage.Width;
      
              int outputImageHeight = firstImage.Height + secondImage.Height + 1;
      
              Bitmap outputImage = new Bitmap(outputImageWidth, outputImageHeight, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
      
              using (Graphics graphics = Graphics.FromImage(outputImage))
              {
                  graphics.DrawImage(firstImage, new Rectangle(new Point(), firstImage.Size),
                      new Rectangle(new Point(), firstImage.Size), GraphicsUnit.Pixel);
                  graphics.DrawImage(secondImage, new Rectangle(new Point(0, firstImage.Height + 1), secondImage.Size),
                      new Rectangle(new Point(), secondImage.Size), GraphicsUnit.Pixel);
              }
      
              return outputImage;
          }
      

      【讨论】:

      • 为什么是 Format32bppArgb?
      • @Toolkit:据我所知,当你使用带有两个参数的构造函数重载时,(width, height)它将创建一个24bit 版本,即Format24bppRgb。如果原始图像包含一个,因此将丢失原始图像的 alpha 通道信息,因此 Format32bppArgb。不过,我相信如果您从原始图像中获得适当的格式而不是内联 Format32bppArgb 的东西会更方便...
      • 效果很好,但我认为没有必要在两个图像之间添加 1 个像素的高度
      【解决方案6】:

      免责声明:我在 Atalasoft 工作

      我们的DotImage Photo SDK(免费)可以做到这一点。

      打开图片

       AtalaImage botImage = new AtalaImage("bottomImage.png");
       AtalaImage topImage = new AtalaImage("topImage.png");
      

      将一个叠加在另一个之上

       Point pos = new Point(0,0); // or whatever you need
       OverlayCommand cmd = new OverlayCommand(topImage, pos);
       ImageResults res = cmd.Apply(botImage);
      

      如果您需要生成不同大小的图像,请查看CanvasCommand。您还可以创建所需大小的 AtalaImage,然后将每个图像叠加到其上。

      保存

       botImage.Save("newImage.png", new PngEncoder(), null);
      

      【讨论】:

      • DotImage Photo SDK 不再免费。 :(
      • 很抱歉——我不再在那里工作了。这个问题的其他答案应该仍然适合你。
      猜你喜欢
      • 2020-06-11
      • 2015-11-12
      • 2010-10-02
      • 1970-01-01
      • 1970-01-01
      • 2011-01-20
      相关资源
      最近更新 更多