您的位置:首页 > 其它

图片灰度处理

2014-11-11 14:53 239 查看
一、WPF灰度处理(转)

文章的内容是来自微软中文技术论坛的一个帖子,当时是想将一段将图片灰度处理的代码转换为XAML的一个样式,在这里要谢谢
XiaoYanQiang、Sheldon_Xiao、shixin的热情回答,现在将他们的回答贴出来供大家学习参考.内容如下:提问:这个功能如何写成一个样式,将一个窗体内所有的Image控件的图片格式都转换为Gray8BitmapImagebitmapImage=newBitmapImage(newUri("D:\\Face.jpg"));
FormatConvertedBitmapnewFormatedBitmapSource=newFormatConvertedBitmap();
newFormatedBitmapSource.BeginInit();
newFormatedBitmapSource.Source=bitmapImage;
newFormatedBitmapSource.DestinationFormat=PixelFormats.Gray8;
newFormatedBitmapSource.EndInit();
img.Source=newFormatedBitmapSource;
this.Content=img;XiaoYanQiang的回答:
publicclassImageAttached
{
//Gray8附加属性,Gary8图片样式的"开关"
publicstaticreadonlyDependencyPropertyGray8Property=
DependencyProperty.RegisterAttached("Gray8",typeof(bool),typeof(ImageAttached),
newFrameworkPropertyMetadata((bool)false,
newPropertyChangedCallback(OnGray8Changed)));

publicstaticboolGetGray8(DependencyObjectd)
{
return(bool)d.GetValue(Gray8Property);
}

publicstaticvoidSetGray8(DependencyObjectd,boolvalue)
{
d.SetValue(Gray8Property,value);
}

privatestaticvoidOnGray8Changed(DependencyObjectd,DependencyPropertyChangedEventArgse)
{
ImagecurrentImage=dasImage;
if(currentImage==null)
{
return;
}

boolisGray8=(bool)d.GetValue(Gray8Property);

if(isGray8)
{
//附加BitmapSourceBackup属性,备份当前BitmapSource,以备恢复用
BitmapSourcebackupBitmapSource=(currentImage.SourceasBitmapSource).CloneCurrentValue();
d.SetValue(BitmapSourceBackupProperty,backupBitmapSource);

//建立Gray8的BitmapSource
FormatConvertedBitmapnewFormatedBitmapSource=newFormatConvertedBitmap();
newFormatedBitmapSource.BeginInit();
newFormatedBitmapSource.Source=currentImage.SourceasBitmapSource;
newFormatedBitmapSource.DestinationFormat=PixelFormats.Gray8;
newFormatedBitmapSource.EndInit();

//替换ImageSource
currentImage.Source=newFormatedBitmapSource;
}
else
{
//图像恢复操作
objectobj=currentImage.GetValue(BitmapSourceBackupProperty);
if(obj==null)
{
return;
}

BitmapSourcebs=objasBitmapSource;
if(bs==null)
{
return;
}

currentImage.Source=bs;
}
}

//备份用源图像的附加属性,当Gray8变更时,自动附加
publicstaticreadonlyDependencyPropertyBitmapSourceBackupProperty=
DependencyProperty.RegisterAttached("BitmapSourceBackup",typeof(BitmapSource),typeof(ImageAttached),
newFrameworkPropertyMetadata(null));

publicstaticBitmapSourceGetBitmapSourceBackup(DependencyObjectd)
{
return(BitmapSource)d.GetValue(BitmapSourceBackupProperty);
}

publicstaticvoidSetBitmapSourceBackup(DependencyObjectd,BitmapSourcevalue)
{
d.SetValue(BitmapSourceBackupProperty,value);
}
}
然后XAML里添加local:ImageAttached.Gray8="True"
<Imagexmlns:local="clr-namespace:WpfImageGray8Sample"Source="/WpfImageGray8Sample;component/Images/44537119.jpg"local:ImageAttached.Gray8="True"/>
这样就可以方便控制Gray8了。


Sheldon_Xiao

的回答:
推荐了一个链接:http://www.rikware.com/post/Setting-FormatConvertedBitmap-Source-via-Binding.aspx
里面也是用转换器实现


