c# 渐变算法

/// <summary>
/// 渐变算法
/// </summary>
/// <param name="sourceImg">位图源(物理路径)</param>
/// <param name="colorHead">起点色(HTML格式)</param>
/// <param name="colorTail">终点色(HTML格式)</param>
/// <param name="imgPath">保存图片路径(物理路径)</param>
public static void LinearGradient(string sourceImg, string destinationImg, string colorHead, string colorTail)
{
using (Image img = Image.FromFile(sourceImg))
{
int width = img.Width;
RGB colorBegin
= RGB.Split(colorHead);
RGB colorEnd
= RGB.Split(colorTail);
decimal diffR = 1m;
decimal diffG = 1m;
decimal diffB = 1m;
//三原色改变步长
diffR = Math.Round(Convert.ToDecimal(Convert.ToDecimal(colorEnd.Red - colorBegin.Red) / width), 2);
diffG
= Math.Round(Convert.ToDecimal(Convert.ToDecimal(colorEnd.Green - colorBegin.Green) / width), 2);
diffB
= Math.Round(Convert.ToDecimal(Convert.ToDecimal(colorEnd.Blue - colorBegin.Blue) / width), 2);
RGB rgb
= new RGB();
for (int i = 0; i < width; i++)
{
rgb.Red
= colorBegin.Red + Convert.ToInt32(diffR * i);
rgb.Green
= colorBegin.Green + Convert.ToInt32(diffG * i);
rgb.Blue
= colorBegin.Blue + Convert.ToInt32(diffB * i);
DrawItem(img,
254, rgb, i, 1, img.Height);
}
img.Save(destinationImg);
}
}
/// <summary>
/// 先平滑再渐变
/// </summary>
/// <param name="sourceImg">位图源(物理路径)</param>
/// <param name="destinationImg">保存图片路径(物理路径)</param>
/// <param name="flowWidth">平滑过渡宽度(以起点色为画笔颜色,在0-flowWidth的X坐标内不变色)</param>
/// <param name="transformWidth">渐变宽度(从flowWidth向后开始渐变,宽度为transformWidth)</param>
/// <param name="colorHead">起点色(HTML格式)</param>
/// <param name="colorTail">终点色(HTML格式)</param>
public static void LinearGradient(string sourceImg, string destinationImg, int flowWidth, int transformWidth, string colorHead, string colorTail)
{
using (Image img = Image.FromFile(sourceImg))
{
int width = img.Width;
int height = img.Height;
if (flowWidth > width)
{
flowWidth
= width - 1;
}
if (transformWidth > width - flowWidth)
{
transformWidth
= width - flowWidth;
}
RGB colorBegin
= RGB.Split(colorHead);
RGB colorEnd
= RGB.Split(colorTail);
decimal diffR = 1m;
decimal diffG = 1m;
decimal diffB = 1m;
diffR
= Math.Round(Convert.ToDecimal(Convert.ToDecimal(colorEnd.Red - colorBegin.Red) / transformWidth), 2);
diffG
= Math.Round(Convert.ToDecimal(Convert.ToDecimal(colorEnd.Green - colorBegin.Green) / transformWidth), 2);
diffB
= Math.Round(Convert.ToDecimal(Convert.ToDecimal(colorEnd.Blue - colorBegin.Blue) / transformWidth), 2);
int alphaLength = 255, alpha = 254;
//alpha值改变步长
decimal diffA = Math.Round(Convert.ToDecimal(alphaLength / transformWidth), 2);
//画平滑部分
RGB rgb = colorBegin;
DrawItem(img, alpha, rgb,
0, flowWidth, height);
for (int i = 0; i < transformWidth; i++)
{
//开始渐变
rgb.Red += Convert.ToInt32(diffR * i);
rgb.Green
+= Convert.ToInt32(diffG * i);
rgb.Blue
+= Convert.ToInt32(diffB * i);
alpha
-= Convert.ToInt32(diffA);
alpha
= Correct(alpha);
//alpha--;
DrawItem(img, alpha, rgb, i + flowWidth, 1, height);
}
img.Save(destinationImg);
}
}
/// <summary>
/// 单元填充操作(include alpha)
/// </summary>
/// <param name="img">位图源</param>
/// <param name="alpha">alpha透明度</param>
/// <param name="color">RGB颜色值</param>
/// <param name="left">X坐标</param>
/// <param name="width">画笔宽度</param>
/// <param name="height">画笔高度</param>
private static void DrawItem(Image img, int alpha, RGB color, int left, int width, int height)
{
using (Graphics g = Graphics.FromImage(img))
{
g.FillRectangle(
new SolidBrush(Color.FromArgb(alpha, color.Red, color.Green, color.Blue)), new Rectangle(left, 0, width, height));
}
}
/// <summary>
/// 颜色的10进制RGB值
/// </summary>
public struct RGB
{
/// <summary>
/// 从HTML颜色值分离出10进制RGB值(如#000000->0,0,0)
/// </summary>
/// <param name="color"></param>
/// <returns></returns>
public static RGB Split(string color)
{
RGB rgb
= new RGB();
rgb.Red
= Convert.ToInt32(color.Substring(1, 2), 16);
rgb.Green
= Convert.ToInt32(color.Substring(3, 2), 16);
rgb.Blue
= Convert.ToInt32(color.Substring(5, 2), 16);
return rgb;
}
/// <summary>
/// 将10进制RGB值合并为HTML颜色值(如255,255,255->#ffffff)
/// </summary>
/// <param name="rgb">颜色RGB</param>
/// <returns></returns>
public static string Join(RGB rgb)
{
string red = Convert.ToString(rgb.Red, 16).PadLeft(2, '0');
string green = Convert.ToString(rgb.Green, 16).PadLeft(2, '0');
string blue = Convert.ToString(rgb.Blue, 16).PadLeft(2, '0');
return String.Concat("#", red, green, blue);
}

private int red, green, blue;

public int Red
{
set { red = GDIUtility.Correct(value); }
get { return red; }
}
public int Green
{
set { green = GDIUtility.Correct(value); }
get { return green; }
}
public int Blue
{
set { blue = GDIUtility.Correct(value); }
get { return blue; }
}
}
原文地址:https://www.cnblogs.com/Googler/p/2050166.html