C# 实现的图片盖章功能,支持拖拽、旋转、放缩、保存
C# 实现的图片盖章功能,支持拖拽、旋转、放缩、保存
发布时间:2017-01-07 来源:查字典编辑
摘要:实现图片盖章功能,在图片上点击,增加“图章”小图片,可以拖拽“图章”到任意位置,也可以点击图章右下角园框,令图片跟着鼠标旋转和放缩。操作方法...

实现图片盖章功能,在图片上点击,增加“图章”小图片,可以拖拽“图章”到任意位置,也可以点击图章右下角园框,令图片跟着鼠标旋转和放缩。

操作方法:1.点击增加“图章”2.选中移动图标3.点中右下角放缩旋转图章。

效果图:

C# 实现的图片盖章功能,支持拖拽、旋转、放缩、保存1

实现代码如下:

1. 窗口Xaml代码

复制代码 代码如下:<Window x:Class="Lenovo.YogaPaster.ImageEditWindow"

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

Title="ImageEditWindow" Height="300" Width="300">

<Grid>

<Grid.RowDefinitions>

<RowDefinition Height="20*"/>

<RowDefinition Height="*"/>

</Grid.RowDefinitions>

<Canvas x:Name="canvas"

Background="Yellow" />

<Button Content="保存成图片" Click="Button_Click_1" Grid.Row="1" HorizontalAlignment="Center" VerticalAlignment="Center"/>

</Grid>

</Window>

2. 窗口后台代码:

复制代码 代码如下:using System;

using System.Collections.Generic;

using System.Drawing;

using System.Drawing.Imaging;

using System.IO;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using System.Windows;

using System.Windows.Controls;

using System.Windows.Data;

using System.Windows.Documents;

using System.Windows.Input;

using System.Windows.Media;

using System.Windows.Media.Imaging;

using System.Windows.Shapes;

using Lenovo.YP.Utils;

using Microsoft.Win32;

using Point = System.Windows.Point;

namespace Lenovo.YogaPaster

{

/// <summary>

/// ImageEditWindow.xaml 的交互逻辑

/// </summary>

public partial class ImageEditWindow : Window

{

public ImageEditWindow()

{

InitializeComponent();

this.Loaded += (sender, e) =>

{

canvas.MouseLeftButtonDown += canvas_MouseLeftButtonDown;

};

}

private void canvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)

{

PhotoEditHelper.CommomMaxZIndex++;

var image = new MoveImage { ContainerCanvas = canvas };

Point point = e.GetPosition(canvas);

image.CreateImage(point);

}

/// <summary>

/// 保存方法

/// </summary>

public void SavePicture()

{

//TODO: openFile对话框

SaveFileDialog saveFileDialog = new SaveFileDialog();

saveFileDialog.FileName = "图片"; // Default file name

saveFileDialog.DefaultExt = ".bmp"; // Default file extension

saveFileDialog.Filter = "图片文件 (.bmp)|*.bmp"; // Filter files by extension

// Show save file dialog box

Nullable<bool> result = saveFileDialog.ShowDialog();

// Process save file dialog box results

if (result == true)

{

// Save document

string filename = saveFileDialog.FileName;

if (File.Exists(filename))

{

File.Delete(filename);

}

BitmapSource bitmapSource = PictureMergeHelper.CreateNotRanderElementScreenshot(canvas, 1800, 1080);

BitmapEncoder bitmapEncoder = new BmpBitmapEncoder();

bitmapEncoder.Frames.Add(BitmapFrame.Create(bitmapSource));

FileStream fileStream = new FileStream(filename, FileMode.Create);

bitmapEncoder.Save(fileStream);

fileStream.Dispose();

}

}

private void Button_Click_1(object sender, RoutedEventArgs e)

{

SavePicture();

}

}

}

3. MoveImage 类文件如下:

复制代码 代码如下:using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Windows;

using System.Windows.Controls;

using System.Windows.Input;

using System.Windows.Media;

using System.Windows.Media.Imaging;

namespace Lenovo.YP.Utils