shixin的回答:
<Windowx:Class="MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:y="clr-namespace:WpfApplication1"Title="MainWindow"Height="350"Width="525">
<Window.Resources>
<y:GrayImagex:Key="GrayImage"/>
</Window.Resources>
<Grid>
<ImageSource="{BindingRelativeSource={RelativeSourceSelf},Path=Tag,Converter={StaticResourceGrayImage}}"Tag="C:\Test.jpg"/>
</Grid>
</Window>
xaml部分还可以写成这样
<Window.Resources>
<y:GrayImagex:Key="GrayImage"/>
<StyleTargetType="{x:TypeImage}">
<SetterProperty="Source"Value="{BindingRelativeSource={RelativeSourceSelf},Path=Tag,Converter={StaticResourceGrayImage}}"/>
</Style>
</Window.Resources>
<Grid>
<ImageTag="C:\Test.jpg"/>
</Grid>
PublicClassGrayImage
ImplementsIValueConverter
PublicFunctionConvert(ByValvalueAsObject,ByValtargetTypeAsType,ByValparameterAsObject,ByValcultureAsGlobalization.CultureInfo)AsObjectImplementsIValueConverter.Convert
Try
DimnewFormatedBitmapSourceAsNewFormatConvertedBitmap
newFormatedBitmapSource.BeginInit()
newFormatedBitmapSource.Source=NewBitmapImage(NewUri(value.ToString))
newFormatedBitmapSource.DestinationFormat=PixelFormats.Gray8
newFormatedBitmapSource.EndInit()
Convert=newFormatedBitmapSource
Catch
Convert=Nothing
EndTry
EndFunction
PublicFunctionConvertBack(ByValvalueAsObject,ByValtargetTypeAsType,ByValparameterAsObject,ByValcultureAsGlobalization.CultureInfo)AsObjectImplementsIValueConverter.ConvertBack
ConvertBack=value
EndFunction
EndClass
二、Windos8和WindowsPhone通过更改像素点颜色更改图片灰度

privateasyncvoidButton_Click(objectsender,RoutedEventArgse)
{
//实例化一个300*300的WriteableBitmap,并将其作为Image控件的图片源
WriteableBitmapwriteableBitmap=newWriteableBitmap(300,300);
image2.Source=writeableBitmap;

StorageFilefile=awaitStorageFile.GetFileFromApplicationUriAsync(newUri("ms-appx:///Assets/2.jpg"));
using(IRandomAccessStreamfileStream=awaitfile.OpenAsync(FileAccessMode.Read))
{
//将指定的图片转换成BitmapDecoder对象
BitmapDecoderdecoder=awaitBitmapDecoder.CreateAsync(fileStream);

//通过BitmapTransform缩放图片的尺寸
BitmapTransformtransform=newBitmapTransform()
{
ScaledWidth=Convert.ToUInt32(writeableBitmap.PixelWidth),
ScaledHeight=Convert.ToUInt32(writeableBitmap.PixelHeight)
};

//获取图片的PixelDataProvider对象
PixelDataProviderpixelData=awaitdecoder.GetPixelDataAsync(
BitmapPixelFormat.Bgra8,
BitmapAlphaMode.Straight,
transform,
ExifOrientationMode.IgnoreExifOrientation,
ColorManagementMode.DoNotColorManage);

//获取图片的像素数据,由于之前指定的格式是BitmapPixelFormat.Bgra8,所以每一个像素由4个字节组成,分别是bgra
byte[]sourcePixels=pixelData.DetachPixelData();
for(inti=0;i<sourcePixels.Length;i+=4)
{

byteB=sourcePixels[i];
byteG=sourcePixels[i+1];
byteR=sourcePixels[i+2];
byteA=sourcePixels[i+3];
byteGrayValue=(byte)(R*0.299+G*0.587+B*0.114);
sourcePixels[i]=GrayValue;
sourcePixels[i+1]=GrayValue;
sourcePixels[i+2]=GrayValue;
sourcePixels[i+3]=0xFF;
}
//将修改后的像素数据写入WriteableBitmap对象的像素缓冲区(WriteableBitmap使用的是BGRA格式)
using(Streamstream=writeableBitmap.PixelBuffer.AsStream())//IBuffer.AsStream()为来自System.Runtime.InteropServices.WindowsRuntime.WindowsRuntimeBufferExtensions中的扩展方法
{
awaitstream.WriteAsync(sourcePixels,0,sourcePixels.Length);
}
}
//用像素缓冲区的数据绘制图片
writeableBitmap.Invalidate();
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: