日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

基于WPF實現用戶頭像選擇器的示例代碼_C#教程

作者:驚鏵 ? 更新時間: 2022-09-18 編程語言

實現思路

制作一個用戶頭像選擇器仿?WeGame

制作一個用戶頭像選擇Canvas為父控件所實現,展示圖片使用ImagePath當作上方的蒙版;

Canvas:主要用途方便移動Image,設置ClipToBounds="True"裁剪為一個正方形200x200做為主要展示區域;

Image:展示需要裁剪的圖片;

Path:CombinedGeometry[1]繪制蒙版大小200x200效果如下;

當選擇一個本地圖片的時候判斷寬與高誰更大,誰小就將它更改為200?,另一邊做等比縮放后給到DrawingVisual繪制一個新的BitmapFrame[2]給Image控件做展示;

當移動圖片的時候右側展示當前區域使用CroppedBitmap[3]進行裁剪并顯示;

源碼Github[4]?Gitee[5]

核心代碼

1)CropAvatar.xaml?代碼如下;

<ResourceDictionary?xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
????????????????????xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
????????????????????xmlns:controls="clr-namespace:WPFDevelopers.Controls">
????<ResourceDictionary.MergedDictionaries>
????????<ResourceDictionary?Source="Basic/ControlBasic.xaml"/>
????</ResourceDictionary.MergedDictionaries>

????<Style?TargetType="controls:CropAvatar"?BasedOn="{StaticResource?ControlBasicStyle}">
????????<Setter?Property="Template">
????????????<Setter.Value>
????????????????<ControlTemplate?TargetType="{x:Type?controls:CropAvatar}">
????????????????????<Canvas?x:Name="PART_Canvas"?ClipToBounds="True">
????????????????????????<Image?x:Name="PART_Image"?Cursor="SizeAll"?></Image>
????????????????????????<Path?x:Name="PART_Layout"?
??????????????????????????????Fill="{DynamicResource?BlackSolidColorBrush}"?
??????????????????????????????Width="200"?Height="200"?
??????????????????????????????Opacity=".5">
????????????????????????????<Path.Data>
????????????????????????????????<CombinedGeometry?GeometryCombineMode="Xor">
????????????????????????????????????<CombinedGeometry.Geometry1>
????????????????????????????????????????<RectangleGeometry?Rect="0,0,200,200"/>
????????????????????????????????????</CombinedGeometry.Geometry1>
????????????????????????????????????<CombinedGeometry.Geometry2>
????????????????????????????????????????<EllipseGeometry?Center="100,100"?RadiusX="100"?RadiusY="100"/>
????????????????????????????????????</CombinedGeometry.Geometry2>
????????????????????????????????</CombinedGeometry>
????????????????????????????</Path.Data>
????????????????????????</Path>
????????????????????????<Grid?x:Name="PART_Grid"?Width="200"?Height="200">
????????????????????????????<Button?x:Name="PART_ReplaceButton"?Style="{StaticResource?PathButton}"
????????????????????????????????????HorizontalAlignment="Right"
????????????????????????????????????VerticalAlignment="Top"
????????????????????????????????????Width="40"?Height="40"?ToolTip="更換圖片"
????????????????????????????????????Visibility="Collapsed">
????????????????????????????????<Button.Content>
????????????????????????????????????<Path?Data="{StaticResource?PathReplace}"
??????????????????????????????????????????Fill="{StaticResource?PrimaryNormalSolidColorBrush}"
??????????????????????????????????????????Height="15"
??????????????????????????????????????????Width="15"
??????????????????????????????????????????Stretch="Fill"?/>
????????????????????????????????</Button.Content>
????????????????????????????</Button>
????????????????????????????<Button?x:Name="PART_AddButton"?Style="{StaticResource?PathButton}"
????????????????????????????????????Width="40"?Height="40"?ToolTip="選擇圖片">
????????????????????????????????<Button.Content>
????????????????????????????????????<Path?Data="{StaticResource?PathAdd}"
??????????????????????????????????????????Fill="{StaticResource?PrimaryNormalSolidColorBrush}"
??????????????????????????????????????????Height="20"
??????????????????????????????????????????Width="20"
??????????????????????????????????????????Stretch="Fill"?
??????????????????????????????????????????RenderTransformOrigin="0.5,0.5"?IsHitTestVisible="False">
????????????????????????????????????????<Path.RenderTransform>
????????????????????????????????????????????<RotateTransform?Angle="45"/>
????????????????????????????????????????</Path.RenderTransform>
????????????????????????????????????</Path>
????????????????????????????????</Button.Content>
????????????????????????????</Button>
????????????????????????</Grid>
????????????????????</Canvas>
????????????????</ControlTemplate>
????????????</Setter.Value>
????????</Setter>
????</Style>

