首页 > 其他分享 >WPF customized Image control can add watermark , save and restore

WPF customized Image control can add watermark , save and restore

时间:2024-06-16 19:35:15浏览次数:23  
标签:control restore scaler watermark image private dialog new using

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

相关文章

  • 【禁用Windows Defender】Defender Control v2.1
    #简介DefenderControl是一款小型便携式免费软件,可以完全禁用Windows中的WindowsDefender。在特殊的情况的环境里会有不错的效果~提醒:使用前请了解你在干什么,否则请不要轻易使用!#软件截图#更新日志不同的阻塞方法一些代码改进#下载恭喜你发现宝藏站点哦,不妨点进......
  • 【第8章】如何利用ControlNet生成“可控画面”?(配置要求/一键安装/快速上手/生成第一张
    这节我们来讲AI绘画领域中一个很重要的概念:ControlNet,看下如何让生成的画面更可控。......
  • kubernetes-ingress-nginx-controller资源-用于管理和处理集群中的 Ingress 资源
    ingress-nginx-controller是一个常用的KubernetesIngress控制器,它基于NGINX实现,主要用于管理和处理集群中的Ingress资源。Ingress资源是Kubernetes中的一种网络入口资源,用于将外部流量路由到集群内部的服务ingress-nginx-controller的功能作用流量管理和路由#1、......
  • Handycontrol组件库的Bug
    我的WPF程序使用了Handycontrol组件库,前端写了<ButtonWidth="100"Height="30"Margin="40,20,20,-100"HorizontalAlignment="Center"Background="#FF0078D7"Command="{Bindin......
  • WPF dependency property to customize control in usercontrol
    //usercontrol<UserControlx:Class="WpfApp157.ImageListBox"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xm......
  • Watermark Sense for Mac(批量图像水印添加工具)v1.4.3版
    WatermarkSensemac是一款为MacOS平台上设计开发的批量图像水印实用程序.WatermarkSenseforMac(图像批量水印工具)使您能够实现伟大创造性的结果,在批处理模式下,节省大量的时间。WatermarkSensemac软件地址WatermarkSenseMac软件功能WatermarkSense支持文本......
  • c# NuGet中安装了Vlc.DotNet.Forms库 工具箱中没有vlcControl控件???
    在C#的WindowsForms应用程序中,使用NuGet包管理器安装了Vlc.DotNet.Forms库后,如果在工具箱(Toolbox)中没有发现VlcControl控件,这通常意味着控件没有被正确注册或者没有被识别。解决方法:确认Vlc.DotNet.Forms库已正确安装。可以通过检查项目的packages文件夹和project.json文件来......
  • Flink Watermark详解
    Watermark是用于处理流数据中事件时间(eventtime)乱序情况的重要机制。在流处理中,数据往往不是按照它们实际发生的时间顺序到达的,这可能是由于网络延迟、系统处理延迟或其他因素导致的。为了能够在这种乱序环境中正确地执行基于时间的操作(如时间窗口聚合),Flink引入了Waterm......
  • ControlNet++:让AI图像生成更精准、更可控
     在人工智能的世界里,文本到图像的生成技术正变得越来越先进。但如何确保生成的图像精确地反映我们的想象呢?最近,一项名为ControlNet++的新技术为我们提供了答案。ControlNet++是一种新颖的方法,它通过优化生成图像与给定条件之间的像素级循环一致性,显著提高了文本到图像生成的......
  • k8s学习--ingress详细解释与应用(nginx ingress controller))
    文章目录lngress简介什么是IngressIngress的用途Ingress的工作原理Ingress的工作流程Ingress的应用场景应用实验环境部署nginxingresscontroller1.安装metalLB2.nginxingresscontroller部署3.ingress对象应用案例(基于名称的负载均衡)(1)创建deployment控制......