//usercontrol
//xaml <UserControl x:Class="WpfApp173.ImageZoomPanWatermark" 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:local="clr-namespace:WpfApp173" mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="50"/> <RowDefinition /> </Grid.RowDefinitions> <ToolBar Grid.Row="0"> <Button Content="Open" Click="OpenClick" Width="100" /> <CheckBox Content="Add Watermark" Width="100" x:Name="checkBx"/> <Button Content="Save Image" Click="SaveMarkedImgClick" Width="100"/> <Button Content="Restore" Click="RestoreClick" Width="100"/> </ToolBar> <Grid x:Name="gd" Grid.Row="1" Background="Transparent" ClipToBounds="True" MouseDown="Grid_MouseDown" MouseUp="Grid_MouseUp" MouseWheel="Grid_MouseWheel" MouseMove="Grid_MouseMove"> <Image x:Name="img" ClipToBounds="True" > <Image.RenderTransform> <TransformGroup> <ScaleTransform x:Name="scaler"/> <TranslateTransform x:Name="translater"/> </TransformGroup> </Image.RenderTransform> </Image> </Grid> </Grid> </UserControl> //usercontrol.cs using Microsoft.Win32; using System; using System.Globalization; using System.IO; using System.Windows; using System.Windows.Controls; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; namespace WpfApp173 { /// <summary> /// Interaction logic for ImageZoomPanWatermark.xaml /// </summary> public partial class ImageZoomPanWatermark : UserControl { public ImageZoomPanWatermark() { InitializeComponent(); } private BitmapImage rawBmi { get; set; } private string rawImgUrl { get; set; } private void OpenClick(object sender, RoutedEventArgs e) { OpenFileDialog dialog = new OpenFileDialog(); dialog.Filter = "Jpg files|*.jpg|Jpeg files|*.jpeg|All files|*.*"; if (dialog.ShowDialog() == true) { string imgUrl = dialog.FileName; rawBmi = new BitmapImage(); rawBmi.BeginInit(); rawBmi.UriSource = new Uri(imgUrl, UriKind.RelativeOrAbsolute); rawBmi.EndInit(); img.Source = rawBmi; rawImgUrl = dialog.FileName; } } private void SaveMarkedImgClick(object sender, RoutedEventArgs e) { SaveFileDialog dialog= new SaveFileDialog(); dialog.Filter = "Jpg Files|*.jpg|All Files|*.*"; if(dialog.ShowDialog()==true) { string newImgFileName= dialog.FileName; using(FileStream fs=new FileStream(newImgFileName, FileMode.Create)) { var encoder = new JpegBitmapEncoder(); encoder.Frames.Add(BitmapFrame.Create((BitmapSource)img.Source)); encoder.QualityLevel = 100; encoder.Save(fs); } } } bool isMoving = false; Point oldPoint { get; set; } private void Grid_MouseDown(object sender, MouseButtonEventArgs e) { oldPoint = e.GetPosition(this); if (checkBx.IsChecked == true) { string str = $"({oldPoint.X},{oldPoint.Y})——{DateTime.Now.ToString("yyyyMMddHHmmss")}"; BitmapImage bmi = new BitmapImage(); bmi.BeginInit(); var bytes = ImageSourceToBytes(img.Source); bmi.StreamSource = new MemoryStream(bytes); bmi.EndInit(); img.Source = GenMarkedImage(bmi, str, e.GetPosition(img)); } } public byte[] ImageSourceToBytes(ImageSource imageSource) { byte[] bytes = null; var bitmapSource = imageSource as BitmapSource; if (bitmapSource != null) { JpegBitmapEncoder encoder = new JpegBitmapEncoder(); encoder.Frames.Add(BitmapFrame.Create(bitmapSource)); using (var stream = new MemoryStream()) { encoder.Save(stream); bytes = stream.ToArray(); } } return bytes; } public BitmapSource GenMarkedImage(BitmapImage image, string watermarkText, Point markedPoint) { FontFamily ff = new FontFamily("Times New Roman"); var typeface = new Typeface(ff, FontStyles.Normal, FontWeights.Normal, FontStretches.Normal); var text = new FormattedText( watermarkText, CultureInfo.InvariantCulture, FlowDirection.LeftToRight, typeface, 100, Brushes.Cyan, 1.25); var visual = new DrawingVisual(); using (var drawingContext = visual.RenderOpen()) { drawingContext.DrawImage(image, new Rect(0, 0, image.Width, image.Height)); double xScale = image.Width / gd.ActualWidth; double yScale = image.Height / gd.ActualHeight; drawingContext.DrawText(text, new Point(markedPoint.X* xScale, markedPoint.Y* yScale)); } var bitmap = new RenderTargetBitmap(image.PixelWidth, image.PixelHeight, image.DpiX, image.DpiY, PixelFormats.Default); bitmap.Render(visual); return bitmap; } private void Grid_MouseUp(object sender, MouseButtonEventArgs e) { if (isMoving && e.ChangedButton == MouseButton.Left && e.ButtonState == MouseButtonState.Released) { Point newPt = e.GetPosition(this); translater.X += newPt.X - oldPoint.X; translater.Y += newPt.Y - oldPoint.Y; isMoving = false; } } private void Grid_MouseWheel(object sender, MouseWheelEventArgs e) { if (e.Delta > 0) { scaler.ScaleX *= 1.2; scaler.ScaleY *= 1.2; } else { scaler.ScaleX /= 1.2; scaler.ScaleY /= 1.2; } scaler.CenterX = e.GetPosition(img).X; scaler.CenterY = e.GetPosition(img).Y; } private void Grid_MouseMove(object sender, MouseEventArgs e) { isMoving = true; } private void RestoreClick(object sender, RoutedEventArgs e) { scaler.CenterX = 0; scaler.CenterY = 0; scaler.ScaleX = 1.0; scaler.ScaleY = 1.0; translater.X = 0; translater.Y = 0; img.Source = new BitmapImage(new Uri(rawImgUrl, UriKind.RelativeOrAbsolute)); } } }
//mainwindow
<Window x:Class="WpfApp173.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:WpfApp173" mc:Ignorable="d" WindowState="Maximized" Title="MainWindow" Height="450" Width="800"> <Grid> <local:ImageZoomPanWatermark/> </Grid> </Window>
Open image
Add watermark
Save
Restore
标签:control,restore,scaler,watermark,image,private,dialog,new,using From: https://www.cnblogs.com/Fred1987/p/18251127