图像灰度拉神,主要是将图像的灰度拉伸至全灰度区间,计算公式如下:
- xaml代码
<Window x:Class="ImageProcess_GrayStretch.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_GrayStretch"
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="Gray Stretch" Margin="5" Click="GrayStretch_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_GrayStretch
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private byte GetMaxValue(byte[] rgbValues)
{
byte maxi = rgbValues[0];
for (int i = 0; i < rgbValues.Length; i++)
{
if (maxi < rgbValues[i])
{
maxi = rgbValues[i];
}
}
return maxi;
}
private byte GetMinValue(byte[] rgbValues)
{
byte mini = rgbValues[0];
for (int i = 0; i < rgbValues.Length; i++)
{
if (mini > rgbValues[i])
{
mini = rgbValues[i];
}
}
return mini;
}
private void BitmapGrayStretch(Bitmap curBitmap, int width, int height)
{
System.Drawing.Rectangle rect = new System.Drawing.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);
byte[] matGray = new byte[width * height];
for (int i = 0; i < rgbValues.Length; i = i + 4)
{
byte alpha = rgbValues[i + 3];
byte red = rgbValues[i + 2];
byte green = rgbValues[i + 1];
byte blue = rgbValues[i];
byte gray = (byte)(red * 0.299 + green * 0.587 + blue * 0.114);
matGray[i / 4] = gray;
}
byte maxGray = GetMaxValue(matGray);
byte minGray = GetMinValue(matGray);
double f = 0;
if (maxGray != minGray)
{
f = 255.0 / (maxGray - minGray);
}
for (int i = 0; i < rgbValues.Length; i = i + 4)
{
rgbValues[i] = (byte)(f * (matGray[i / 4] - minGray));
rgbValues[i + 1] = (byte)(f * (matGray[i / 4] - minGray));
rgbValues[i + 2] = (byte)(f * (matGray[i / 4] - minGray));
}
Marshal.Copy(rgbValues, 0, ptr, bytes);
curBitmap.UnlockBits(bmpData);
}
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 Load_Click(object sender, RoutedEventArgs e)
{
img.Source = new BitmapImage(new Uri(@"D:\程序项目目录\ImgList\World.jpg", UriKind.RelativeOrAbsolute));
}
private void GrayStretch_Click(object sender, RoutedEventArgs e)
{
Bitmap bitmap = ImageSourceToBitmap(img.Source);
BitmapGrayStretch(bitmap, bitmap.Width, bitmap.Height);
img.Source = BitmapToBitmapImage(bitmap);
}
}
}