基于WPF實(shí)現(xiàn)裁剪圖像功能
WPF 實(shí)現(xiàn)裁剪圖像
框架使用.NET4 至 .NET6
Visual Studio 2022
使用 Canvas
展示選擇的裁剪圖片
使用 4
個(gè) Rectangle
設(shè)置未選中區(qū)域分別是左上右下
中間展示當(dāng)前的裁剪區(qū)域使用了 Border
移動(dòng)
- 左右移動(dòng)使用
Canvas.SetLeft
- 上下移動(dòng)使用
Canvas.SetTop
Border
獲取裁剪區(qū)域獲取GetLeft
、GetTop
、Border
的Width
與Height
拉伸 Border
使用了之前截圖控件使用的裝飾器 ScreenCutAdorner
新增裝飾器不允許拉伸超出 Canvas
畫(huà)布
實(shí)現(xiàn)代碼
1)新建 CropImage.cs
控件代碼如下:
using?System; using?System.Windows; using?System.Windows.Controls; using?System.Windows.Documents; 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?=?RectangleLeftTemplateName,?Type?=?typeof(Rectangle))] ????[TemplatePart(Name?=?RectangleTopTemplateName,?Type?=?typeof(Rectangle))] ????[TemplatePart(Name?=?RectangleRightTemplateName,?Type?=?typeof(Rectangle))] ????[TemplatePart(Name?=?RectangleBottomTemplateName,?Type?=?typeof(Rectangle))] ????[TemplatePart(Name?=?BorderTemplateName,?Type?=?typeof(Border))] ????public?class?CropImage?:?Control ????{ ????????private?const?string?CanvasTemplateName?=?"PART_Canvas"; ????????private?const?string?RectangleLeftTemplateName?=?"PART_RectangleLeft"; ????????private?const?string?RectangleTopTemplateName?=?"PART_RectangleTop"; ????????private?const?string?RectangleRightTemplateName?=?"PART_RectangleRight"; ????????private?const?string?RectangleBottomTemplateName?=?"PART_RectangleBottom"; ????????private?const?string?BorderTemplateName?=?"PART_Border"; ????????private?BitmapFrame?bitmapFrame; ????????private?Rectangle?_rectangleLeft,?_rectangleTop,?_rectangleRight,?_rectangleBottom; ????????private?Border?_border; ????????private?Canvas?_canvas; ????????public?ImageSource?Source ????????{ ????????????get?{?return?(ImageSource)GetValue(SourceProperty);?} ????????????set?{?SetValue(SourceProperty,?value);?} ????????} ????????public?static?readonly?DependencyProperty?SourceProperty?= ????????????DependencyProperty.Register("Source",?typeof(ImageSource),?typeof(CropImage),?new?PropertyMetadata(null,?OnSourceChanged)); ????????public?Rect?CurrentRect ????????{ ????????????get?{?return?(Rect)GetValue(CurrentRectProperty);?} ????????????private?set?{?SetValue(CurrentRectProperty,?value);?} ????????} ????????public?static?readonly?DependencyProperty?CurrentRectProperty?= ????????????DependencyProperty.Register("CurrentRect",?typeof(Rect),?typeof(CropImage),?new?PropertyMetadata(null)); ????????public?ImageSource?CurrentAreaBitmap ????????{ ????????????get?{?return?(ImageSource)GetValue(CurrentAreaBitmapProperty);?} ????????????private?set?{?SetValue(CurrentAreaBitmapProperty,?value);?} ????????} ????????public?static?readonly?DependencyProperty?CurrentAreaBitmapProperty?= ????????????DependencyProperty.Register("CurrentAreaBitmap",?typeof(ImageSource),?typeof(CropImage),?new?PropertyMetadata(null)); ????????private?AdornerLayer?adornerLayer; ????????private?ScreenCutAdorner?screenCutAdorner; ????????private?bool?isDragging; ????????private?double?offsetX,?offsetY; ????????private?static?void?OnSourceChanged(DependencyObject?d,?DependencyPropertyChangedEventArgs?e) ????????{ ????????????var?crop?=?(CropImage)d; ????????????if?(crop?!=?null) ????????????????crop.DrawImage(); ????????} ????????static?CropImage() ????????{ ????????????DefaultStyleKeyProperty.OverrideMetadata(typeof(CropImage), ????????????????new?FrameworkPropertyMetadata(typeof(CropImage))); ????????} ????????public?override?void?OnApplyTemplate() ????????{ ????????????base.OnApplyTemplate(); ????????????_canvas?=?GetTemplateChild(CanvasTemplateName)?as?Canvas; ????????????_rectangleLeft?=?GetTemplateChild(RectangleLeftTemplateName)?as?Rectangle; ????????????_rectangleTop?=?GetTemplateChild(RectangleTopTemplateName)?as?Rectangle; ????????????_rectangleRight?=?GetTemplateChild(RectangleRightTemplateName)?as?Rectangle; ????????????_rectangleBottom?=?GetTemplateChild(RectangleBottomTemplateName)?as?Rectangle; ????????????_border?=?GetTemplateChild(BorderTemplateName)?as?Border; ????????????DrawImage(); ????????} ????????void?DrawImage() ????????{ ????????????if?(Source?==?null) ????????????{ ????????????????_border.Visibility?=?Visibility.Collapsed; ????????????????if?(adornerLayer?==?null)?return; ????????????????adornerLayer.Remove(screenCutAdorner); ????????????????screenCutAdorner?=?null; ????????????????adornerLayer?=?null; ????????????????return; ????????????} ????????????_border.Visibility?=?Visibility.Visible; ????????????var?bitmap?=?(BitmapImage)Source; ????????????bitmapFrame?=?ControlsHelper.CreateResizedImage(bitmap,?(int)bitmap.Width,?(int)bitmap.Height,?0); ????????????_canvas.Width?=?bitmap.Width; ????????????_canvas.Height?=?bitmap.Height; ????????????_canvas.Background?=?new?ImageBrush(bitmap); ????????????_border.Width?=?bitmap.Width?*?0.2; ????????????_border.Height?=?bitmap.Height?*?0.2; ????????????var?cx?=?_canvas.Width?/?2?-?_border.Width?/?2; ????????????var?cy?=?_canvas.Height?/?2?-?_border.Height?/?2; ????????????Canvas.SetLeft(_border,?cx); ????????????Canvas.SetTop(_border,?cy); ????????????if?(adornerLayer?!=?null)?return; ????????????adornerLayer?=?AdornerLayer.GetAdornerLayer(_border); ????????????screenCutAdorner?=?new?ScreenCutAdorner(_border); ????????????adornerLayer.Add(screenCutAdorner); ????????????_border.SizeChanged?-=?Border_SizeChanged; ????????????_border.SizeChanged?+=?Border_SizeChanged; ????????????_border.MouseDown?-=?Border_MouseDown; ????????????_border.MouseDown?+=?Border_MouseDown; ????????????_border.MouseMove?-=?Border_MouseMove; ????????????_border.MouseMove?+=?Border_MouseMove; ????????????_border.MouseUp?-=?Border_MouseUp; ????????????_border.MouseUp?+=?Border_MouseUp; ????????} ????????private?void?Border_MouseUp(object?sender,?MouseButtonEventArgs?e) ????????{ ????????????isDragging?=?false; ????????????var?draggableControl?=?sender?as?UIElement; ????????????draggableControl.ReleaseMouseCapture(); ????????} ????????private?void?Border_MouseDown(object?sender,?MouseButtonEventArgs?e) ????????{ ????????????if?(!isDragging) ????????????{ ????????????????isDragging?=?true; ????????????????var?draggableControl?=?sender?as?UIElement; ????????????????var?position?=?e.GetPosition(this); ????????????????offsetX?=?position.X?-?Canvas.GetLeft(draggableControl); ????????????????offsetY?=?position.Y?-?Canvas.GetTop(draggableControl); ????????????????draggableControl.CaptureMouse(); ????????????} ????????} ????????private?void?Border_MouseMove(object?sender,?MouseEventArgs?e) ????????{ ????????????if?(isDragging?&&?e.LeftButton?==?MouseButtonState.Pressed) ????????????{ ????????????????var?draggableControl?=?sender?as?UIElement; ????????????????var?position?=?e.GetPosition(this); ????????????????var?x?=?position.X?-?offsetX; ????????????????x?=?x?<?0???0?:?x; ????????????????x?=?x?+?_border.Width?>?_canvas.Width???_canvas.Width?-?_border.Width?:?x; ????????????????var?y?=?position.Y?-?offsetY; ????????????????y?=?y?<?0???0?:?y; ????????????????y?=?y?+?_border.Height?>?_canvas.Height???_canvas.Height?-?_border.Height?:?y; ????????????????Canvas.SetLeft(draggableControl,?x); ????????????????Canvas.SetTop(draggableControl,?y); ????????????????Render(); ????????????} ????????} ????????void?Render() ????????{ ????????????var?cy?=?Canvas.GetTop(_border); ????????????cy?=?cy?<?0???0?:?cy; ????????????var?borderLeft?=?Canvas.GetLeft(_border); ????????????borderLeft?=?borderLeft?<?0???0?:?borderLeft; ????????????_rectangleLeft.Width?=?borderLeft; ????????????_rectangleLeft.Height?=?_border.ActualHeight; ????????????Canvas.SetTop(_rectangleLeft,?cy); ????????????_rectangleTop.Width?=?_canvas.Width; ????????????_rectangleTop.Height?=?cy; ????????????var?rx?=?borderLeft?+?_border.ActualWidth; ????????????rx?=?rx?>?_canvas.Width???_canvas.Width?:?rx; ????????????_rectangleRight.Width?=?_canvas.Width?-?rx; ????????????_rectangleRight.Height?=?_border.ActualHeight; ????????????Canvas.SetLeft(_rectangleRight,?rx); ????????????Canvas.SetTop(_rectangleRight,?cy); ????????????var?by?=?cy?+?_border.ActualHeight; ????????????by?=?by?<?0???0?:?by; ????????????_rectangleBottom.Width?=?_canvas.Width; ????????????var?rby?=?_canvas.Height?-?by; ????????????_rectangleBottom.Height?=?rby?<?0???0?:?rby; ????????????Canvas.SetTop(_rectangleBottom,?by); ????????????var?bitmap?=?CutBitmap(); ????????????if?(bitmap?==?null)?return; ????????????var?frame?=?BitmapFrame.Create(bitmap); ????????????CurrentAreaBitmap?=?frame; ????????} ????????private?void?Border_SizeChanged(object?sender,?SizeChangedEventArgs?e) ????????{ ????????????Render(); ????????} ????????private?CroppedBitmap?CutBitmap() ????????{ ????????????var?width?=?_border.Width; ????????????var?height?=?_border.Height; ????????????if?(double.IsNaN(width)?||?double.IsNaN(height)) ????????????????return?null; ????????????var?left?=?Canvas.GetLeft(_border); ????????????var?top?=?Canvas.GetTop(_border); ????????????CurrentRect?=?new?Rect(left,?top,?width,?height); ????????????return?new?CroppedBitmap(bitmapFrame, ???????????????new?Int32Rect((int)CurrentRect.X,?(int)CurrentRect.Y,?(int)CurrentRect.Width,?(int)CurrentRect.Height)); ????????} ????} }
2)修復(fù) ScreenCutAdorner.cs
裝飾器不允許超過(guò) Canvas
代碼如下:
using?System; using?System.Windows; using?System.Windows.Controls; using?System.Windows.Controls.Primitives; using?System.Windows.Documents; using?System.Windows.Input; using?System.Windows.Media; using?System.Windows.Shapes; namespace?WPFDevelopers.Controls { ????public?class?ScreenCutAdorner?:?Adorner ????{ ????????private?const?double?THUMB_SIZE?=?15; ????????private?const?double?MINIMAL_SIZE?=?20; ????????private?readonly?Thumb?lc; ????????private?readonly?Thumb?tl; ????????private?readonly?Thumb?tc; ????????private?readonly?Thumb?tr; ????????private?readonly?Thumb?rc; ????????private?readonly?Thumb?br; ????????private?readonly?Thumb?bc; ????????private?readonly?Thumb?bl; ????????private?readonly?VisualCollection?visCollec; ????????private?readonly?Canvas?canvas; ????????public?ScreenCutAdorner(UIElement?adorned)?:?base(adorned) ????????{ ????????????canvas?=?FindParent(adorned)?as?Canvas; ????????????visCollec?=?new?VisualCollection(this); ????????????visCollec.Add(lc?=?GetResizeThumb(Cursors.SizeWE,?HorizontalAlignment.Left,?VerticalAlignment.Center)); ????????????visCollec.Add(tl?=?GetResizeThumb(Cursors.SizeNWSE,?HorizontalAlignment.Left,?VerticalAlignment.Top)); ????????????visCollec.Add(tc?=?GetResizeThumb(Cursors.SizeNS,?HorizontalAlignment.Center,?VerticalAlignment.Top)); ????????????visCollec.Add(tr?=?GetResizeThumb(Cursors.SizeNESW,?HorizontalAlignment.Right,?VerticalAlignment.Top)); ????????????visCollec.Add(rc?=?GetResizeThumb(Cursors.SizeWE,?HorizontalAlignment.Right,?VerticalAlignment.Center)); ????????????visCollec.Add(br?=?GetResizeThumb(Cursors.SizeNWSE,?HorizontalAlignment.Right,?VerticalAlignment.Bottom)); ????????????visCollec.Add(bc?=?GetResizeThumb(Cursors.SizeNS,?HorizontalAlignment.Center,?VerticalAlignment.Bottom)); ????????????visCollec.Add(bl?=?GetResizeThumb(Cursors.SizeNESW,?HorizontalAlignment.Left,?VerticalAlignment.Bottom)); ????????} ????????private?static?UIElement?FindParent(UIElement?element) ????????{ ????????????DependencyObject?obj?=?element; ????????????obj?=?VisualTreeHelper.GetParent(obj); ????????????return?obj?as?UIElement; ????????} ????????protected?override?int?VisualChildrenCount?=>?visCollec.Count; ????????protected?override?Size?ArrangeOverride(Size?finalSize) ????????{ ????????????var?offset?=?THUMB_SIZE?/?2; ????????????var?sz?=?new?Size(THUMB_SIZE,?THUMB_SIZE); ????????????lc.Arrange(new?Rect(new?Point(-offset,?AdornedElement.RenderSize.Height?/?2?-?offset),?sz)); ????????????tl.Arrange(new?Rect(new?Point(-offset,?-offset),?sz)); ????????????tc.Arrange(new?Rect(new?Point(AdornedElement.RenderSize.Width?/?2?-?offset,?-offset),?sz)); ????????????tr.Arrange(new?Rect(new?Point(AdornedElement.RenderSize.Width?-?offset,?-offset),?sz)); ????????????rc.Arrange(new?Rect( ????????????????new?Point(AdornedElement.RenderSize.Width?-?offset,?AdornedElement.RenderSize.Height?/?2?-?offset), ????????????????sz)); ????????????br.Arrange(new?Rect( ????????????????new?Point(AdornedElement.RenderSize.Width?-?offset,?AdornedElement.RenderSize.Height?-?offset),?sz)); ????????????bc.Arrange(new?Rect( ????????????????new?Point(AdornedElement.RenderSize.Width?/?2?-?offset,?AdornedElement.RenderSize.Height?-?offset), ????????????????sz)); ????????????bl.Arrange(new?Rect(new?Point(-offset,?AdornedElement.RenderSize.Height?-?offset),?sz)); ????????????return?finalSize; ????????} ????????private?void?Resize(FrameworkElement?frameworkElement) ????????{ ????????????if?(double.IsNaN(frameworkElement.Width)) ????????????????frameworkElement.Width?=?frameworkElement.RenderSize.Width; ????????????if?(double.IsNaN(frameworkElement.Height)) ????????????????frameworkElement.Height?=?frameworkElement.RenderSize.Height; ????????} ????????private?Thumb?GetResizeThumb(Cursor?cur,?HorizontalAlignment?hor,?VerticalAlignment?ver) ????????{ ????????????var?thumb?=?new?Thumb ????????????{ ????????????????Width?=?THUMB_SIZE, ????????????????Height?=?THUMB_SIZE, ????????????????HorizontalAlignment?=?hor, ????????????????VerticalAlignment?=?ver, ????????????????Cursor?=?cur, ????????????????Template?=?new?ControlTemplate(typeof(Thumb)) ????????????????{ ????????????????????VisualTree?=?GetFactory(new?SolidColorBrush(Colors.White)) ????????????????} ????????????}; ????????????var?maxWidth?=?double.IsNaN(canvas.Width)???canvas.ActualWidth?:?canvas.Width; ????????????var?maxHeight?=?double.IsNaN(canvas.Height)???canvas.ActualHeight?:?canvas.Height; ????????????thumb.DragDelta?+=?(s,?e)?=> ????????????{ ????????????????var?element?=?AdornedElement?as?FrameworkElement; ????????????????if?(element?==?null) ????????????????????return; ????????????????Resize(element); ????????????????switch?(thumb.VerticalAlignment) ????????????????{ ????????????????????case?VerticalAlignment.Bottom: ????????????????????????if?(element.Height?+?e.VerticalChange?>?MINIMAL_SIZE) ????????????????????????{ ????????????????????????????var?newHeight?=?element.Height?+?e.VerticalChange; ????????????????????????????var?top?=?Canvas.GetTop(element)?+?newHeight; ????????????????????????????if?(newHeight?>?0?&&?top?<=?canvas.ActualHeight) ????????????????????????????????element.Height?=?newHeight; ????????????????????????} ????????????????????????break; ????????????????????case?VerticalAlignment.Top: ????????????????????????if?(element.Height?-?e.VerticalChange?>?MINIMAL_SIZE) ????????????????????????{ ????????????????????????????var?newHeight?=?element.Height?-?e.VerticalChange; ????????????????????????????var?top?=?Canvas.GetTop(element); ????????????????????????????if?(newHeight?>?0?&&?top?+?e.VerticalChange?>=?0) ????????????????????????????{ ????????????????????????????????element.Height?=?newHeight; ????????????????????????????????Canvas.SetTop(element,?top?+?e.VerticalChange); ????????????????????????????} ????????????????????????} ????????????????????????break; ????????????????} ????????????????switch?(thumb.HorizontalAlignment) ????????????????{ ????????????????????case?HorizontalAlignment.Left: ????????????????????????if?(element.Width?-?e.HorizontalChange?>?MINIMAL_SIZE) ????????????????????????{ ????????????????????????????var?newWidth?=?element.Width?-?e.HorizontalChange; ????????????????????????????var?left?=?Canvas.GetLeft(element); ????????????????????????????if?(newWidth?>?0?&&?left?+?e.HorizontalChange?>=?0) ????????????????????????????{ ????????????????????????????????element.Width?=?newWidth; ????????????????????????????????Canvas.SetLeft(element,?left?+?e.HorizontalChange); ????????????????????????????} ????????????????????????} ????????????????????????break; ????????????????????case?HorizontalAlignment.Right: ????????????????????????if?(element.Width?+?e.HorizontalChange?>?MINIMAL_SIZE) ????????????????????????{ ????????????????????????????var?newWidth?=?element.Width?+?e.HorizontalChange; ????????????????????????????var?left?=?Canvas.GetLeft(element)?+?newWidth; ????????????????????????????if?(newWidth?>?0?&&?left?<=?canvas.ActualWidth) ????????????????????????????????element.Width?=?newWidth; ????????????????????????} ????????????????????????break; ????????????????} ????????????????e.Handled?=?true; ????????????}; ????????????return?thumb; ????????} ????????private?FrameworkElementFactory?GetFactory(Brush?back) ????????{ ????????????var?fef?=?new?FrameworkElementFactory(typeof(Ellipse)); ????????????fef.SetValue(Shape.FillProperty,?back); ????????????fef.SetValue(Shape.StrokeProperty,?DrawingContextHelper.Brush); ????????????fef.SetValue(Shape.StrokeThicknessProperty,?(double)2); ????????????return?fef; ????????} ????????protected?override?Visual?GetVisualChild(int?index) ????????{ ????????????return?visCollec[index]; ????????} ????} }
3)新建 CropImage.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 ????????x:Key="WD.CropImage" ????????BasedOn="{StaticResource?WD.ControlBasicStyle}" ????????TargetType="{x:Type?controls:CropImage}"> ????????<Setter?Property="Template"> ????????????<Setter.Value> ????????????????<ControlTemplate?TargetType="{x:Type?controls:CropImage}"> ????????????????????<Canvas?x:Name="PART_Canvas"> ????????????????????????<Rectangle?x:Name="PART_RectangleLeft"?Style="{DynamicResource?WD.ScreenCutRectangleStyle}"?/> ????????????????????????<Rectangle?x:Name="PART_RectangleTop"?Style="{DynamicResource?WD.ScreenCutRectangleStyle}"?/> ????????????????????????<Rectangle?x:Name="PART_RectangleRight"?Style="{DynamicResource?WD.ScreenCutRectangleStyle}"?/> ????????????????????????<Rectangle?x:Name="PART_RectangleBottom"?Style="{DynamicResource?WD.ScreenCutRectangleStyle}"?/> ????????????????????????<Border ????????????????????????????x:Name="PART_Border" ????????????????????????????Background="Transparent" ????????????????????????????BorderBrush="{DynamicResource?WD.PrimaryNormalSolidColorBrush}" ????????????????????????????BorderThickness="2" ????????????????????????????Cursor="SizeAll"?/> ????????????????????</Canvas> ????????????????</ControlTemplate> ????????????</Setter.Value> ????????</Setter> ????</Style> ????<Style?BasedOn="{StaticResource?WD.CropImage}"?TargetType="{x:Type?controls:CropImage}"?/> </ResourceDictionary>
4)新建 CropImageExample.xaml
代碼如下:
<UserControl ????x:Class="WPFDevelopers.Samples.ExampleViews.CropImageExample" ????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:local="clr-namespace:WPFDevelopers.Samples.ExampleViews" ????xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" ????xmlns:wd="https://github.com/WPFDevelopersOrg/WPFDevelopers" ????d:DesignHeight="450" ????d:DesignWidth="800" ????mc:Ignorable="d"> ????????<Grid> ????????????<Grid.RowDefinitions> ????????????????<RowDefinition?Height="*"?/> ????????????????<RowDefinition?Height="Auto"?/> ????????????</Grid.RowDefinitions> ????????????<Grid.ColumnDefinitions> ????????????????<ColumnDefinition?/> ????????????????<ColumnDefinition?/> ????????????</Grid.ColumnDefinitions> ????????????<wd:CropImage ????????????????Name="MyCropImage" ????????????????Grid.Row="0" ????????????????Grid.Column="0"?/> ????????????<Image ????????????????Grid.Column="1" ????????????????Width="{Binding?CurrentRect.Width,?ElementName=MyCropImage}" ????????????????Height="{Binding?CurrentRect.Height,?ElementName=MyCropImage}" ????????????????VerticalAlignment="Center" ????????????????Source="{Binding?CurrentAreaBitmap,?ElementName=MyCropImage}" ????????????????Stretch="Uniform"?/> ????????????<StackPanel ????????????????Grid.Row="1" ????????????????Grid.ColumnSpan="2" ????????????????HorizontalAlignment="Center" ????????????????Orientation="Horizontal"> ????????????????<Button ????????????????????Margin="0,20,10,20" ????????????????????Click="OnImportClickHandler" ????????????????????Content="選擇圖片" ????????????????????Style="{StaticResource?WD.PrimaryButton}"?/> ????????????????<Button ????????????????????Margin="0,20,10,20" ????????????????????Click="BtnSave_Click" ????????????????????Content="保存圖片" ????????????????????Style="{StaticResource?WD.SuccessPrimaryButton}"?/> ????????????</StackPanel> ????????</Grid> </UserControl>
5)新建 CropImageExample.xaml.cs
代碼如下:
- 選擇圖片不允許大于
1M
- 如果選擇的圖片尺寸寬或高大于
500
,則會(huì)修改圖片尺寸一半寬高
using?Microsoft.Win32; using?System; using?System.IO; using?System.Windows; using?System.Windows.Controls; using?System.Windows.Media.Imaging; namespace?WPFDevelopers.Samples.ExampleViews { ????public?partial?class?CropImageExample?:?UserControl ????{ ????????public?CropImageExample() ????????{ ????????????InitializeComponent(); ????????} ????????double?ConvertBytesToMB(long?bytes) ????????{ ????????????return?(double)bytes?/?(1024?*?1024); ????????} ????????private?void?OnImportClickHandler(object?sender,?RoutedEventArgs?e) ????????{ ????????????var?openFileDialog?=?new?OpenFileDialog(); ????????????openFileDialog.Filter?=?"圖像文件(*.jpg;*.jpeg;*.png;)|*.jpg;*.jpeg;*.png;"; ????????????if?(openFileDialog.ShowDialog()?==?true) ????????????{ ????????????????var?fileInfo?=?new?FileInfo(openFileDialog.FileName); ????????????????var?fileSize?=?fileInfo.Length; ????????????????var?mb?=?ConvertBytesToMB(fileSize); ????????????????if?(mb?>?1) ????????????????{ ????????????????????WPFDevelopers.Controls.MessageBox.Show("圖片不能大于?1M?",?"提示",?MessageBoxButton.OK,?MessageBoxImage.Error); ????????????????????return; ????????????????} ????????????????var?bitmap?=?new?BitmapImage(); ????????????????bitmap.BeginInit(); ????????????????bitmap.CacheOption?=?BitmapCacheOption.OnLoad; ????????????????bitmap.UriSource?=?new?Uri(openFileDialog.FileName,?UriKind.Absolute); ????????????????bitmap.EndInit(); ????????????????if?(bitmap.PixelWidth?>?500?||?bitmap.PixelHeight?>?500) ????????????????{ ????????????????????var?width?=?(int)(bitmap.PixelWidth?*?0.5); ????????????????????var?height?=?(int)(bitmap.PixelHeight?*?0.5); ????????????????????var?croppedBitmap?=?new?CroppedBitmap(bitmap,?new?Int32Rect(0,?0,?width,?height)); ????????????????????var?bitmapNew?=?new?BitmapImage(); ????????????????????bitmapNew.BeginInit(); ????????????????????bitmapNew.DecodePixelWidth?=?width; ????????????????????bitmapNew.DecodePixelHeight?=?height; ????????????????????var?memoryStream?=?new?MemoryStream(); ????????????????????var?encoder?=?new?JpegBitmapEncoder(); ????????????????????encoder.Frames.Add(BitmapFrame.Create(croppedBitmap.Source)); ????????????????????encoder.Save(memoryStream); ????????????????????memoryStream.Seek(0,?SeekOrigin.Begin); ????????????????????bitmapNew.StreamSource?=?memoryStream; ????????????????????bitmapNew.EndInit(); ????????????????????MyCropImage.Source?=?bitmapNew; ????????????????} ????????????????else ????????????????{ ????????????????????MyCropImage.Source?=?bitmap; ????????????????} ????????????} ????????} ????????private?void?BtnSave_Click(object?sender,?RoutedEventArgs?e) ????????{ ????????????var?dlg?=?new?SaveFileDialog(); ????????????dlg.FileName?=?$"WPFDevelopers_CropImage_{DateTime.Now.ToString("yyyyMMddHHmmss")}.jpg"; ????????????dlg.DefaultExt?=?".jpg"; ????????????dlg.Filter?=?"image?file|*.jpg"; ????????????if?(dlg.ShowDialog()?==?true) ????????????{ ????????????????var?pngEncoder?=?new?PngBitmapEncoder(); ????????????????pngEncoder.Frames.Add(BitmapFrame.Create((BitmapSource)MyCropImage.CurrentAreaBitmap)); ????????????????using?(var?fs?=?File.OpenWrite(dlg.FileName)) ????????????????{ ????????????????????pngEncoder.Save(fs); ????????????????????fs.Dispose(); ????????????????????fs.Close(); ????????????????} ????????????} ????????} ????} }
效果圖
以上就是基于WPF實(shí)現(xiàn)裁剪圖像功能的詳細(xì)內(nèi)容,更多關(guān)于WPF裁剪圖像的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
.net C# 實(shí)現(xiàn)任意List的笛卡爾乘積算法代碼
笛卡爾(Descartes)乘積又叫直積。假設(shè)集合A={a,b},集合B={0,1,2},則兩個(gè)集合的笛卡爾積為{(a,0),(a,1),(a,2),(b,0),(b,1), (b,2)}。2013-05-05WPF實(shí)現(xiàn)繪制統(tǒng)計(jì)圖(柱狀圖)的方法詳解
這篇文章主要為大家詳細(xì)介紹了如何基于WPF實(shí)現(xiàn)實(shí)現(xiàn)統(tǒng)計(jì)圖(柱狀圖)的繪制,文中的示例代碼簡(jiǎn)潔易懂,對(duì)我們學(xué)習(xí)WPF有一定幫助,感興趣的可以了解一下2022-07-07C# 中const,readonly,static的使用小結(jié)
這篇文章主要介紹了C# 中使用const,readonly,static的示例,幫助大家更好的理解和使用c#,感興趣的朋友可以了解下2021-01-01C# TextBox控件實(shí)現(xiàn)只能輸入數(shù)字的方法
這篇文章主要介紹了C# TextBox控件實(shí)現(xiàn)只能輸入數(shù)字的方法,本文使用TextBox的keypress事件實(shí)現(xiàn)這個(gè)需求,需要的朋友可以參考下2015-06-06