该控件扩展了ToolStrip的功能,增加了水印功能,增加了图标在鼠标进入时自动增亮的功能。
只要实现思想:
扩展了ToolStripProfessionalRenderer渲染器,重写了OnRenderToolStripBorder、OnRenderSeparator、OnRenderItemImage、OnRenderToolStripBackground等几个方法,从而实现背景,水印的实现。
代码如下
/// <summary>
/// ToolStrip 渲染器。更改背景为过度显示和鼠标进入时图片自动增亮的功能。
/// </summary>
public class JWToolStripBarRenderer : ToolStripProfessionalRenderer
{
//Dictionary<string, Image> dict = new Dictionary<string, Image>();
private Brush backgroundBrush = null;
List<EtyImageState> m_ImageList = new List<EtyImageState>();
public JWToolStripBarRenderer()
{
this.RoundedEdges = false;
}
/// <summary>
/// 当更换背景颜色时,执行该方法才能生效,为的是提高效率。
/// </summary>
public void ResetBackgroundBrush()
{
this.backgroundBrush = null;
}
private Color m_ToolStripGradientBegin = SystemColors.InactiveBorder;
/// <summary>
/// 获取在 ToolStrip 背景中使用的渐变的开始颜色。
/// </summary>
public Color ToolStripGradientBegin
{
get { return m_ToolStripGradientBegin; }
set { m_ToolStripGradientBegin = value; }
}
private Color m_ToolStripGradientEnd = SystemColors.ControlLightLight;
/// <summary>
/// 获取在 ToolStrip 背景中使用的渐变的结束颜色。
/// </summary>
public Color ToolStripGradientEnd
{
get { return m_ToolStripGradientEnd; }
set { m_ToolStripGradientEnd = value; }
}
private BackgroundGradientStyle m_BackgroundGradientStyle = BackgroundGradientStyle.Horizontal;
/// <summary>
/// 设置背景渐变方式。
/// </summary>
public BackgroundGradientStyle BackgroundGradientStyle
{
get { return m_BackgroundGradientStyle; }
set
{
m_BackgroundGradientStyle = value;
}
}
private DrawBorderMode m_DrawBorderMode = DrawBorderMode.TopAndBottom;
/// <summary>
/// 画ToolStrip边框的形式。
/// </summary>
public DrawBorderMode DrawBorderMode
{
get { return m_DrawBorderMode; }
set { m_DrawBorderMode = value; }
}
private Image m_WatermarkImage;
/// <summary>
/// 水印的图片。
/// </summary>
///
public Image WatermarkImage
{
get { return m_WatermarkImage; }
set { m_WatermarkImage = value; }
}
private int m_brightValue = 30;
/// <summary>
/// 鼠标进入时的图片增亮值。默认为 30
/// </summary>
public int BrightValue
{
get { return m_brightValue; }
set { m_brightValue = value; }
}
//protected override void OnRenderArrow(ToolStripArrowRenderEventArgs e)
//{
// e.ArrowColor = Color.Red;
// e.Direction = ArrowDirection.Right;
// base.OnRenderArrow(e);
//}
// This method draws a border around the GridStrip control.
protected override void OnRenderToolStripBorder(
ToolStripRenderEventArgs e)
{
base.OnRenderToolStripBorder(e);
if (e.ToolStrip is ToolStripDropDown) //过滤,根据需要可能还有更多的过滤
return;
using (Pen pen = new Pen(SystemColors.ButtonShadow))
{
if (m_DrawBorderMode == DrawBorderMode.TopAndBottom || m_DrawBorderMode == DrawBorderMode.TopOnly)
e.Graphics.DrawLine(pen, e.AffectedBounds.X, e.AffectedBounds.Y, e.AffectedBounds.Width, e.AffectedBounds.Y);
if (m_DrawBorderMode == DrawBorderMode.TopAndBottom || m_DrawBorderMode == DrawBorderMode.BottomOnly)
e.Graphics.DrawLine(pen, e.AffectedBounds.X, e.AffectedBounds.Height - 1, e.AffectedBounds.Width, e.AffectedBounds.Height - 1);
}
}
protected override void OnRenderSeparator(ToolStripSeparatorRenderEventArgs e)
{
if (e.ToolStrip.LayoutStyle == ToolStripLayoutStyle.Table || e.ToolStrip.LayoutStyle == ToolStripLayoutStyle.Flow)
{
base.OnRenderSeparator(new ToolStripSeparatorRenderEventArgs(e.Graphics, e.Item as ToolStripSeparator, false));
//e.Graphics.FillRectangle(new SolidBrush(Color.Red), new Rectangle(0, 0, 100, 2));
}
else
base.OnRenderSeparator(e);
}
//修改只保留原图片。
protected override void OnRenderItemImage(ToolStripItemImageRenderEventArgs e)
{
Bitmap img = e.Image as Bitmap;
if (img != null)
{
bool isEqualsInitImage = false;
EtyImageState ety = EtyImageState.GetEtyImageState(m_ImageList, img.GetHashCode(), out isEqualsInitImage);
if (ety == null)
{
ety = new EtyImageState();
ety.InitImage = img;
ety.LightImage = ImageTool.Brightness(img, m_brightValue);
m_ImageList.Add(ety);
}
if (e.Item.Selected)
e.Item.Image = ety.LightImage;
else
e.Item.Image = ety.InitImage;
}
base.OnRenderItemImage(e);
}
int borderPadding = 2;
protected override void OnRenderToolStripBackground(ToolStripRenderEventArgs e)
{
base.OnRenderToolStripBackground(e);
if (e.ToolStrip is ToolStripDropDown) //过滤,根据需要可能还有更多的过滤
return;
//SystemColors.ControlLightLight,
//SystemColors.InactiveBorder,
Color gradientEnd = this.ToolStripGradientEnd;
float angle = 0;
if (m_BackgroundGradientStyle == BackgroundGradientStyle.Vertical)
angle = 90;
if (m_BackgroundGradientStyle == BackgroundGradientStyle.None)
gradientEnd = this.ToolStripGradientBegin;
if (this.backgroundBrush == null)
{
this.backgroundBrush = new LinearGradientBrush(
e.ToolStrip.ClientRectangle,
this.ToolStripGradientBegin,
gradientEnd,
angle,
true);
}
// Paint the GridStrip control's background.
e.Graphics.FillRectangle(
this.backgroundBrush,
e.AffectedBounds);
if (e.ToolStrip.GripStyle == ToolStripGripStyle.Visible)
{
ControlPaint.DrawBorder3D(e.Graphics, new Rectangle(3, 3, 2, e.ToolStrip.Height - 6), Border3DStyle.Etched, Border3DSide.Left | Border3DSide.Right);
ControlPaint.DrawBorder3D(e.Graphics, new Rectangle(7, 3, 2, e.ToolStrip.Height - 6), Border3DStyle.Etched, Border3DSide.Left | Border3DSide.Right);
}
//显示水印。
if (m_WatermarkImage != null)
{
Point position = Point.Empty;
int top = borderPadding;
int left = 0;
int width = 0;
int height = 0;
if (m_WatermarkImage.Height > e.ToolStrip.Height - borderPadding * 2)
{
//重新定义图片的显示宽高
double rate = (double)m_WatermarkImage.Width / (double)m_WatermarkImage.Height;
height = e.ToolStrip.Height - borderPadding * 2;
width = Convert.ToInt32(rate * height);
}
else
{
width = m_WatermarkImage.Width;
height = m_WatermarkImage.Height;
top = (e.ToolStrip.Height - height) / 2;
}
left = e.ToolStrip.Width - width - borderPadding * 2;
position = new Point(left, top);
Rectangle rect = new Rectangle(left, top, width, height);
e.Graphics.DrawImage(m_WatermarkImage, rect, new Rectangle(0, 0, m_WatermarkImage.Width, m_WatermarkImage.Height), GraphicsUnit.Pixel);
}
}
// This method handles the RenderGrip event.
protected override void OnRenderGrip(ToolStripGripRenderEventArgs e)
{
//DrawTitleBar(
// e.Graphics,
// new Rectangle(0, 0, e.ToolStrip.Width, e.ToolStrip.Height));
//ControlPaint.DrawBorder3D(e.Graphics, new Rectangle(0, 3, 2, e.ToolStrip.Height - 6), Border3DStyle.RaisedInner);
//ControlPaint.DrawBorder3D(e.Graphics, new Rectangle(3, 3, 2, e.ToolStrip.Height - 6), Border3DStyle.RaisedInner);
}
}
/// <summary>
/// 为保存图片的状态而设
/// </summary>
internal class EtyImageState
{
public int InitImageKey
{
get
{
if (m_InitImage == null)
return -1;
else
return m_InitImage.GetHashCode();
}
}
private Image m_InitImage;
public Image InitImage
{
get { return m_InitImage; }
set { m_InitImage = value; }
}
public int LightImageKey
{
get
{
if (m_LightImage == null)
return -1;
else
return m_LightImage.GetHashCode();
}
}
private Image m_LightImage;
public Image LightImage
{
get { return m_LightImage; }
set { m_LightImage = value; }
}
/// <summary>
/// 从集合
/// </summary>
/// <param name="list"></param>
/// <param name="key"></param>
/// <returns></returns>
public static EtyImageState GetEtyImageState(List<EtyImageState> list, int key, out bool isEqualsInitImage)
{
isEqualsInitImage = false;
EtyImageState retEty = null;
foreach (EtyImageState ety in list)
{
if (ety.InitImageKey == key)
{
isEqualsInitImage = true;
retEty = ety;
break;
}
else if (ety.LightImageKey == key)
{
retEty = ety;
break;
}
}
return retEty;
}
}
水印的处理(数字图片处理)
public static class ImageTool
{
/// <summary>
/// 根据字符串生成图片。
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
public static Bitmap DeserializeFromBase64(string data)
{
// Decode the string and create a memory stream
// on the decoded string data.
MemoryStream stream =
new MemoryStream(Convert.FromBase64String(data));
// Create a new bitmap from the stream.
Bitmap b = new Bitmap(stream);
return b;
}
//图片 转为 base64编码的文本
public static string ImgToBase64String(Image bmp)
{
MemoryStream ms = new MemoryStream();
bmp.Save(ms, bmp.RawFormat);
byte[] arr = new byte[ms.Length];
ms.Position = 0;
ms.Read(arr, 0, (int)ms.Length);
ms.Close();
String strbase64 = Convert.ToBase64String(arr);
return strbase64;
}
/// <summary>
/// 图片增亮。
/// </summary>
/// <param name="img"></param>
/// <returns></returns>
public static Image Brightness(Image img, int brightValue)
{
int percent = brightValue;
Single v = 0.006F * percent;
Single[][] matrix = {
new Single[] { 1, 0, 0, 0, 0 },
new Single[] { 0, 1, 0, 0, 0 },
new Single[] { 0, 0, 1, 0, 0 },
new Single[] { 0, 0, 0, 1, 0 },
new Single[] { v, v, v, 0, 1 }
};
System.Drawing.Imaging.ColorMatrix cm = new System.Drawing.Imaging.ColorMatrix(matrix);
System.Drawing.Imaging.ImageAttributes attr = new System.Drawing.Imaging.ImageAttributes();
attr.SetColorMatrix(cm);
//Image tmp
//Image tmp = (Image)img.Clone();
Bitmap tmp = new Bitmap(img);
Graphics g = Graphics.FromImage(tmp);
try
{
Rectangle destRect = new Rectangle(0, 0, img.Width, img.Height);
g.DrawImage(tmp, destRect, 0, 0, tmp.Width, tmp.Height, GraphicsUnit.Pixel, attr);
}
finally
{
g.Dispose();
}
return tmp;
}
//处理不了透明的背景
/// <summary>
/// 制作水印图片
/// </summary>
/// <param name="iTheImage">要制作水印的图片</param>
/// <param name="width">制作水印的宽</param>
/// <param name="height">制作水印的高</param>
/// <returns></returns>
public static Bitmap WatermarkImage(Bitmap iTheImage, int width, int height)
{
//Bitmap watermark = new Bitmap(width, height,
// PixelFormat.Format24bppRgb);
Bitmap watermark = new Bitmap(iTheImage);
Graphics g = Graphics.FromImage(watermark);
g.Clear(Color.White);
//g.Clear(iTheImage.GetPixel(0,0));
g.SmoothingMode = SmoothingMode.HighQuality;
g.InterpolationMode = InterpolationMode.High;
ImageAttributes imageAttributes = new ImageAttributes();
ColorMap colorMap = new ColorMap();
colorMap.OldColor = Color.FromArgb(255, 0, 255, 0);
colorMap.NewColor = Color.FromArgb(0, 0, 0, 0);
ColorMap[] remapTable = { colorMap };
imageAttributes.SetRemapTable(remapTable, ColorAdjustType.Bitmap);
float[][] colorMatrixElements = {
new float[] {1.0f, 0.0f, 0.0f, 0.0f, 0.0f},
new float[] {0.0f, 1.0f, 0.0f, 0.0f, 0.0f},
new float[] {0.0f, 0.0f, 1.0f, 0.0f, 0.0f},
new float[] {0.0f, 0.0f, 0.0f, 0.3f, 0.0f},
new float[] {0.0f, 0.0f, 0.0f, 0.0f, 1.0f}
};
ColorMatrix colorMatrix = new ColorMatrix(colorMatrixElements);
imageAttributes.SetColorMatrix(colorMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);
#region 保留学习
////int WatermarkWidth = 0;
////int WatermarkHeight = 0;
////double bl = 1d;
//////计算水印图片的比率
//////取背景的1/4宽度来比较
////if ((width > watermark.Width * 4) && (height > watermark.Height * 4))
////{
//// bl = 1;
////}
////else if ((width > watermark.Width * 4) && (height < watermark.Height * 4))
////{
//// bl = Convert.ToDouble(height / 4) / Convert.ToDouble(watermark.Height);
////}
////else if ((width < watermark.Width * 4) && (height > watermark.Height * 4))
////{
//// bl = Convert.ToDouble(width / 4) / Convert.ToDouble(watermark.Width);
////}
////else
////{
//// if ((width * watermark.Height) > (height * watermark.Width))
//// {
//// bl = Convert.ToDouble(height / 4) / Convert.ToDouble(watermark.Height);
//// }
//// else
//// {
//// bl = Convert.ToDouble(width / 4) / Convert.ToDouble(watermark.Width);
//// }
////}
////WatermarkWidth = Convert.ToInt32(watermark.Width * bl);
////WatermarkHeight = Convert.ToInt32(watermark.Height * bl);
////switch (_watermarkPosition)
////{
//// case "WM_TOP_LEFT":
//// xpos = 10;
//// ypos = 10;
//// break;
//// case "WM_TOP_RIGHT":
//// xpos = _width - WatermarkWidth - 10;
//// ypos = 10;
//// break;
//// case "WM_BOTTOM_RIGHT":
//// xpos = _width - WatermarkWidth - 10;
//// ypos = _height - WatermarkHeight - 10;
//// break;
//// case "WM_BOTTOM_LEFT":
//// xpos = 10;
//// ypos = _height - WatermarkHeight - 10;
//// break;
////}
#endregion
try
{
Rectangle destRect = new Rectangle(0, 0, watermark.Width, watermark.Height);
g.DrawImage(iTheImage, destRect, 0, 0, watermark.Width, watermark.Height,
GraphicsUnit.Pixel,
imageAttributes);
}
finally
{
imageAttributes.Dispose();
g.Dispose();
}
return watermark;
}
/// <summary>
/// 制作透明的图片。对透明背景保留原来的样子。
/// </summary>
/// <param name="bmpobj"></param>
/// <param name="transValue">透明度 (0 - 255)</param>
public static void WatermarkImage(Bitmap bmpobj, int transValue)
{
for (int i = 0; i < bmpobj.Height; i++)
{
for (int j = 0; j < bmpobj.Width; j++)
{
Color dot = bmpobj.GetPixel(j, i);
if (dot.A > 0)
{
bmpobj.SetPixel(j, i, Color.White);
bmpobj.SetPixel(j,i,Color.FromArgb(transValue,dot.R,dot.G,dot.B));
}
}
}
}
/// <summary>
/// 灰度转换,逐点方式
/// </summary>
public static void GrayByPixels(Bitmap bmpobj)
{
for (int i = 0; i < bmpobj.Height; i++)
{
for (int j = 0; j < bmpobj.Width; j++)
{
Color dot = bmpobj.GetPixel(j, i);
if (dot.A > 0)
{
int tmpValue = GetGrayNumColor(dot);
bmpobj.SetPixel(j, i, Color.FromArgb(tmpValue, tmpValue, tmpValue));
}
}
}
}
/// <summary>
/// 根据RGB,计算灰度值
/// </summary>
/// <param name="posClr">Color值</param>
/// <returns>灰度值,整型</returns>
private static int GetGrayNumColor(System.Drawing.Color posClr)
{
return (posClr.R * 19595 + posClr.G * 38469 + posClr.B * 7472) >> 16;
}
////public static bool Invert(Bitmap b)
////{
//// BitmapData bmData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height),
//// ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
//// int stride = bmData.Stride;
//// System.IntPtr Scan0 = bmData.Scan0;
//// unsafe
//// {
//// byte* p = (byte*)(void*)Scan0;
//// int nOffset = stride - b.Width * 3;
//// int nWidth = b.Width * 3;
//// for (int y = 0; y < b.Height; ++y)
//// {
//// for (int x = 0; x < nWidth; ++x)
//// {
//// p[0] = (byte)(255 - p[0]);
//// ++p;
//// }
//// p += nOffset;
//// }
//// }
//// b.UnlockBits(bmData);
//// return true;
////}
////public static bool Gray(Bitmap b)
////{
//// BitmapData bmData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height),
//// ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
//// int stride = bmData.Stride;
//// System.IntPtr Scan0 = bmData.Scan0;
//// unsafe
//// {
//// byte* p = (byte*)(void*)Scan0;
//// int nOffset = stride - b.Width * 3;
//// byte red, green, blue;
//// for (int y = 0; y < b.Height; ++y)
//// {
//// for (int x = 0; x < b.Width; ++x)
//// {
//// blue = p[0];
//// green = p[1];
//// red = p[2];
//// p[0] = p[1] = p[2] = (byte)(.299 * red + .587 * green + .114 * blue);
//// p += 3;
//// }
//// p += nOffset;
//// }
//// }
//// b.UnlockBits(bmData);
//// return true;
////}
////public static bool Brightness(Bitmap b, int nBrightness)
////{
//// if (nBrightness < -255 || nBrightness > 255)
//// return false;
//// BitmapData bmData = b.LockBits(new Rectangle(0, 0, b.Width,
//// b.Height), ImageLockMode.ReadWrite,
//// PixelFormat.Format24bppRgb);
//// int stride = bmData.Stride;
//// System.IntPtr Scan0 = bmData.Scan0;
//// int nVal = 0;
//// unsafe
//// {
//// byte* p = (byte*)(void*)Scan0;
//// int nOffset = stride - b.Width * 3;
//// int nWidth = b.Width * 3;
//// for (int y = 0; y < b.Height; ++y)
//// {
//// for (int x = 0; x < nWidth; ++x)
//// {
//// nVal = (int)(p[0] + nBrightness);
//// if (nVal < 0) nVal = 0;
//// if (nVal > 255) nVal = 255;
//// p[0] = (byte)nVal;
//// ++p;
//// }
//// p += nOffset;
//// }
//// }
//// b.UnlockBits(bmData);
//// return true;
////}
}
/// <summary>
/// 扩展的ToolStrip,更改背景为过度显示和鼠标进入时图片自动增亮的功能。
/// </summary>
public partial class ToolStripEx : ToolStrip
{
private JWToolStripBarRenderer render = new JWToolStripBarRenderer();
public ToolStripEx()
{
this.Renderer = render;
}
/// <summary>
/// 获取在 ToolStrip 背景中使用的渐变的开始颜色。
/// </summary>
[Description("获取在 ToolStrip 背景中使用的渐变的开始颜色。"), DefaultValue(typeof(Color), "InactiveBorder"), Category("特效设置")]
public Color ToolStripGradientBegin
{
get { return render.ToolStripGradientBegin; }
set
{
render.ToolStripGradientBegin = value;
render.ResetBackgroundBrush();
this.Invalidate();
}
}
/// <summary>
/// 获取在 ToolStrip 背景中使用的渐变的结束颜色。
/// </summary>
[Description("获取在 ToolStrip 背景中使用的渐变的结束颜色。"), DefaultValue(typeof(Color), "ControlLightLight"), Category("特效设置")]
public Color ToolStripGradientEnd
{
get { return render.ToolStripGradientEnd; }
set
{
render.ToolStripGradientEnd = value;
render.ResetBackgroundBrush();
this.Invalidate();
}
}
/// <summary>
/// 设置背景渐变方式。
/// </summary>
[Description("设置背景渐变方式。"), DefaultValue(typeof(BackgroundGradientStyle), "Horizontal"), Category("特效设置")]
public BackgroundGradientStyle BackgroundGradientStyle
{
get { return render.BackgroundGradientStyle; }
set
{
render.BackgroundGradientStyle = value;
render.ResetBackgroundBrush();
this.Invalidate();
}
}
private Bitmap m_WatermarkImage;
/// <summary>
/// 水印的图片。
/// </summary>
///
[Description("水印的图片。"), DefaultValue(null), Category("特效设置")]
public Bitmap WatermarkImage
{
get { return m_WatermarkImage; }
set
{
m_WatermarkImage = value;
//制作水印
if (value != null)
{
Bitmap img = new Bitmap(value);
if (m_watermarkGrayEffect)
ImageTool.GrayByPixels(img);
if (m_WatermarkTransparency != 255)
ImageTool.WatermarkImage(img, m_WatermarkTransparency);
render.WatermarkImage = img;
}
else
render.WatermarkImage = null;
this.Invalidate();
}
}
/// <summary>
/// 画ToolStrip边框的形式。
/// </summary>
[Description("画ToolStrip边框的形式。"), DefaultValue(typeof(DrawBorderMode), "TopAndBottom"), Category("特效设置")]
public DrawBorderMode DrawBorderMode
{
get { return render.DrawBorderMode; }
set
{
render.DrawBorderMode = value;
this.Invalidate();
}
}
private bool m_watermarkGrayEffect = false;
/// <summary>
/// 水印的灰度效果,默认为 false;
/// </summary>
///
[Description("水印的灰度效果,默认为 false;"), DefaultValue(false), Category("特效设置")]
public bool WatermarkGrayEffect
{
get { return m_watermarkGrayEffect; }
set
{
m_watermarkGrayEffect = value;
WatermarkImage = m_WatermarkImage;
}
}
private int m_WatermarkTransparency = 255;
/// <summary>
/// 水印显示的透明度。
/// </summary>
///
[Description("水印显示的透明度。默认为 255;"), DefaultValue(255), Category("特效设置")]
public int WatermarkTransparency
{
get { return m_WatermarkTransparency; }
set
{
if (value > 255 || value < 0)
throw new Exception("请输入 0 - 255 之间的一个数值。");
m_WatermarkTransparency = value;
WatermarkImage = m_WatermarkImage;
}
}
}
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/Yjianyong/archive/2009/12/27/5087300.aspx