WPF customized Image control can add watermark , save and restore

 //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

 

posted @ 2024-06-16 19:23  FredGrit  阅读(5)  评论(0编辑  收藏  举报