简体   繁体   中英

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

The original picture: The original picture

在此处输入图像描述

How I want to display it: Original picture with mirrored image

在此处输入图像描述

So far, I believe I will need to make a copy of original picture(transformPic) into another variable (lets call it Temp), then resize transformedPic for double width. Copy Temp into transformedPic. Then I will store a mirrored image of the original picture into Temp and copy it into the second half of transformedPic.

My code so far:

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;
                        }
                    }

How can I store the Temp array(mirrored original image) into the second half of the transformedPic(original picture) and both of them one picture itself?

I have to do all this with the concepts of copying, resizing, and for looping 2D arrays.

If I understand what you are asking, you could use the following.

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;
}

Usage

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

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

Some notes:

  1. MemoryCopy is not CLS-compliant, though all you really need to do is copy the original scan line to the new scanline. It's just an extra loop and wouldn't be the much slower (if any).
  2. Span<int> here is not needed at all, but I find them neater then pointer access syntax
  3. This lacks a large amount of sanity checks and input validation
  4. You will need to mark the project to allow unsafe code. This is supper fast and efficient, and to keep that fast you will need it

Output

结果

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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