通过WEB修改服务器上图片的色调

效果如下:
example.jpg

需求:
很久很久以前,还在做asp的时候,在我网站的客户都会自动创建一个2级名的网站,设置了相应的模块。但有些客户喜欢某个模块的样式,不喜欢它的颜色,便要求我们改成他所喜欢的颜色。修改其实也很容易,无法就是把图片DOWN下来利用PS修改一下色调。但是,客户数量的庞大使得我们无暇一一满足。所以便想到客户可以自己通过web修改为自己喜欢的颜色。这样,普通的CSS很方便,但是模块中的图片颜色却不能修改。现在做.net了,又想这样做,折腾了好几天,终于实现了。

原理:
其实,修改简单修改图片的颜色,就是修改图片的色调(色相)。做过ps的人都知道,简单的拖动色掉的滚动条,图片就变为不同的颜色。而改变图片的色调,其实质也就是改变图片的R、G、B值,大家都知道无论任何色彩都是由RGB的不同比例组合而得到的。所以通过改变RGB然后重新组合就达到了改变图片颜色的效果,但是,除非专业的色彩搭配的人员,一般不可能通过单独一一调整R/G/B来达到自己想要的色彩效果,所以,就出现了色调这个名词,通过一定的计算公式,把色调的调整值换算为R/G/B的值,然后修改R/G/B来达到预期的效果。同样,修改图片的饱和度、明暗也是同样的原理(下两个专题可以陆续详细介绍)。

具体代码:
代码的关键,就是把色调值换算为R/G/B对应的值。

1、页面HTML
 1 ExpandedBlockStart.gif ContractedBlock.gif <% dot.gif @ Page language="c#" Codebehind="PS.aspx.cs" AutoEventWireup="false" Inherits="BxgTest.PS"  %>
 2 None.gif <! DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"  >
 3 None.gif < HTML >
 4 None.gif     < HEAD >
 5 None.gif         < title > PS </ title >
 6 None.gif         < meta  content ="Microsoft Visual Studio .NET 7.1"  name ="GENERATOR" >
 7 None.gif         < meta  content ="C#"  name ="CODE_LANGUAGE" >
 8 None.gif         < meta  content ="JavaScript"  name ="vs_defaultClientScript" >
 9 None.gif         < meta  content ="http://schemas.microsoft.com/intellisense/ie5"  name ="vs_targetSchema" >
10 ExpandedBlockStart.gifContractedBlock.gif         < SCRIPT  language ="JavaScript" > dot.gif
11InBlock.gif
12InBlock.gif    var changedNotApplied = false;
13InBlock.gif    var hueText = "";
14InBlock.gif    
15InBlock.gif    function hueClick() 
16ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
17InBlock.gif        hue = event.offsetX;
18InBlock.gif        //changedNotApplied = true;
19InBlock.gif        
20InBlock.gif        document.Form1.TextBox1.value=hue;
21InBlock.gif        return false;
22ExpandedSubBlockEnd.gif    }

