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

<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方式,效率高;比较纠结的是序号问题。