using System;
|
using System.Collections.Generic;
|
using System.ComponentModel;
|
using System.Drawing;
|
using System.Drawing.Drawing2D;
|
using System.Linq;
|
using System.Runtime.InteropServices;
|
using System.Text;
|
using System.Windows.Forms;
|
using DPumpHydr.WinFrmUI.WenSkin.Controls;
|
|
namespace DPumpHydr.WinFrmUI.WenSkin.Test
|
{
|
public class WenPie : WenControl
|
{
|
|
|
public WenPie() : base()
|
{
|
}
|
|
#region 私有属性
|
|
private int value = 5;
|
private int cutCount = 60;
|
|
#endregion
|
|
#region 公有属性
|
|
[Category("Wen"), Description("显示图标"), DefaultValue(null)]
|
public Image Image { get; set; }
|
|
[Category("Wen"), Description("进度值"), DefaultValue(0)]
|
public int Value { get => value; set { this.value = value; this.Invalidate(); this.Refresh(); } }
|
|
[Category("Wen"), Description("获取或设置最大值(切割份数)"), DefaultValue(60)]
|
public int CutCount { get => cutCount; set => cutCount = value; }
|
#endregion
|
protected override void OnPaint(PaintEventArgs e)
|
{
|
base.OnPaint(e);
|
|
Graphics g = e.Graphics.SetGDIHigh();
|
|
if (Image == null)
|
return;
|
|
if (Value > CutCount)
|
return;
|
|
//计算中点
|
float w = Width / 2;
|
float h = Height / 2;
|
|
g.DrawImage(Image, new Rectangle(0, 0, Width, Height));
|
|
Bitmap bitmap = WhiteAndBlack(new Bitmap(Image));
|
Image image = ResizeImage(bitmap, Width, Height);
|
Brush brush = new TextureBrush(image);
|
|
//计算坐标点
|
//先确定角度
|
double angle = 360.00 / CutCount * Value;
|
if (angle >= 360)
|
return;
|
|
PointF pointF = new PointF();
|
|
List<PointF> pointFs = new List<PointF>();
|
if (angle < 45)
|
{
|
double tanValue = Math.PI * angle / 180;
|
pointF.X = Math.Abs((float)(Math.Atan(tanValue) * h));
|
pointF.Y = h;
|
|
//设置路径并绘制
|
pointFs.Add(new PointF(0, h));
|
pointFs.Add(new PointF(0, 0));
|
pointFs.Add(pointF);
|
pointFs.Add(new PointF(w, h));
|
pointFs.Add(new PointF(w, -h));
|
pointFs.Add(new PointF(-w, -h));
|
pointFs.Add(new PointF(-w, h));
|
}
|
else if (angle < 90)
|
{
|
double tanValue = Math.PI * (90 - angle) / 180;
|
pointF.Y = Math.Abs((float)Math.Tan(tanValue) * w);
|
pointF.X = w;
|
pointFs.Add(new PointF(0, h));
|
pointFs.Add(new PointF(0, 0));
|
pointFs.Add(pointF);
|
pointFs.Add(new PointF(w, -h));
|
pointFs.Add(new PointF(-w, -h));
|
pointFs.Add(new PointF(-w, h));
|
}
|
else if (angle < 135)
|
{
|
double tanValue = Math.PI * (angle - 90) / 180;
|
pointF.Y = -Math.Abs((float)Math.Tan(tanValue) * w);
|
pointF.X = w;
|
|
pointFs.Add(new PointF(0, h));
|
pointFs.Add(new PointF(0, 0));
|
pointFs.Add(pointF);
|
pointFs.Add(new PointF(w, -h));
|
pointFs.Add(new PointF(-w, -h));
|
pointFs.Add(new PointF(-w, h));
|
}
|
else if (angle < 180)
|
{
|
double tanValue = Math.PI * (180 - angle) / 180;
|
pointF.X = Math.Abs((float)Math.Tan(tanValue) * h);
|
pointF.Y = -h;
|
|
pointFs.Add(new PointF(0, h));
|
pointFs.Add(new PointF(0, 0));
|
pointFs.Add(pointF);
|
pointFs.Add(new PointF(-w, -h));
|
pointFs.Add(new PointF(-w, h));
|
}
|
else if (angle < 225)
|
{
|
double tanValue = Math.PI * (angle - 180) / 180;
|
pointF.X = -Math.Abs((float)Math.Tan(tanValue) * h);
|
pointF.Y = -h;
|
|
pointFs.Add(new PointF(0, h));
|
pointFs.Add(new PointF(0, 0));
|
pointFs.Add(pointF);
|
pointFs.Add(new PointF(-w, -h));
|
pointFs.Add(new PointF(-w, h));
|
}
|
else if (angle < 270)
|
{
|
double tanValue = Math.PI * (270 - angle) / 180;
|
pointF.Y = -Math.Abs((float)Math.Tan(tanValue) * w);
|
pointF.X = -w;
|
|
pointFs.Add(new PointF(0, h));
|
pointFs.Add(new PointF(0, 0));
|
pointFs.Add(pointF);
|
pointFs.Add(new PointF(-w, h));
|
}
|
else if (angle < 315)
|
{
|
double tanValue = Math.PI * (angle - 270) / 180;
|
pointF.Y = Math.Abs((float)Math.Tan(tanValue) * w);
|
pointF.X = -w;
|
|
pointFs.Add(new PointF(0, h));
|
pointFs.Add(new PointF(0, 0));
|
pointFs.Add(pointF);
|
pointFs.Add(new PointF(-w, h));
|
}
|
else if (angle < 360)
|
{
|
double tanValue = Math.PI * (360 - angle) / 180;
|
pointF.X = -Math.Abs((float)Math.Tan(tanValue) * h);
|
pointF.Y = h;
|
|
pointFs.Add(new PointF(0, h));
|
pointFs.Add(new PointF(0, 0));
|
pointFs.Add(pointF);
|
}
|
|
g.FillPolygon(brush, PointConvert(pointFs.ToArray(), this.Width, this.Height));
|
}
|
|
/// <summary>
|
/// Resize图片
|
/// </summary>
|
/// <param name="bmp">原始Bitmap </param>
|
/// <param name="newW">新的宽度</param>
|
/// <param name="newH">新的高度</param>
|
/// <returns>处理以后的图片</returns>
|
public static Bitmap ResizeImage(Image bmp, int newW, int newH)
|
{
|
try
|
{
|
Bitmap b = new Bitmap(newW, newH);
|
Graphics g = Graphics.FromImage(b);
|
// 插值算法的质量
|
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
|
g.DrawImage(bmp, new Rectangle(0, 0, newW, newH), new Rectangle(0, 0, bmp.Width, bmp.Height), GraphicsUnit.Pixel);
|
g.Dispose();
|
return b;
|
}
|
catch
|
{
|
return null;
|
}
|
}
|
|
//数学点转为真实点
|
public PointF[] PointConvert(PointF[] pointFs, int width, int height)
|
{
|
List<PointF> pointFsout = new List<PointF>();
|
foreach (var item in pointFs)
|
{
|
pointFsout.Add(new PointF(item.X + width / 2, height / 2 - item.Y));
|
}
|
return pointFsout.ToArray();
|
}
|
public Bitmap WhiteAndBlack(System.Drawing.Bitmap image)
|
{
|
//原来图片的长度
|
int width = image.Width;
|
//原来图片的高度
|
int height = image.Height;
|
//改变色素
|
//横坐标
|
for (int x = 0; x < width; x++)
|
{
|
//纵坐标
|
for (int y = 0; y < height; y++)
|
{
|
//获得坐标(x,y)颜色
|
Color color = image.GetPixel(x, y);
|
//获得该颜色下的黑白色
|
int value = (color.R + color.G + color.B) / 3;
|
//设置颜色
|
image.SetPixel(x, y, Color.FromArgb(value, value, value));
|
}
|
}
|
return image;
|
}
|
|
//改变大小
|
public void SaveImage(string path, int width, int height)
|
{
|
Bitmap bitmap = new Bitmap(this.Width, this.Height);
|
this.DrawToBitmap(bitmap, new Rectangle(0, 0, this.Width, this.Height));
|
bitmap = ResizeImage(bitmap, width, height);
|
bitmap.Save(path);
|
}
|
//原始大小
|
public void SaveImage(string path)
|
{
|
Bitmap bitmap = new Bitmap(this.Width, this.Height);
|
this.DrawToBitmap(bitmap, new Rectangle(0, 0, this.Width, this.Height));
|
bitmap.Save(path);
|
}
|
}
|
}
|