23ExpandedBlockEnd.gif        
</ SCRIPT >
24 None.gif     </ HEAD >
25 None.gif     < body  MS_POSITIONING ="GridLayout" >
26 None.gif         < form  id ="Form1"  method ="post"  runat ="server" >
27 None.gif             < TABLE  id ="Table1"  style ="WIDTH: 912px; HEIGHT: 158px"  cellSpacing ="0"  cellPadding ="0"
28 None.gif                width ="912"  border ="1" >
29 None.gif                 < TR >
30 None.gif                     < TD  style ="WIDTH: 139px" >< FONT  face ="宋体" > 原始图象 </ FONT ></ TD >
31 None.gif                     < TD >< asp:image  id ="Image1"  runat ="server" ></ asp:image ></ TD >
32 None.gif                 </ TR >
33 None.gif                 < TR >
34 None.gif                     < TD  style ="WIDTH: 139px" >< FONT  face ="宋体" > 修改后的图象 </ FONT ></ TD >
35 None.gif                     < TD >< FONT  face ="宋体" >< asp:image  id ="Image2"  runat ="server" ></ asp:image ></ FONT ></ TD >
36 None.gif                 </ TR >
37 None.gif                 < TR >
38 None.gif                     < TD  style ="WIDTH: 139px" >< FONT  face ="宋体" > 设置值 </ FONT ></ TD >
39 None.gif                     < TD >< IMG  alt ="simp"  src ="imgs.png"  style ="CURSOR: hand"  onclick ="hueClick()"  name ="huebar" >
40 None.gif                         < asp:TextBox  id ="TextBox1"  runat ="server"  Width ="48px" ></ asp:TextBox >< FONT  face ="宋体" > &nbsp; 0~360 </ FONT ></ TD >
41 None.gif                 </ TR >
42 None.gif                 < TR >
43 None.gif                     < TD  style ="WIDTH: 139px" >
44 None.gif                         < asp:Button  id ="Button1"  runat ="server"  Text ="Button" ></ asp:Button ></ TD >
45 None.gif                     < TD ></ TD >
46 None.gif                 </ TR >
47 None.gif             </ TABLE >
48 None.gif         </ form >
49 None.gif     </ body >
50 None.gif </ HTML >
51 None.gif
其中有段JS,实质就是把选择的颜色转变为色掉,这个很简单。你预先弄张七彩图,长度为360(色调范围)然后取X位置就是对应的值了。