</ResourceDictionary>

2)CropAvatar.cs?代碼如下;

using?System;
using?System.Windows;
using?System.Windows.Controls;
using?System.Windows.Input;
using?System.Windows.Media;
using?System.Windows.Media.Imaging;
using?System.Windows.Shapes;
using?WPFDevelopers.Helpers;

namespace?WPFDevelopers.Controls
{
????[TemplatePart(Name?=?CanvasTemplateName,?Type?=?typeof(Canvas))]
????[TemplatePart(Name?=?ImageTemplateName,?Type?=?typeof(Image))]
????[TemplatePart(Name?=?PathTemplateName,?Type?=?typeof(Path))]
????[TemplatePart(Name?=?GridTemplateName,?Type?=?typeof(Grid))]
????[TemplatePart(Name?=?ReplaceButtonTemplateName,?Type?=?typeof(Button))]
????[TemplatePart(Name?=?AddButtonTemplateName,?Type?=?typeof(Button))]
????public?partial?class?CropAvatar?:?Control
????{
????????private?const?string?CanvasTemplateName?=?"PART_Canvas";
????????private?const?string?ImageTemplateName?=?"PART_Image";
????????private?const?string?PathTemplateName?=?"PART_Layout";
????????private?const?string?GridTemplateName?=?"PART_Grid";
????????private?const?string?ReplaceButtonTemplateName?=?"PART_ReplaceButton";
????????private?const?string?AddButtonTemplateName?=?"PART_AddButton";
????????private?Point?point;
????????private?const?int?_size?=?200;
????????private?bool?isDown;
????????private?bool?isLeft;
????????private?CroppedBitmap?crop;
????????private?Canvas?canvas;
????????private?Image?image;
????????private?Path?path;
????????private?Grid?grid;
????????private?Button?replaceButton,?addButton;
????????private?int?initialX,?initialY,?voffsetX,?voffsetY;
????????private?double?vNewStartX,?vNewStartY,?_StartX,?_StartY,?centerX,?centerY;
????????private?BitmapFrame?bitmapFrame;

????????public?ImageSource?OutImageSource
????????{
????????????get?{?return?(ImageSource)GetValue(OutImageSourceProperty);?}
????????????set?{?SetValue(OutImageSourceProperty,?value);?}
????????}

????????public?static?readonly?DependencyProperty?OutImageSourceProperty?=
????????????DependencyProperty.Register("OutImageSource",?typeof(ImageSource),?typeof(CropAvatar),?new?PropertyMetadata(null));


????????static?CropAvatar()
????????{
????????????DefaultStyleKeyProperty.OverrideMetadata(typeof(CropAvatar),?new?FrameworkPropertyMetadata(typeof(CropAvatar)));
????????}
????????public?override?void?OnApplyTemplate()
????????{
????????????base.OnApplyTemplate();
????????????canvas?=?GetTemplateChild(CanvasTemplateName)?as?Canvas;
????????????canvas.Loaded?+=?Canvas_Loaded;
????????????grid?=?GetTemplateChild(GridTemplateName)?as?Grid;
????????????image?=?GetTemplateChild(ImageTemplateName)?as?Image;
????????????image.MouseDown?+=?Image_MouseDown;
????????????image.MouseMove?+=?Image_MouseMove;
????????????image.MouseUp?+=?Image_MouseUp;
????????????image.MouseLeave?+=?Image_MouseLeave;
????????????path?=?GetTemplateChild(PathTemplateName)?as?Path;
????????????replaceButton?=?GetTemplateChild(ReplaceButtonTemplateName)?as?Button;
????????????replaceButton.Click?+=?ReplaceButton_Click;
????????????addButton?=?GetTemplateChild(AddButtonTemplateName)?as?Button;
????????????addButton.Click?+=?AddButton_Click;
????????}

????????private?void?Canvas_Loaded(object?sender,?RoutedEventArgs?e)
????????{
????????????if?(sender?is?Canvas?canvas)
????????????{
????????????????var?width?=?canvas.ActualWidth;
????????????????var?height?=?canvas.ActualHeight;
????????????????centerX?=?(width?-?path.Width)?/?2.0d;
????????????????centerY?=?(height?-?path.Height)?/?2.0d;
????????????????canvas.Clip?=?new?RectangleGeometry(new?Rect(centerX,?centerY,?200,?200));?
????????????????Canvas.SetLeft(path,?centerX);
????????????????Canvas.SetTop(path,?centerY);
????????????????Canvas.SetLeft(grid,?centerX);
????????????????Canvas.SetTop(grid,?centerY);
????????????}
????????}

????????private?void?Image_MouseLeave(object?sender,?MouseEventArgs?e)
????????{
????????????isDown?=?false;
????????????if?(isLeft)
????????????????_StartX?=?Canvas.GetLeft(image);
????????????else
????????????????_StartY?=?Canvas.GetTop(image);
????????}

????????private?void?Image_MouseUp(object?sender,?MouseButtonEventArgs?e)
????????{
????????????if?(isDown)
????????????{
????????????????var?vPoint?=?e.GetPosition(this);
????????????????if?(isLeft)
????????????????{
????????????????????_StartX?=?Canvas.GetLeft(image);
????????????????????initialX?=?voffsetX;
????????????????}

????????????????else
????????????????{
????????????????????_StartY?=?Canvas.GetTop(image);
????????????????????initialY?=?voffsetY;
????????????????}
????????????}
????????}

????????private?void?Image_MouseMove(object?sender,?MouseEventArgs?e)
????????{
????????????if?(e.LeftButton?==?MouseButtonState.Pressed?&&?isDown)
????????????{
????????????????var?vPoint?=?e.GetPosition(this);
????????????????if?(isLeft)
????????????????{
????????????????????var?voffset?=?vPoint.X?-?point.X;
????????????????????vNewStartX?=?_StartX?+?voffset;
????????????????????var?xPath?=?Canvas.GetLeft(path);
????????????????????if?(vNewStartX?<=?xPath?&&?vNewStartX?>=?-(bitmapFrame.Width?-?200?-?xPath))
????????????????????{
????????????????????????Canvas.SetLeft(image,?vNewStartX);
????????????????????????voffsetX?=?initialX?-?(int)voffset;
????????????????????????voffsetX?=?voffsetX?<?0???0?:?voffsetX;
????????????????????????crop?=?new?CroppedBitmap(bitmapFrame,?new?Int32Rect(voffsetX,?0,?_size,?_size));

????????????????????}
????????????????}
????????????????else
????????????????{
????????????????????var?voffset?=?vPoint.Y?-?point.Y;
????????????????????vNewStartY?=?_StartY?+?voffset;
????????????????????var?yPath?=?Canvas.GetTop(path);
????????????????????if?(vNewStartY?<=?yPath?&&?vNewStartY?>=?-(bitmapFrame.Height?-?200?-?yPath))
????????????????????{
????????????????????????Canvas.SetTop(image,?vNewStartY);
????????????????????????voffsetY?=?initialY?-?(int)voffset;
????????????????????????voffsetY?=?voffsetY?<?0???0?:?voffsetY;
????????????????????????crop?=?new?CroppedBitmap(bitmapFrame,?new?Int32Rect(0,?voffsetY,?_size,?_size));
????????????????????}
????????????????}
????????????????OutImageSource?=?crop;
????????????}
????????}

????????private?void?Image_MouseDown(object?sender,?MouseButtonEventArgs?e)
????????{
????????????isDown?=?true;
????????????point?=?e.GetPosition(this);
????????}

????????private?void?ReplaceButton_Click(object?sender,?RoutedEventArgs?e)
????????{
????????????InitialImage();
????????}

????????private?void?AddButton_Click(object?sender,?RoutedEventArgs?e)
????????{
????????????InitialImage();
????????}

????????void?InitialImage()
????????{
????????????vNewStartX?=?0;
????????????vNewStartY?=?0;
????????????var?uri?=?ControlsHelper.ImageUri();
????????????if?(uri?==?null)?return;
????????????var?bitmap?=?new?BitmapImage(uri);
????????????if?(bitmap.Height?>?bitmap.Width)
????????????{
????????????????double?scale?=?(double)bitmap.Width?/?(double)path.Width;
????????????????image.Width?=?_size;
????????????????image.Height?=?(double)bitmap.Height?/?scale;
????????????????isLeft?=?false;
????????????}
????????????else?if?(bitmap.Width?>?bitmap.Height)
????????????{
????????????????double?scale?=?(double)bitmap.Height?/?(double)path.Height;
????????????????image.Width?=?(double)bitmap.Width?/?scale;
????????????????image.Height?=?_size;
????????????????isLeft?=?true;
????????????}
????????????bitmapFrame?=?ControlsHelper.CreateResizedImage(bitmap,?(int)image.Width,?(int)image.Height,?0);
????????????image.Source?=?bitmapFrame;
????????????if?(image.Source?!=?null)
????????????{
????????????????replaceButton.Visibility?=?Visibility.Visible;
????????????????addButton.Visibility?=?Visibility.Collapsed;
????????????}
????????????Canvas.SetLeft(grid,?centerX);
????????????Canvas.SetTop(grid,?centerY);
????????????_StartX?=?(canvas.ActualWidth?-?image.Width)?/?2.0d;
????????????_StartY?=?(canvas.ActualHeight?-?image.Height)?/?2.0d;
????????????Canvas.SetLeft(image,?_StartX);
????????????Canvas.SetTop(image,?_StartY);????????
????????????if?(isLeft)
????????????{
????????????????initialX?=?(int)(image.Width?-?200)?/?2;
????????????????initialY?=?0;
????????????????crop?=?new?CroppedBitmap(bitmapFrame,?new?Int32Rect(initialX,?0,?_size,?_size));

????????????}
????????????else
????????????{
????????????????initialY?=?(int)(image.Height?-?200)?/?2;
????????????????initialX?=?0;
????????????????crop?=?new?CroppedBitmap(bitmapFrame,?new?Int32Rect(0,?initialY,?_size,?_size));
????????????}
????????????OutImageSource?=?crop;
????????}
???????
????}
}

