WPF图像水平镜像和垂直镜像处理

    目的:实现图像的水平镜像和垂直镜像功能。

  • xaml代码 
<Window x:Class="ImageProcess_Mirror.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:ImageProcess_Mirror"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition Height="auto"/>
        </Grid.RowDefinitions>
        <Image Name="img" Stretch="Uniform"/>
        <StackPanel Grid.Row="1" Orientation="Horizontal">
            <Button Content="Load Bitmap" Margin="5" Click="Load_Click"/>
            <Button Content="HorizontalMirror" Margin="5" Click="HorizontalMirror_Click"/>
            <Button Content="VerticalMirror" Margin="5" Click="VerticalMirror_Click"/>
        </StackPanel>
    </Grid>
</Window>
  • 后台代码
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;

namespace ImageProcess_Mirror
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private Bitmap ImageSourceToBitmap(ImageSource imageSource)
        {
            BitmapSource bitmapSource = (BitmapSource)imageSource;
            Bitmap bmp = new Bitmap(bitmapSource.PixelWidth, bitmapSource.PixelHeight, System.Drawing.Imaging.PixelFormat.Format32bppPArgb);
            BitmapData data = bmp.LockBits(
                new System.Drawing.Rectangle(System.Drawing.Point.Empty, bmp.Size), ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppPArgb);
            bitmapSource.CopyPixels(Int32Rect.Empty, data.Scan0, data.Height * data.Stride, data.Stride);
            bmp.UnlockBits(data);
            return bmp;
        }

        private BitmapImage BitmapToBitmapImage(Bitmap bitmap)
        {
            using (MemoryStream stream = new MemoryStream())
            {
                bitmap.Save(stream, ImageFormat.Png);
                stream.Position = 0;
                BitmapImage result = new BitmapImage();
                result.BeginInit();
                result.CacheOption = BitmapCacheOption.OnLoad;
                result.StreamSource = stream;
                result.EndInit();
                result.Freeze();
                return result;
            }
        }

        private void BitmapMirror(Bitmap curBitmap, int width, int height, int direction)
        {
            Rectangle rect = new Rectangle(0, 0, width, height);
            BitmapData bmpData = curBitmap.LockBits(rect, ImageLockMode.ReadWrite, curBitmap.PixelFormat);
            IntPtr ptr = bmpData.Scan0;
            int bytes = width * height * 4;
            byte[] rgbValues = new byte[bytes];
            Marshal.Copy(ptr, rgbValues, 0, bytes);
            int halfWidth = width / 2;
            int halfHeight = height / 2;
            byte temp;
            if (direction == 0)
            {
                for (int i = 0; i < height; i++)
                {
                    for (int j = 0; j < halfWidth; j++)
                    {
                        int index1 = i * width * 4 + 4 * j;               // B
                        int index2 = (i + 1) * width * 4 - (1 + j) * 4;
                        temp = rgbValues[index1];
                        rgbValues[index1] = rgbValues[index2];
                        rgbValues[index2] = temp;
                        index1 = i * width * 4 + 4 * j + 1;               // G
                        index2 = (i + 1) * width * 4 - (1 + j) * 4 + 1;
                        temp = rgbValues[index1];
                        rgbValues[index1] = rgbValues[index2];
                        rgbValues[index2] = temp;
                        index1 = i * width * 4 + 4 * j + 2;               // R
                        index2 = (i + 1) * width * 4 - (1 + j) * 4 + 2;
                        temp = rgbValues[index1];
                        rgbValues[index1] = rgbValues[index2];
                        rgbValues[index2] = temp;
                        index1 = i * width * 4 + 4 * j + 3;               // A
                        index2 = (i + 1) * width * 4 - (1 + j) * 4 + 3;
                        temp = rgbValues[index1];
                        rgbValues[index1] = rgbValues[index2];
                        rgbValues[index2] = temp;
                    }
                }
            }
            else
            {
                for (int i = 0; i < width; i++)
                {
                    for (int j = 0; j < halfHeight; j++)
                    {
                        int index1 = j * width * 4 + i * 4;
                        int index2 = (height - j - 1) * width * 4 + i * 4;    // B
                        temp = rgbValues[index1];
                        rgbValues[index1] = rgbValues[index2];
                        rgbValues[index2] = temp;
                        index1 = j * width * 4 + i * 4 + 1;
                        index2 = (height - j - 1) * width * 4 + i * 4 + 1;    // G
                        temp = rgbValues[index1];
                        rgbValues[index1] = rgbValues[index2];
                        rgbValues[index2] = temp;
                        index1 = j * width * 4 + i * 4 + 2;
                        index2 = (height - j - 1) * width * 4 + i * 4 + 2;    // R
                        temp = rgbValues[index1];
                        rgbValues[index1] = rgbValues[index2];
                        rgbValues[index2] = temp;
                        index1 = j * width * 4 + i * 4 + 3;
                        index2 = (height - j - 1) * width * 4 + i * 4 + 3;    // A
                        temp = rgbValues[index1];
                        rgbValues[index1] = rgbValues[index2];
                        rgbValues[index2] = temp;
                    }
                }
            }
            Marshal.Copy(rgbValues, 0, ptr, bytes);
            curBitmap.UnlockBits(bmpData);
        }

        private void VerticalMirror_Click(object sender, RoutedEventArgs e)
        {
            Bitmap bitmap = ImageSourceToBitmap(img.Source);
            BitmapMirror(bitmap, bitmap.Width, bitmap.Height, 1);
            img.Source = BitmapToBitmapImage(bitmap);
        }

        private void HorizontalMirror_Click(object sender, RoutedEventArgs e)
        {
            Bitmap bitmap = ImageSourceToBitmap(img.Source);
            BitmapMirror(bitmap, bitmap.Width, bitmap.Height, 0);
            img.Source = BitmapToBitmapImage(bitmap);
        }

        private void Load_Click(object sender, RoutedEventArgs e)
        {
            img.Source = new BitmapImage(new Uri(@"D:\程序项目目录\ImgList\World.jpg", UriKind.RelativeOrAbsolute));
        }
    }
}

    技术要点:图像处理采用LockBits方式,效率高;比较纠结的是序号问题。

猜你喜欢

转载自blog.csdn.net/u012366767/article/details/81504515