二、***.aspx.cs
*.aspx.cs
  1using System;
  2using System.Collections;
  3using System.ComponentModel;
  4using System.Data;
  5using System.Drawing;
  6using System.Web;
  7using System.Web.SessionState;
  8using System.Web.UI;
  9using System.Web.UI.WebControls;
 10using System.Web.UI.HtmlControls;
 11
 12namespace BxgTest
 13{
 14    /**//// <summary>
 15    /// PS 的摘要说明。
 16    /// </summary>
 17    public class PS : System.Web.UI.Page
 18    {
 19        protected System.Web.UI.WebControls.Image Image1;
 20        protected System.Web.UI.WebControls.Image Image2;
 21        protected System.Web.UI.WebControls.Button Button1;
 22        protected System.Web.UI.WebControls.TextBox TextBox1;
 23        protected System.Web.UI.HtmlControls.HtmlForm Form1;
 24   
 25        private void Page_Load(object sender, System.EventArgs e)
 26        {
 27            if(!Page.IsPostBack)
 28                bindPIC();
 29        }
 30
 31        private void bindPIC()
 32        {
 33            Image1.ImageUrl = Server.MapPath("112.jpg");
 34            Image2.ImageUrl = Server.MapPath("112P.jpg");
 35        }
 36
 37        Web 窗体设计器生成的代码#region Web 窗体设计器生成的代码
 38        override protected void OnInit(EventArgs e)
 39        {
 40            //
 41            // CODEGEN: 该调用是 ASP.NET Web 窗体设计器所必需的。
 42            //
 43            InitializeComponent();
 44            base.OnInit(e);
 45        }
 46       
 47        /**//// <summary>
 48        /// 设计器支持所需的方法 - 不要使用代码编辑器修改
 49        /// 此方法的内容。
 50        /// </summary>
 51        private void InitializeComponent()
 52        {   
 53            this.Button1.Click += new System.EventHandler(this.Button1_Click);
 54            this.Load += new System.EventHandler(this.Page_Load);
 55
 56        }
 57        #endregion
 58
 59        private void Button1_Click(object sender, System.EventArgs e)
 60        {
 61            System.Drawing.Image image = System.Drawing.Image.FromFile(System.Web.HttpContext.Current.Server.MapPath("112.jpg"));
 62            //取高和宽
 63            int phWidth = image.Width;
 64            int phHeight =image.Height;
 65            //建新图,指定格式为每像素 24 位;红色、绿色和蓝色分量各使用 8 位。
 66            System.Drawing.Bitmap bmPhoto = new System.Drawing.Bitmap(phWidth, phHeight, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
 67            //设置分辨率
 68            bmPhoto.SetResolution(image.HorizontalResolution,image.VerticalResolution);
 69            //准备Graphics
 70            System.Drawing.Graphics grPhoto = System.Drawing.Graphics.FromImage(bmPhoto);
 71
 72
 73            //指定消除锯齿的呈现。
 74            grPhoto.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
 75            grPhoto.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
 76            grPhoto.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
 77            grPhoto.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighSpeed;
 78
 79            //拷贝原图到做图区
 80            grPhoto.DrawImage(
 81                image,                              
 82                new System.Drawing.Rectangle(0, 0, phWidth, phHeight),
 83                0,                                     
 84                0,                                      
 85                phWidth,                               
 86                phHeight,                              
 87                System.Drawing.GraphicsUnit.Pixel);
 88
 89
 90            HueModifier h = new HueModifier();
 91            h.Hue = Convert.ToInt32(TextBox1.Text);
 92
 93            Bitmap imgnew = h.Apply(bmPhoto);
 94
 95            imgnew.Save(Server.MapPath("112P.jpg"), System.Drawing.Imaging.ImageFormat.Jpeg);
 96
 97            imgnew.Dispose();
 98            grPhoto.Dispose();
 99            bmPhoto.Dispose();
100            image.Dispose();
101        }
102    }
103}
这里需要注意的是,必须是每象素24位的图片,所以,我先新建了和原来图片一样大的图,然后复制过去。

3、处理类(部分代码来自网络)
CLASS
  1using System;
  2using System.Drawing;
  3using System.Drawing.Imaging;
  4
  5namespace BxgTest
  6{
  7    public class RGB
  8    {
  9        public const short R = 2;
 10        public const short G = 1;
 11        public const short B = 0;
 12
 13        public byte Red;
 14        public byte Green;
 15        public byte Blue;
 16
 17        public System.Drawing.Color Color
 18        {
 19            get { return System.Drawing.Color.FromArgb(Red, Green, Blue); }
 20            set
 21            {
 22                Red        = value.R;
 23                Green    = value.G;
 24                Blue    = value.B;
 25            }
 26        }
 27
 28        public RGB(){}
 29
 30        public RGB(byte red, byte green, byte blue)
 31        {
 32            this.Red    = red;
 33            this.Green    = green;
 34            this.Blue    = blue;
 35        }
 36    };
 37
 38
 39
 40
 41
 42
 43    public class HSL
 44    {
 45        public int        Hue;            // 0-359 : 色调
 46        public double    Saturation;        // 0-1 : 饱和度
 47        public double    Luminance;        // 0-1 : 明暗度
 48
 49        public HSL(){}
 50
 51        public HSL(int hue, double saturation, double luminance)
 52        {
 53            this.Hue        = hue;
 54            this.Saturation    = saturation;
 55            this.Luminance    = luminance;
 56        }
 57    };
 58
 59
 60
 61
 62
 63
 64
 65    public class ColorConverter
 66    {
 67        public static void RGB2HSL(RGB rgb, HSL hsl)
 68        {
 69            double    r = (rgb.Red / 255.0);
 70            double    g = (rgb.Green / 255.0);
 71            double    b = (rgb.Blue / 255.0);
 72
 73            double    min = Math.Min(Math.Min(r, g), b);
 74            double    max = Math.Max(Math.Max(r, g), b);
 75            double    delta = max - min;
 76
 77            hsl.Luminance = (max + min) / 2;
 78
 79            if (delta == 0)
 80            {
 81                hsl.Hue = 0;
 82                hsl.Saturation = 0.0;
 83            }
 84            else
 85            {
 86                hsl.Saturation = (hsl.Luminance < 0.5) ? (delta / (max + min)) : (delta / (2 - max - min));
 87
 88                double    del_r = (((max - r) / 6) + (delta / 2)) / delta;
 89                double    del_g = (((max - g) / 6) + (delta / 2)) / delta;
 90                double    del_b = (((max - b) / 6) + (delta / 2)) / delta;
 91                double    hue;
 92
 93                if (r == max)
 94                    hue = del_b - del_g;
 95                else if (g == max)
 96                    hue = (1.0 / 3) + del_r - del_b;
 97                else
 98                    hue = (2.0 / 3) + del_g - del_r;
 99
100                if (hue < 0)
101                    hue += 1;
102                if (hue > 1)
103                    hue -= 1;
104
105                hsl.Hue = (int) (hue * 360);
106            }
107        }
108
109        /**//// <summary>
110        /// 把HSH转成对应的RGB
111        /// </summary>
112        /// <param name="hsl"></param>
113        /// <param name="rgb"></param>
114        public static void HSL2RGB(HSL hsl, RGB rgb)
115        {
116            if (hsl.Saturation == 0)
117            {
118                rgb.Red = rgb.Green = rgb.Blue = (byte) (hsl.Luminance * 255);
119            }
120            else
121            {
122                double    v1, v2;
123                double    hue = (double) hsl.Hue / 360;
124
125                v2 = (hsl.Luminance < 0.5) ? (hsl.Luminance * (1 + hsl.Saturation)) : ((hsl.Luminance + hsl.Saturation) - (hsl.Luminance * hsl.Saturation));
126                v1 = 2 * hsl.Luminance - v2;
127
128                rgb.Red        = (byte)(255 * Hue_2_RGB(v1, v2, hue + (1.0 / 3)));
129                rgb.Green    = (byte)(255 * Hue_2_RGB(v1, v2, hue));
130                rgb.Blue    = (byte)(255 * Hue_2_RGB(v1, v2, hue - (1.0 / 3)));
131            }
132        }
133
134
135        Private members#region Private members
136        private static double Hue_2_RGB(double v1, double v2, double vH)
137        {
138            if (vH < 0)
139                vH += 1;
140            if (vH > 1)
141                vH -= 1;
142            if ((6 * vH) < 1)
143                return (v1 + (v2 - v1) * 6 * vH);
144            if ((2 * vH) < 1)
145                return v2;
146            if ((3 * vH) < 2)
147                return (v1 + (v2 - v1) * ((2.0 / 3) - vH) * 6);
148            return v1;
149        }
150        #endregion
151    }
152
153
154
155
156    public class HueModifier
157    {
158        private int hue = 0;
159
160        public int Hue
161        {
162            get { return hue; }
163            set { hue = System.Math.Max(0, System.Math.Min(359, value)); }
164        }
165
166        public HueModifier()
167        {
168        }
169
170        public HueModifier(int hue)
171        {
172            this.hue = hue;
173        }
174
175   
176        public Bitmap Apply(Bitmap srcImg)
177        {
178            if (srcImg.PixelFormat != PixelFormat.Format24bppRgb)
179             throw new Exception("Sorry!");   
180
181            int width = srcImg.Width;
182            int height = srcImg.Height;
183
184            BitmapData srcData = srcImg.LockBits(
185                new Rectangle(0, 0, width, height),
186                ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
187
188            Bitmap dstImg = new Bitmap(width, height, PixelFormat.Format24bppRgb);
189
190            BitmapData dstData = dstImg.LockBits(
191                new Rectangle(0, 0, width, height),
192                ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
193
194            RGB        rgb = new RGB();
195            HSL        hsl = new HSL();
196            int        offset = srcData.Stride - width * 3;
197
198            unsafe
199            {
200                byte * src = (byte *) srcData.Scan0.ToPointer();
201                byte * dst = (byte *) dstData.Scan0.ToPointer();
202
203                for (int y = 0; y < height; y++) //循环,一个象素一个象素的转
204                {
205                    for (int x = 0; x < width; x++, src += 3, dst += 3)
206                    {
207                        rgb.Red        = src[RGB.R];
208                        rgb.Green    = src[RGB.G];
209                        rgb.Blue    = src[RGB.B];
210
211                        ColorConverter.RGB2HSL(rgb, hsl);
212
213                        hsl.Hue = hsl.Hue + hue;
214
215                        ColorConverter.HSL2RGB(hsl, rgb);
216
217                        dst[RGB.R] = rgb.Red;
218                        dst[RGB.G] = rgb.Green;
219                        dst[RGB.B] = rgb.Blue;
220                    }
221                    src += offset;
222                    dst += offset;
223                }
224            }
225            dstImg.UnlockBits(dstData);
226            srcImg.UnlockBits(srcData);
227
228            return dstImg;
229        }
230    }
231}

转载于:https://www.cnblogs.com/ziyang/archive/2005/09/21/241325.html

猜你喜欢

转载自blog.csdn.net/weixin_34112900/article/details/93161283