3)CropAvatarWindow.xaml使用如下;

<ws:Window?x:Class="WPFDevelopers.Samples.ExampleViews.CropAvatarWindow"
????????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:wpfdev="https://github.com/WPFDevelopersOrg/WPFDevelopers"
????????xmlns:ws="https://github.com/WPFDevelopersOrg.WPFDevelopers.Minimal"
????????mc:Ignorable="d"??WindowStyle="ToolWindow"?ResizeMode="NoResize"
????????WindowStartupLocation="CenterScreen"
????????Title="WPF?開發者-頭像選擇器"?Height="450"?Width="800">
????<Grid>
????????<Grid.ColumnDefinitions>
????????????<ColumnDefinition/>
????????????<ColumnDefinition/>
????????</Grid.ColumnDefinitions>
????????<Grid.RowDefinitions>
????????????<RowDefinition/>
????????????<RowDefinition?Height="Auto"/>
????????</Grid.RowDefinitions>
????????<wpfdev:CropAvatar?x:Name="MyCropAvatar"/>
????????<Image?Grid.Column="1"?Name="CropAvatarImage"?Source="{Binding?ElementName=MyCropAvatar,Path=OutImageSource}"?
???????????????Stretch="Fill"?Width="200"?Height="200">
????????????<Image.Clip>
????????????????<EllipseGeometry?Center="100,100"?RadiusX="100"?RadiusY="100"/>
????????????</Image.Clip>
????????</Image>
????????<UniformGrid?Grid.Row="1"?Grid.ColumnSpan="2"?
?????????????????????HorizontalAlignment="Center"?
?????????????????????VerticalAlignment="Center">
????????????<Button??Content="保存"?Click="btnSave_Click"?Style="{StaticResource?PrimaryButton}"?Margin="4,0"/>
????????????<Button??Content="關閉"?Click="btnClose_Click"?Margin="4,0"/>
????????</UniformGrid>
????</Grid>
</ws:Window>