{

/// <summary>

/// 添加一个image控件,并实现拖动效果

/// </summary>

public class MoveImage

{

#region 字段

private int m_ZIndex;

/// <summary>

/// 当前图章的位置

/// </summary>

///

/// <summary>

/// 旋转图标的起始位置

/// </summary>

private Point m_ImageRoundStartOffset;

/// <summary>

/// 旋转图标的当前位置

/// </summary>

private Point m_ImageRoundOffset;

/// <summary>

/// 标识图章是否被拖拽

/// </summary>

private bool m_IsDragging;

/// <summary>

/// 标识旋转图标是否被是否被拖拽

/// </summary>

private bool m_IsimageRoundDragging;

/// <summary>

/// 图章的父容器

/// </summary>

public Canvas ContainerCanvas { get; set; }

/// <summary>

/// 图章图片

/// </summary>

private Image m_FlogImage;

/// <summary>

/// 旋转按钮图片

/// </summary>

private Image m_RotateImage;

/// <summary>

/// 图章和旋转图片的容器

/// </summary>

private Grid m_MoveImageGrid;

/// <summary>

/// 选转

/// </summary>

private RotateTransform m_ImageRotate;

/// <summary>

/// 缩放

/// </summary>

private ScaleTransform m_ImageScale;

/// <summary>

/// 上次位置

/// </summary>

private Point m_OldPos;

#endregion

public MoveImage()

{ }

/// <summary>

/// 创建一个图标

/// </summary>

/// <param name="position">图标的位置</param>

public void CreateImage(Point position)

{

#region 设置布局

m_FlogImage = new Image

{

//Width = 100,

//Height = 100,

Source = new BitmapImage(new Uri("/Images/shuzi.jpg", UriKind.RelativeOrAbsolute))

};

m_RotateImage = new Image

{

Width = 20,

Height = 20,

Source = new BitmapImage(new Uri("/Images/round.jpg", UriKind.RelativeOrAbsolute))

};

m_RotateImage.HorizontalAlignment = HorizontalAlignment.Right;

m_RotateImage.VerticalAlignment = VerticalAlignment.Bottom;

m_RotateImage.Visibility = Visibility.Hidden;

m_MoveImageGrid = new Grid();

m_MoveImageGrid.Width = 110;

m_MoveImageGrid.Height = 110;

m_MoveImageGrid.Children.Add(m_FlogImage);

m_MoveImageGrid.Children.Add(m_RotateImage);

m_MoveImageGrid.MouseEnter += RootGridMouseEnter;

m_MoveImageGrid.MouseLeave += RootGridMouseLeave;

m_RotateImage.MouseLeftButtonDown += imageRound_MouseLeftButtonDown;

m_RotateImage.MouseMove += imageRound_MouseMove;

m_RotateImage.MouseLeftButtonUp += imageRound_MouseLeftButtonUp;

// Image in den Vordergrund bringen

Canvas.SetZIndex(m_MoveImageGrid, m_ZIndex++);

#endregion

// Event Handler für das Image installieren

m_MoveImageGrid.MouseLeftButtonDown += RootGridMouseLeftButtonDown;

m_MoveImageGrid.MouseLeftButtonUp += RootGridMouseLeftButtonUp;

m_MoveImageGrid.MouseMove += RootGridMouseMove;

// Image leicht transparent machen

m_MoveImageGrid.Opacity = 0.8;

m_ImageRotate = new RotateTransform(0, 0, 0);

m_ImageScale = new ScaleTransform();

//m_ImageScale.ScaleX = 1;

//m_ImageScale.ScaleY = 1;

TransformGroup transformGroup = new TransformGroup();

transformGroup.Children.Add(m_ImageRotate);

transformGroup.Children.Add(m_ImageScale);

m_MoveImageGrid.RenderTransform = transformGroup;

//m_ImageScale111 = new ScaleTransform();

//m_ImageScale111.ScaleX = 0.5;

//m_ImageScale111.ScaleY = 0.5;

//imageRound.RenderTransform = m_ImageScale111;

m_MoveImageGrid.RenderTransformOrigin = new Point(0.5, 0.5);

// Image positionieren

var pos = position;

Canvas.SetLeft(m_MoveImageGrid, pos.X - (m_MoveImageGrid.Width / 2));

Canvas.SetTop(m_MoveImageGrid, pos.Y - (m_MoveImageGrid.Height / 2));

// Image zum Canvas hinzufügen

ContainerCanvas.Children.Add(m_MoveImageGrid);

}

/// <summary>

/// 控制旋转图标隐藏

/// </summary>

/// <param name="sender"></param>

/// <param name="e"></param>

private void RootGridMouseLeave(object sender, MouseEventArgs e)

{

m_RotateImage.Visibility = Visibility.Hidden;

}

/// <summary>

/// 控制选择图标显示

/// </summary>

/// <param name="sender"></param>

/// <param name="e"></param>

private void RootGridMouseEnter(object sender, MouseEventArgs e)

{

m_RotateImage.Visibility = Visibility.Visible;

}

#region 控制盖章的移动

private void RootGridMouseMove(object sender, MouseEventArgs e)

{

if (m_IsDragging)

{

var pos = e.GetPosition(ContainerCanvas);

Canvas.SetLeft(m_MoveImageGrid, Canvas.GetLeft(m_MoveImageGrid) + pos.X - m_OldPos.X);

Canvas.SetTop(m_MoveImageGrid, Canvas.GetTop(m_MoveImageGrid) + pos.Y - m_OldPos.Y);

m_OldPos = pos;

}

}

private void RootGridMouseLeftButtonUp(object sender, MouseButtonEventArgs e)

{

var grid = sender as Grid;

// Canvas.SetZIndex(image, m_ZIndex++);

// Bild wieder leicht transparent machen

grid.Opacity = 0.8;

grid.ReleaseMouseCapture();

m_IsDragging = false;

}

private void RootGridMouseLeftButtonDown(object sender, MouseButtonEventArgs e)

{

var grid = sender as Grid;

// auf "nicht"-transparent setzen

grid.Opacity = 1;

// Position des Pointers relativ zum Bild speichern

m_OldPos = e.GetPosition(ContainerCanvas);

// isDragging auf true setzen für MouseMove

m_IsDragging = true;

// Image in den Vordergrund bringen

Canvas.SetZIndex(grid, PhotoEditHelper.CommomMaxZIndex++);

// Den Pointer einfangen. Bei schnellen Bewegungen kann der

// Pointer aus dem Image bewegt werden. Damit die Pointer-

// Events weiterhin stattfinden, wird der Pointer eingefangen.

grid.CaptureMouse();

// als behandelt markieren, damit nicht noch der

// PointerPressed-Event Handler des Canvas aufgerufen wird.

e.Handled = true;

}

#endregion

#region 控制图章的旋转

private void imageRound_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)

{

var image = sender as Image;

m_MoveImageGrid.Opacity = 1;

image.ReleaseMouseCapture();

m_IsimageRoundDragging = false;

}

private void imageRound_MouseMove(object sender, MouseEventArgs e)

{

if (m_IsimageRoundDragging)

{

//鼠标当前点的坐标

m_ImageRoundOffset = e.GetPosition(ContainerCanvas);

m_ImageScale.ScaleX =

m_ImageScale.ScaleY = GetLength(currCenter, m_ImageRoundStartOffset, m_ImageRoundOffset);

m_ImageRotate.Angle = GetAngle(currCenter, m_ImageRoundStartOffset, m_ImageRoundOffset) - 45;

}

}

private Point currCenter;

private void imageRound_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)

