using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Imaging;
using System.Threading.Tasks;
using System.Threading;
using Eventech.DynPicture.Model;
using System.Collections.Concurrent;
namespace Eventech.DynPicture.WinFrmUI
{
///
/// 图片视图控件
/// 获取视图点
///
public partial class PictureEditBasic : UserControl
{
///
/// 构造函数
///
public PictureEditBasic()
{
InitializeComponent();
#region 防止闪烁
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
SetStyle(ControlStyles.DoubleBuffer, true);
SetStyle(ControlStyles.UserPaint, true);
#endregion
this.MinimumSize = new Size(10, 10);
_oldClientRectf = GetClientRectangleF();
this.AsyncLoadingImage = Properties.Resources.Loading;
}
#region 事件
///
/// 异步加载图片完成事件
///
/// 第一个返回值为bool型,判断异步操作是否成功
/// 如果异步操作失败,第二个参数为异常信息,否则为null
public event Action LoadImageAsyncCompletedEvent;
///
/// 点击图片后触发
///
/// 第一个参数为源图位置信息
/// 第二个参数为鼠标相关信息
public event Action ImageViewPointFClickEvent;
#endregion
#region 公开属性
///
/// 源图(赋值后不在对此图片做任何处理)
///
[Browsable(true)]
[Description("源图")]
public virtual Image Image
{
get { return _img; }
set
{
_img = value;
this.DisplayImage = value;
}
}
///
/// 源图
///
protected Image _img = null;
///
/// 获取用于显示的图片的副本(此图片是根据Image进行处理过的图片)
///
public virtual Image DisplayImage
{
get
{
if (_displayImage == null)
return null;
return _displayImage.CloneC();
}
protected set
{
if (_displayImage != null)
_displayImage.Dispose();
_displayImage = CreateOriginDisplayImage(value);
this.Invalidate();
}
}
///
/// 创建原始显示图片
///
/// 源图
/// 初始化的显示图片
protected virtual Image CreateOriginDisplayImage(Image img)
{
if (img == null)
return null;
var cmg = img.CloneC();
_isAutoFit = true;
_displayAngle = 0;
CalcuAutoSize(cmg);
return cmg;
}
///
/// 用于显示的图片
///
protected Image _displayImage = null;
///
/// 当控件释放时是否释放Image
///
[Browsable(true)]
[Description("当控件释放时是否释放图片资源")]
public bool IsDisposeImageWhenDisposed
{
get { return _isDisposeImageWhenDisposed; }
set { _isDisposeImageWhenDisposed = value; }
}
private bool _isDisposeImageWhenDisposed = false;
///
/// Image至DisplayImage的旋转角度(顺时针)
///
protected int _displayAngle = 0;
///
/// 无图片时用于显示的提示文本
///
[Browsable(true)]
[Description("无图片时显示文字")]
public string NullText
{
get { return _nullText; }
set { _nullText = value; }
}
private string _nullText = "无图片";
#endregion
#region 同步加载
///
/// 同步加载
///
///
public void LoadImageSync(string fileName)
{
if (System.IO.File.Exists(fileName))
this.Image = Image.FromFile(fileName);
}
#endregion
#region 异步加载图片
private Task _load_async_task = null;//当前异步加载任务
private readonly ConcurrentDictionary _dict_load_async_task_cancel = new ConcurrentDictionary();
private object _locker_load_async_task = new object();//任务锁
///
/// 异步加载图片时用于显示的图片
///
[Browsable(true)]
[Description("异步加载图片时的显示动画")]
public virtual Image AsyncLoadingImage
{
set
{
if (_asyncLoadingImage != null)
{
if (_animateImage != null)
_animateImage.Dispose();
else
_asyncLoadingImage.Dispose();
}
_asyncLoadingImage = null;
_animateImage = null;
if (value != null)
{
_asyncLoadingImage = (Image)value.Clone();
if (_asyncLoadingImage != null && ImageAnimator.CanAnimate(_asyncLoadingImage))
{
_animateImage = new AnimateImage(_asyncLoadingImage);
_animateImage.OnFrameChanged += delegate { this.Invalidate(); };
}
else
{
_animateImage = null;
}
}
}
}
///
/// 异步加载图片时的动态图
///
protected Image _asyncLoadingImage;
///
/// 是否正在异步加载图片
///
protected bool _isAsyncLoading = false;
///
/// 动态图片操作对象
///
protected AnimateImage _animateImage = null;
///
/// 异步加载图片
///
/// 文件磁盘路径
///
public void LoadImageAsync(string fileName)
{
_isAsyncLoading = true;
if (_animateImage != null)
_animateImage.Play();
this.Invalidate();
var task = Task.Factory.StartNew(() =>
{
return Image.FromFile(fileName);
});
task.ContinueWith((tas) =>
{
if (IsDisposed)
return;
while (!IsHandleCreated)
{
Thread.Sleep(10);
}
this.Invoke(new Action(() =>
{
_isAsyncLoading = false;
if (_animateImage != null)
{
_animateImage.Stop();
}
this.Image = tas.Result;
if (this.LoadImageAsyncCompletedEvent != null)
{
var flag = tas.IsFaulted ? false : true;
var ex = tas.Exception == null ? null : tas.Exception.GetBaseException();
this.LoadImageAsyncCompletedEvent(flag, ex);
}
}));
});
}
///
/// 异步加载图片
///
/// 参数为返回图片路径的委托
public void LoadImageAsync(Func dele)
{
_isAsyncLoading = true;
if (_animateImage != null)
_animateImage.Play();
this.Invalidate();
var task = Task.Factory.StartNew(() =>
{
return Image.FromFile(dele());
});
task.ContinueWith((tas) =>
{
if (IsDisposed)
return;
while (!IsHandleCreated)
{
Thread.Sleep(10);
}
this.Invoke(new Action(() =>
{
_isAsyncLoading = false;
if (_animateImage != null)
{
_animateImage.Stop();
}
this.Image = tas.Result;
if (this.LoadImageAsyncCompletedEvent != null)
{
var flag = tas.IsFaulted ? false : true;
var ex = tas.Exception == null ? null : tas.Exception.GetBaseException();
this.LoadImageAsyncCompletedEvent(flag, ex);
}
}));
});
}
///
/// 异步加载图片
///
/// 参数为返回图片的委托
public void LoadImageAsync(Func dele)
{
lock (_locker_load_async_task)
{
if (_load_async_task != null)
{
if (_isAsyncLoading)
{
_isAsyncLoading = false;
if (_animateImage != null)
{
_animateImage.Stop();
}
_dict_load_async_task_cancel.AddOrUpdate(_load_async_task.Id, true, (key, oldValue) => true);
}
}
}
_isAsyncLoading = true;
if (_animateImage != null)
_animateImage.Play();
this.Invalidate();
var task = Task.Factory.StartNew(() =>
{
_dict_load_async_task_cancel.TryAdd(Task.CurrentId.Value, false);
return dele();
});
lock (_locker_load_async_task)
{
_load_async_task = task;
}
task.ContinueWith((tas) =>
{
bool cancel = false;
if (IsDisposed)
{
_dict_load_async_task_cancel.TryRemove(tas.Id, out cancel);
return;
}
while (!IsHandleCreated)
{
Thread.Sleep(10);
}
if (_dict_load_async_task_cancel.TryRemove(tas.Id, out cancel))
{
if (cancel)
return;
this.Invoke(new Action(() =>
{
_isAsyncLoading = false;
if (_animateImage != null)
{
_animateImage.Stop();
}
this.Image = tas.Result;
if (this.LoadImageAsyncCompletedEvent != null)
{
var flag = tas.IsFaulted ? false : true;
var ex = tas.Exception == null ? null : tas.Exception.GetBaseException();
this.LoadImageAsyncCompletedEvent(flag, ex);
}
}));
}
});
}
///
/// 异步加载图片
///
/// 参数为返回图片的委托
//public void LoadImageAsync(Func loadImage_cb,Action finish_cb)
//{
// _isAsyncLoading = true;
// if (_animateImage != null)
// _animateImage.Play();
// this.Invalidate();
// var task = Task.Factory.StartNew(() =>
// {
// return loadImage_cb();
// });
// task.ContinueWith((tas) =>
// {
// if (IsDisposed)
// return;
// while (!IsHandleCreated)
// {
// Thread.Sleep(10);
// }
// this.Invoke(new Action(() =>
// {
// _isAsyncLoading = false;
// if (_animateImage != null)
// {
// _animateImage.Stop();
// }
// var img = tas.Result;
// this.Image = img;
// if (finish_cb != null && img != null)
// {
// finish_cb.Invoke(img);
// }
// if (this.LoadImageAsyncCompletedEvent != null)
// {
// var flag = tas.IsFaulted ? false : true;
// var ex = tas.Exception == null ? null : tas.Exception.GetBaseException();
// this.LoadImageAsyncCompletedEvent(flag, ex);
// }
// }));
// });
//}
#endregion
#region 边框
///
/// 边框颜色
///
[Browsable(true)]
[Description("自定义边框颜色")]
public Color CustomBorderColor
{
get { return _customBorderColor; }
set { _customBorderColor = value; }
}
private Color _customBorderColor = Color.Black;
///
/// 边框宽度
///
[Browsable(true)]
[Description("自定义边框宽度")]
public int CustomBorderWidth
{
get { return _customBorderWidth; }
set { _customBorderWidth = value; }
}
private int _customBorderWidth = 1;
///
/// 边框是否显示
///
[Browsable(true)]
[Description("自定义边框可见性")]
[DefaultValue(false)]
public bool CustomBorderVisible
{
get { return _customBorderVisible; }
set
{
_customBorderVisible = value;
}
}
private bool _customBorderVisible = false;
///
/// 绘制边框
///
protected virtual void DrawBorder(Graphics g)
{
if (this.CustomBorderVisible)
{
var x = this.CustomBorderWidth / 2f;
var y = this.CustomBorderWidth / 2f;
var width = this.Width - this.CustomBorderWidth;
var height = this.Height - this.CustomBorderWidth;
using (var pen = new Pen(this.CustomBorderColor, this.CustomBorderWidth))
{
g.DrawRectangle(pen, x, y, width, height);
}
}
}
#endregion
#region 鼠标左键按下拖动图片
///
/// 是否允许鼠标左键按下拖动图片
///
[Browsable(true)]
[Description("是否允许鼠标左键按下拖动图片")]
[DefaultValue(true)]
public bool AllowMouseDownMoveImage
{
get { return _allowMouseDownMoveImage; }
set { _allowMouseDownMoveImage = value; }
}
private bool _allowMouseDownMoveImage = true;
//鼠标左键是否按下
private bool _mouseLeftDown = false;
//鼠标左键移动点位置
private Point _mouseLeftMovePoint;
///
/// 鼠标按下
///
///
protected override void OnMouseDown(MouseEventArgs e)
{
base.OnMouseDown(e);
if (e.Button == MouseButtons.Left)
{
if (_displayImage != null)
{
if (this.AllowMouseDownMoveImage)
{
if (_desRectf.Contains(e.Location))
{
_mouseLeftDown = true;
_mouseLeftMovePoint = e.Location;
}
}
}
}
}
///
/// 鼠标移动
///
///
protected override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
if (_displayImage != null)
{
if (_desRectf.Contains(e.Location))
{
this.Cursor = Cursors.Hand;
if (_allowMouseDownMoveImage)
{
if (_mouseLeftDown)
{
MoveImage(e.Location);
}
}
return;
}
}
this.Cursor = Cursors.Default;
}
///
/// 鼠标弹起
///
///
protected override void OnMouseUp(MouseEventArgs e)
{
base.OnMouseUp(e);
_mouseLeftDown = false;
}
#endregion
#region 鼠标点击满足相关条件后触发 ImageViewPointFClickEvent 事件
///
/// 鼠标点击触发获取控件位置点对应源图片位置点事件
///
///
protected override void OnMouseClick(MouseEventArgs e)
{
base.OnMouseClick(e);
if (_displayImage != null)
{
if (this.ImageViewPointFClickEvent != null)
{
if (_desRectf.Contains(e.Location))
{
var dp = ViewPointToDisplay(e.Location);
var sp = DisplayPointToSource(dp);
this.ImageViewPointFClickEvent(sp, e);
}
}
}
}
#endregion
#region 相关参数
///
/// 源矩形
///
protected RectangleF _srcRectf;
///
/// 图片缩放矩形
///
protected RectangleF _zoomRectf;
///
/// 目标矩形
///
protected RectangleF _desRectf;
///
/// 上一次控件矩形
///
protected RectangleF _oldClientRectf;
///
/// 最小缩放系数
///
protected int _minZoom = 1;
///
/// 最大缩放系数
///
protected int _maxZoom = 3200;
///
/// 当前缩放系数
///
protected float _currentZoom;
///
/// 是否为自适应状态
///
protected bool _isAutoFit = false;
#endregion
#region 事件处理程序
///
/// 控件改变大小
///
///
protected override void OnResize(EventArgs e)
{
base.OnResize(e);
if (_displayImage != null)
{
if (_isAutoFit)
{
CalcuAutoSize(_displayImage);
}
else
{
//如果之前图片全在容器内
if (_oldClientRectf.Contains(_zoomRectf))
{
var borderWidth = _customBorderVisible ? _customBorderWidth : 0;
_zoomRectf.X = (_zoomRectf.X - borderWidth) / _oldClientRectf.Width * (this.Width - 2 * _customBorderWidth);
_zoomRectf.Y = (_zoomRectf.Y - borderWidth) / _oldClientRectf.Height * (this.Height - 2 * _customBorderWidth);
}
_desRectf = GetClientRectangleF();
_desRectf.Intersect(_zoomRectf);
_srcRectf = CalcuSrcRectangleF(_zoomRectf, _desRectf);
}
}
_oldClientRectf = GetClientRectangleF();
this.Invalidate();
}
///
/// 控件重绘
///
///
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
DrawBorder(e.Graphics);
if (_isAsyncLoading)
{
DrawAsyncLodingImage(e.Graphics);
}
else
{
if (_displayImage == null)
{
DrawNullText(e.Graphics);
}
else
{
e.Graphics.DrawImage(_displayImage, _desRectf, _srcRectf, GraphicsUnit.Pixel);
}
}
}
///
/// 绘制NullText
///
///
protected virtual void DrawNullText(Graphics g)
{
if (!string.IsNullOrEmpty(this.NullText))
{
var rectf = GetClientRectangleF();
using (var brush = new SolidBrush(this.ForeColor))
{
var stringformat = new StringFormat();
stringformat.Alignment = StringAlignment.Center;
stringformat.LineAlignment = StringAlignment.Center;
var p = new PointF(rectf.Width / 2 + rectf.X, rectf.Height / 2 + rectf.Y);
g.DrawString(this.NullText, this.Font, brush, p, stringformat);
}
}
}
///
/// 绘制异步加载图片
///
///
protected virtual void DrawAsyncLodingImage(Graphics g)
{
lock (_asyncLoadingImage)
{
if (_asyncLoadingImage != null)
{
var clientRectf = GetClientRectangleF();
var scale = 1f;
if (_asyncLoadingImage.Width > clientRectf.Width || _asyncLoadingImage.Height > clientRectf.Height)
{
var xscale = _asyncLoadingImage.Width / clientRectf.Width;
var yscale = _asyncLoadingImage.Height / clientRectf.Height;
scale = xscale > yscale ? xscale : yscale;
}
var autoWidth = _asyncLoadingImage.Width / scale;
var autoHeight = _asyncLoadingImage.Height / scale;
var zoomx = (clientRectf.Width - autoWidth) / 2;
var zoomy = (clientRectf.Height - autoHeight) / 2;
var desRectf = new RectangleF(zoomx, zoomy, autoWidth, autoHeight);
var srcRectf = new RectangleF(0, 0, _asyncLoadingImage.Width, _asyncLoadingImage.Height);
if (_animateImage != null)
{
g.DrawImage(_animateImage.Image, desRectf, srcRectf, GraphicsUnit.Pixel);
}
else
{
g.DrawImage(_asyncLoadingImage, desRectf, srcRectf, GraphicsUnit.Pixel);
}
}
}
}
///
/// 鼠标滚轮移动
///
///
protected override void OnMouseWheel(MouseEventArgs e)
{
base.OnMouseWheel(e);
if (_displayImage == null)
return;
if (!this.ClientRectangle.Contains(e.Location))
return;
var flag = e.Delta > 0 ? 1 : 0;
ZoomImage(flag, e.Location);
}
#endregion
#region 可继承方法
///
/// flag为0代表缩小,其他代表放大,p为放大或缩小的中心点
///
///
///
protected void ZoomImage(int flag, Point? p = null)
{
_isAutoFit = false;
#region zoom
float zoom;
if (flag == 0)//缩小
{
if (_currentZoom > _minZoom)
zoom = _currentZoom * 0.9f;
else
zoom = _minZoom;
if (zoom < _minZoom)
zoom = _minZoom;
}
else
{
if (_currentZoom < _maxZoom)
{
zoom = _currentZoom * 1.1f;
}
else
{
zoom = _maxZoom;
}
if (zoom > _maxZoom)
zoom = _maxZoom;
}
#endregion
#region RectangleF
PointF px;
if (p != null && _desRectf.Contains(p.Value))
{
px = new PointF(p.Value.X, p.Value.Y);
}
else
{
px = new PointF(_desRectf.X + _desRectf.Width / 2, _desRectf.Y + _desRectf.Height / 2);
}
var pxScaleX = (px.X - _zoomRectf.X) / _zoomRectf.Width;
var pxScaleY = (px.Y - _zoomRectf.Y) / _zoomRectf.Height;
_zoomRectf.X = _zoomRectf.X - _displayImage.Width / 100f * (zoom - _currentZoom) * pxScaleX;
_zoomRectf.Y = _zoomRectf.Y - _displayImage.Height / 100f * (zoom - _currentZoom) * pxScaleY;
_zoomRectf.Width = _displayImage.Width / 100f * zoom;
_zoomRectf.Height = _displayImage.Height / 100f * zoom;
_desRectf = GetClientRectangleF();
_desRectf.Intersect(_zoomRectf);
_srcRectf = CalcuSrcRectangleF(_zoomRectf, _desRectf);
#endregion
_currentZoom = zoom;
this.Invalidate();
}
///
/// 移动图片
///
///
protected void MoveImage(Point p)
{
if (this.Image == null)
return;
_isAutoFit = false;
_zoomRectf.X += p.X - _mouseLeftMovePoint.X;
_zoomRectf.Y += p.Y - _mouseLeftMovePoint.Y;
_desRectf = GetClientRectangleF();
_desRectf.Intersect(_zoomRectf);
_srcRectf = CalcuSrcRectangleF(_zoomRectf, _desRectf);
_mouseLeftMovePoint = p;
this.Invalidate();
}
///
/// 通过_zoomRectf和desRectf计算_srcRectf
///
///
///
///
protected RectangleF CalcuSrcRectangleF(RectangleF zoomRectf, RectangleF desRectf)
{
var srcScaleX = (desRectf.X - zoomRectf.X) / zoomRectf.Width;
var srcScaleY = (desRectf.Y - zoomRectf.Y) / zoomRectf.Height;
var srcScaleW = desRectf.Width / zoomRectf.Width;
var srcScaleH = desRectf.Height / zoomRectf.Height;
var x = _displayImage.Width * srcScaleX;
var y = _displayImage.Height * srcScaleY;
var width = _displayImage.Width * srcScaleW;
var height = _displayImage.Height * srcScaleH;
return new RectangleF(x, y, width, height);
}
///
/// 计算自适应的相关参数
///
///
protected void CalcuAutoSize(Image img)
{
if (img == null)
return;
var crectf = GetClientRectangleF();
var scale = 1f;
if (img.Width > crectf.Width || img.Height > crectf.Height)
{
var xscale = img.Width / crectf.Width;
var yscale = img.Height / crectf.Height;
scale = xscale > yscale ? xscale : yscale;
}
_currentZoom = 100 / scale;
var autoWidth = img.Width / scale;
var autoHeight = img.Height / scale;
var zoomx = (crectf.Width - autoWidth) / 2;
var zoomy = (crectf.Height - autoHeight) / 2;
_srcRectf = new RectangleF(0, 0, img.Width, img.Height);
_zoomRectf = new RectangleF(zoomx, zoomy, autoWidth, autoHeight);
_desRectf = _zoomRectf;
}
///
/// 获取工作区域(去除边框)
///
///
protected RectangleF GetClientRectangleF()
{
if (_customBorderVisible)
{
return new RectangleF(_customBorderWidth, _customBorderWidth, this.Width - 2 * _customBorderWidth, this.Height - 2 * _customBorderWidth);
}
else
{
return new RectangleF(0, 0, this.Width, this.Height);
}
}
///
/// 旋转图片
///
///
protected void RotateImage(Image img)
{
var angle = _displayAngle % 360;
switch (angle)
{
case 90: img.RotateFlip(RotateFlipType.Rotate90FlipNone); break;
case 180: img.RotateFlip(RotateFlipType.Rotate180FlipNone); break;
case 270: img.RotateFlip(RotateFlipType.Rotate270FlipNone); break;
default: break;
}
}
#endregion
#region 公有方法
///
/// 重置图片
///
public void ResetImage()
{
this.DisplayImage = _img;
}
///
/// 显示加载界面
///
public void ShowLoading()
{
_isAsyncLoading = true;
if (_animateImage != null)
_animateImage.Play();
this.Invalidate();
}
///
/// 隐藏加载界面
///
public void HideLoading()
{
_isAsyncLoading = false;
if (_animateImage != null)
_animateImage.Stop();
this.Invalidate();
}
///
/// 自适应(针对于显示图片)
///
public void SetAutoFit()
{
if (_displayImage == null)
return;
_isAutoFit = true;
CalcuAutoSize(_displayImage);
this.Invalidate();
}
///
/// 保存图片
///
///
///
public bool SaveDisplayImage(string fileName)
{
if (_displayImage == null)
return false;
try
{
_displayImage.Save(fileName);
return true;
}
catch
{
return false;
}
}
///
/// 保存至Png格式
///
public bool ExportToBmp()
{
string file_path = null;
return ExportToBmp(out file_path);
}
///
/// 保存至BMP格式
///
public bool ExportToBmp(out string file_path)
{
file_path = null;
if (_displayImage == null)
return false;
var dlg = new SaveFileDialog();
dlg.Title = "保存Bmp格式图片";
dlg.Filter = "图片|*.bmp";
dlg.AutoUpgradeEnabled = true;
dlg.AddExtension = true;
dlg.DefaultExt = ".bmp";
if (dlg.ShowDialog() == DialogResult.OK)
{
_displayImage.Save(dlg.FileName, ImageFormat.Bmp);
file_path = dlg.FileName;
return true;
}
else
{
return false;
}
}
///
/// 保存至Png格式
///
public bool ExportToPng()
{
string file_path = null;
return ExportToPng(out file_path);
}
///
/// 保存至Png格式
///
public bool ExportToPng(out string file_path)
{
file_path = null;
if (_displayImage == null)
return false;
var dlg = new SaveFileDialog();
dlg.Title = "保存PNG格式图片";
dlg.Filter = "图片|*.png";
dlg.AutoUpgradeEnabled = true;
dlg.AddExtension = true;
dlg.DefaultExt = ".png";
if (dlg.ShowDialog() == DialogResult.OK)
{
_displayImage.Save(dlg.FileName, ImageFormat.Png);
file_path = dlg.FileName;
return true;
}
else
{
return false;
}
}
///
/// 保存至Png格式
///
///
///
public bool ExportToPng(string filePath)
{
_displayImage.Save(filePath, ImageFormat.Png);
return true;
}
///
/// 保存至Png格式
///
public bool ExportToJpeg()
{
string file_path = null;
return ExportToJpeg(out file_path);
}
///
/// 保存至Jpeg格式
///
public bool ExportToJpeg(out string file_path)
{
file_path = null;
if (_displayImage == null)
return false;
var dlg = new SaveFileDialog();
dlg.Title = "保存Jpeg格式图片";
dlg.Filter = "图片|*.jpeg";
dlg.AutoUpgradeEnabled = true;
dlg.AddExtension = true;
dlg.DefaultExt = ".jpeg";
if (dlg.ShowDialog() == DialogResult.OK)
{
file_path = dlg.FileName;
_displayImage.Save(dlg.FileName, ImageFormat.Jpeg);
return true;
}
return false;
}
///
/// 向右旋转90度
///
public void RotateToRight()
{
if (_displayImage == null)
return;
_displayImage.RotateFlip(RotateFlipType.Rotate90FlipNone);
_displayAngle += 90;
SetAutoFit();
}
///
/// 向左旋转90度
///
public void RotateToLeft()
{
if (_displayImage == null)
return;
_displayImage.RotateFlip(RotateFlipType.Rotate270FlipNone);
_displayAngle += 270;
SetAutoFit();
}
///
/// 替换图片(如果尺寸相同保持状态,否则重置)
///
///
public virtual void ReplaceImage(Image img)
{
if (img != null && _img != null)
{
if (img.Size == _img.Size)
{
_img = img;
var cimg = _img.CloneC();
RotateImage(cimg);
if (_displayImage != null)
_displayImage.Dispose();
_displayImage = cimg;
this.Invalidate();
return;
}
}
this.Image = img;
}
///
/// 放大
///
public void ZoomOut()
{
if (this.Image == null)
return;
ZoomImage(1);
}
///
/// 缩小
///
public void ZoomIn()
{
if (this.Image == null)
return;
ZoomImage(0);
}
#endregion
#region 坐标转换
///
/// 根据容器上的点获取相对于显示图片的点位置
///
///
///
protected virtual PointF ViewPointToDisplay(PointF vp)
{
var dp = new PointF();
dp.X = (vp.X - _zoomRectf.X) / _currentZoom * 100;
dp.Y = (vp.Y - _zoomRectf.Y) / _currentZoom * 100;
return dp;
}
///
/// 根据容器上的点获取相对于源图的点位置
///
///
///
public virtual PointF? ViewPointToImage(PointF vf)
{
if (Image == null)
return null;
if (!_desRectf.Contains(vf))
return null;
var dp = ViewPointToDisplay(vf);
var sp = DisplayPointToSource(dp);
return sp;
}
///
/// 将DisplayImage上的点坐标转换为Image上的坐标
///
///
///
protected virtual PointF DisplayPointToSource(PointF dp)
{
var sp = dp;
var angle = _displayAngle % 360;
switch (angle)
{
case 90: sp = new PointF(dp.Y, _displayImage.Width - dp.X); break;
case 180: sp = new PointF(_displayImage.Width - dp.X, _displayImage.Height - dp.Y); break;
case 270: sp = new PointF(_displayImage.Height - dp.Y, dp.X); break;
default: break;
}
return sp;
}
///
/// 将Image上的点坐标转换为DisplayImage上的坐标
///
///
///
protected virtual PointF SourcePointToDisplay(PointF sp)
{
var dp = sp;
var angle = _displayAngle % 360;
switch (angle)
{
case 90: dp = new PointF(_img.Height - sp.Y, sp.X); break;
case 180: dp = new PointF(_img.Width - sp.X, this.Image.Height - sp.Y); break;
case 270: dp = new PointF(sp.Y, _img.Width - sp.X); break;
default: break;
}
return dp;
}
///
/// 通过源图点获取zoom图片点
///
///
///
protected virtual PointF SourcePointToZoom(PointF sp)
{
var dp = SourcePointToDisplay(sp);
var zp = DisplayPointToZoom(dp);
return zp;
}
///
/// 通过DislayImage上的点获取Zoom上的点
///
///
///
protected virtual PointF DisplayPointToZoom(PointF dp)
{
var zp = new PointF();
zp.X = dp.X * _currentZoom / 100 + _zoomRectf.X;
zp.Y = dp.Y * _currentZoom / 100 + _zoomRectf.Y;
return zp;
}
#endregion
///
/// 释放图片资源
///
protected virtual void DisposeImages()
{
if (_displayImage != null)
_displayImage.Dispose();
if (_animateImage == null)
{
if (_asyncLoadingImage != null)
_asyncLoadingImage.Dispose();
}
else
{
_animateImage.Dispose();
}
if (_img != null)
{
if (this.IsDisposeImageWhenDisposed)
{
_img.Dispose();
}
}
}
}
}