4)?CropAvatarWindow.xaml.cs?代碼如下;

using?System.Windows;

namespace?WPFDevelopers.Samples.ExampleViews
{
????///?<summary>
????///?CropAvatarWindow.xaml?的交互邏輯
????///?</summary>
????public?partial?class?CropAvatarWindow?
????{
????????public?CropAvatarWindow()
????????{
????????????InitializeComponent();
????????}

????????private?void?btnSave_Click(object?sender,?RoutedEventArgs?e)
????????{
????????????DialogResult?=?true;
????????}

????????private?void?btnClose_Click(object?sender,?RoutedEventArgs?e)
????????{
????????????DialogResult?=?false;
????????}
????}
}

5)?CropAvatarExample.xaml?使用如下;

<UserControl?x:Class="WPFDevelopers.Samples.ExampleViews.CropAvatarExample"
?????????????xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
?????????????xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
?????????????xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"?
?????????????xmlns:d="http://schemas.microsoft.com/expression/blend/2008"?
?????????????xmlns:wpfdev="https://github.com/WPFDevelopersOrg/WPFDevelopers"
?????????????xmlns:local="clr-namespace:WPFDevelopers.Samples.ExampleViews"
?????????????mc:Ignorable="d"?
?????????????d:DesignHeight="450"?d:DesignWidth="800">
????<Grid>
????????<Grid.ColumnDefinitions>
????????????<ColumnDefinition/>
????????????<ColumnDefinition/>
????????</Grid.ColumnDefinitions>
????????<Button?Content="圖像選擇器"?VerticalAlignment="Center"?HorizontalAlignment="Center"?Click="Button_Click"/>
????????<Image?Grid.Column="1"?Name="MyImage"
???????????????Stretch="Fill"?Width="200"?Height="200">
????????????<Image.Clip>
????????????????<EllipseGeometry?Center="100,100"?RadiusX="100"?RadiusY="100"/>
????????????</Image.Clip>
????????</Image>
????</Grid>
</UserControl>

6)?CropAvatarExample.xaml.cs?代碼如下;

using?System.Windows.Controls;

namespace?WPFDevelopers.Samples.ExampleViews
{
????///?<summary>
????///?CropAvatarExample.xaml?的交互邏輯
????///?</summary>
????public?partial?class?CropAvatarExample?:?UserControl
????{
????????public?CropAvatarExample()
????????{
????????????InitializeComponent();
????????}

????????private?void?Button_Click(object?sender,?System.Windows.RoutedEventArgs?e)
????????{
????????????var?cropAvatarWindow?=?new?CropAvatarWindow();
????????????if?(cropAvatarWindow.ShowDialog()?==?true)
????????????{
????????????????MyImage.Source?=?cropAvatarWindow.CropAvatarImage.Source;
????????????}
????????}
????}
}

參考資料

[1]CombinedGeometry

[2]BitmapFrame

[3]CroppedBitmap

[4]Github

[5]Gitee

原文鏈接:https://www.cnblogs.com/yanjinhua/p/16517793.html

欄目分類
最近更新