{

var image = sender as Image;

m_MoveImageGrid.Opacity = 1;

//中心点坐标

currCenter = new Point(Canvas.GetLeft(m_MoveImageGrid) + m_MoveImageGrid.Width / 2, Canvas.GetTop(m_MoveImageGrid) + m_MoveImageGrid.Height / 2);

m_ImageRoundStartOffset = new Point(currCenter.X + m_MoveImageGrid.Width / 2, currCenter.Y);

m_IsimageRoundDragging = true;

Canvas.SetZIndex(m_MoveImageGrid, PhotoEditHelper.CommomMaxZIndex++);

image.CaptureMouse();

e.Handled = true;

}

/// 根据余弦定理求两个线段夹角

/// </summary>

/// <param name="origin">原点</param>

/// <param name="start">start点</param>

/// <param name="end">end点</param>

/// <returns></returns>

private double GetAngle(Point origin, Point start, Point end)

{

double cosfi = 0, fi = 0, norm = 0;

double dsx = start.X - origin.X;

double dsy = start.Y - origin.Y;

double dex = end.X - origin.X;

double dey = end.Y - origin.Y;

cosfi = dsx * dex + dsy * dey;

norm = (dsx * dsx + dsy * dsy) * (dex * dex + dey * dey);

if (norm == 0) return 0; // origin和end坐标一样

cosfi /= Math.Sqrt(norm);

if (cosfi >= 1.0) return 0;

if (cosfi <= -1.0) return 180;

fi = Math.Acos(cosfi);

double angle = 180 * fi / Math.PI;

if (dey > 0)

{

return angle;

}

return -angle;

}

private double GetLength(Point origin, Point start, Point end)

{

double dex = end.X - origin.X;

double dey = end.Y - origin.Y;

double dsx = start.X - origin.X;

double dsy = start.Y - origin.Y;

double startLength = Math.Sqrt(Math.Pow(dsx, 2) + Math.Pow(dsy, 2));

double endLength = Math.Sqrt(Math.Pow(dex, 2) + Math.Pow(dey, 2));

return endLength / startLength;

}

#endregion

}

推荐文章
猜你喜欢
附近的人在看
推荐阅读
拓展阅读
相关阅读
网友关注
最新C#教程学习
热门C#教程学习
编程开发子分类