繁体   English   中英

如何在 C# 中将原始图片及其镜像合并为一个图像?

[英]How can I make a original picture and its mirrored image merge together to be one image in C#?

原图:原图

在此处输入图像描述

我想如何显示它:带有镜像的原始图片

在此处输入图像描述

到目前为止,我相信我需要将原始图片(transformPic)的副本复制到另一个变量中(我们称之为 Temp),然后将transformPic 的大小调整为双倍宽度。 将Temp复制到transformedPic中。 然后我将原始图片的镜像存储到Temp中,并将其复制到transformedPic的后半部分。

到目前为止我的代码:

int Height = transformedPic.GetLength(0); //rows
                    int Width = transformedPic.GetLength(1); //columns


                    Color Temp;
                    //copying transformedPic into temp variable
                    for (int i = 0; i < Height; i++)
                    {
                        for (int j = 0; j < Width; j++)
                        {
                            Temp = transformedPic[i, j];
                            transformedPic[i, j] = transformedPic[i, j];
                            transformedPic[i, j] = Temp;
                        }
                    }

                    //doubling the width of transformedPic
                    for (int i = 0; i < Height; i++)
                    {
                        for (int j = 0; j < Width*2; j++)
                        {
                            transformedPic[i, j-1] = transformedPic[i, j-1];
                        }
                    }

                    //copying temp into transformedPic variable
                    for (int i = 0; i < Height; i++)
                    {
                        for (int j = 0; j < Width; j++)
                        {
                            Temp = transformedPic[i, j];
                            transformedPic[i, j] = transformedPic[i, j];
                            transformedPic[i, j] = Temp;
                        }
                    }

                    //Mirroring original picture horizontally in Temp variable
                    for (int i = 0; i < Height; i++)
                    {
                        for (int j = 0; j < Width / 2; j++)
                        {
                            Temp = transformedPic[i, j];
                            transformedPic[i, j] = transformedPic[i, Width - 1 - j];
                            transformedPic[i, Width - 1 - j] = Temp;
                        }
                    }

如何将 Temp 数组(镜像原始图像)存储到transformedPic(原始图片)的后半部分,并且它们本身都是一张图片?

我必须使用复制、调整大小和循环 2D arrays 的概念来完成所有这些工作。

如果我理解您的要求,您可以使用以下内容。

public static unsafe Bitmap SomeMethod(Bitmap original)
{
   int w = original.Width, w2 = w * 2, h = original.Height;   
   var combined = new Bitmap(w*2,h);

   var originalData = original.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.ReadWrite, PixelFormat.Format32bppPArgb);
   var combineData = combined.LockBits(new Rectangle(0, 0, w2, h), ImageLockMode.ReadWrite, PixelFormat.Format32bppPArgb);

   try
   {
      var spanOrig = new ReadOnlySpan<int>(originalData.Scan0.ToPointer(),w*h );
      var spanCombined = new Span<int>(combineData.Scan0.ToPointer(), w2 * h);

      for (var y = 0; y < h; y++)
      {
         // might as well do a direct memory copy since we know part of the new image is the same
         Buffer.MemoryCopy(
             (int*)originalData.Scan0 + y * w, 
             (int*)combineData.Scan0 + y * w2, 
             w * sizeof(int), w * sizeof(int));

         for (var x = 0; x < w; x++) 
            spanCombined[w + x + y * w2] = spanOrig[w - x - 1 + y * w];
      }
   }
   finally
   {
      // unlock the bitmap
      original.UnlockBits(originalData);
      combined.UnlockBits(combineData);
   }

   return combined;
}

用法

using var original = new Bitmap(@"D:\uJRI8.jpg");
using var result = SomeMethod(original);

// safe it how you like
result.Save(@"D:\Result.bmp");

一些注意事项:

  1. MemoryCopy不符合 CLS,尽管您真正需要做的只是将原始扫描线复制到新扫描线。 这只是一个额外的循环,不会慢得多(如果有的话)。
  2. 这里根本不需要Span<int> ,但我发现它们比指针访问语法更整洁
  3. 这缺乏大量的健全性检查和输入验证
  4. 您需要标记项目以允许不安全的代码。 这是超级快速和高效的,为了保持这么快,你需要它

Output

结果

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM