请教如何改变一个图片的色相(PS里面的色相)和饱和度(PS里面的饱和度)?改变后保存下来,谢谢比如:System.Drawing.Image Image;
Image = System.Drawing.Image.FromFile(TempPath);如何设置它的饱和度和色相,然后保存下来?希望能给一段可用的代码
下面这段代码可以实现变灰度,但色相和饱和度不知道要怎么换算来做,特请教:    protected void Page_Load(object sender, EventArgs e)
    {
        try
        {
            String stPath = Request.QueryString["path"].Trim();
            int width = int.Parse(Request.QueryString["width"]);
            int height = int.Parse(Request.QueryString["height"]);
            string ImagePath = stPath;
            string TempPath = Server.MapPath(ImagePath);
            float SourceWidth = 0f, SourceHeght = 0f, NewWidth = 0f, NewHeight = 0f;
            System.Drawing.Image Image;
            Image = System.Drawing.Image.FromFile(TempPath);
            SourceWidth = Image.Width;
            SourceHeght = Image.Height;
            float Width = float.Parse(width.ToString());
            float Height = float.Parse(height.ToString());
            if (SourceWidth <= Width && SourceHeght <= Height)
            {
                NewWidth = SourceWidth;
                NewHeight = SourceHeght;
            }
            else if (Width > 0f && Height == 0f)
            {
                NewWidth = Width;
                NewHeight = NewWidth * SourceHeght / SourceWidth;
            }
            else if (Width == 0f && Height > 0f)
            {
                NewHeight = Height;
                NewWidth = NewHeight * SourceWidth / SourceHeght;
            }
            else if (SourceWidth >= Width || SourceHeght >= Height)
            {
                if ((SourceWidth / SourceHeght) > (Width / Height))
                {
                    NewWidth = Width;
                    NewHeight = SourceHeght * NewWidth / SourceWidth;
                }
                else
                {
                    NewHeight = Height;
                    NewWidth = SourceWidth * NewHeight / SourceHeght;
                }
            }
            if (NewWidth == 0f) NewWidth = 1f;
            if (NewHeight == 0f) NewHeight = 1f;
            Bitmap drawBasic = new Bitmap(Convert.ToInt32(NewWidth), Convert.ToInt32(NewHeight), PixelFormat.Format64bppArgb);
            Graphics g = Graphics.FromImage(drawBasic);
            g.DrawImage(Image, 0, 0, NewWidth, NewHeight);
            //g.DrawImage(frameImage, 0, 0, frameImage.Width, frameImage.Height);
            //g.FillRectangle(new SolidBrush(Color.FromArgb(80, Color.Yellow)), new Rectangle(0, 0, Convert.ToInt32(NewWidth), Convert.ToInt32(NewHeight)));
            g.Save();
            int Height1 = Convert.ToInt32(NewHeight);
            int Width1 = Convert.ToInt32(NewWidth);
            Bitmap bitmap = new Bitmap(Width1, Height1);
            Bitmap MyBitmap = drawBasic;            Color pixel;
            for (int x = 0; x < Width1; x++)
                for (int y = 0; y < Height1; y++)
                {
                    pixel = MyBitmap.GetPixel(x, y);
                    int r, sg, b, Result = 0;
                    r = pixel.R;
                    sg = pixel.G;
                    b = pixel.B;
                    //实例程序以加权平均值法产生黑白图像   
                    int iType = 2;
                    //int iType = 0;
                    switch (iType)
                    {
                        case 0://平均值法   
                            Result = ((r + sg + b) / 3);
                            break;
                        case 1://最大值法   
                            Result = r > sg ? r : sg;
                            Result = Result > b ? Result : b;
                            break;
                        case 2://加权平均值法   
                            Result = ((int)(0.7 * r) + (int)(0.2 * sg) + (int)(0.1 * b));
                            //Result = ((int)(0.6 * r) + (int)(0.3 * sg) + (int)(0.2 * b));                            break;
                    }
                    bitmap.SetPixel(x, y, Color.FromArgb(Result, Result, Result));
                    //bitmap.SetPixel(x, y, Color.FromArgb(255 - r, 255 - sg, 255 - b));
                }
           
                       MemoryStream ms = new MemoryStream();
            bitmap.Save(ms, ImageFormat.Jpeg);
            //drawBasic.Save(ms, ImageFormat.Jpeg);
            Response.Clear();
            Response.ContentType = "image/jpeg";
            Response.BinaryWrite(ms.ToArray());
            ms.Dispose();
            g.Dispose();
            drawBasic.Dispose();
            Image.Dispose();        }
        catch(Exception ex)
        {
            throw new Exception(ex.Message);
            Response.Write("deny request");
            Response.End();
        }
    }
    public bool ThumbnailCallback()
    {
        return false;
    }

解决方案 »

  1.   

    网上rgb到hsi(Hue Saturation Intensity)的转换代码很容易找到。
    把颜色空间换到HSI上,调整色泽H,饱和度S就一目了然了。
      

  2.   

    问题解决了,在网上抄了一个,贴上来分析Imports System.Drawing
    Imports System.Drawing.ImagingPublic Class HSLFilter
        Inherits BasicFilter    Private _hue As Double = 0.0
        Private _saturation As Double = 0.0
        Private _lightness As Double = 0.0    ''' <summary>
        ''' Get or set hue correction value.
        ''' </summary>
        ''' <value>Any double, will be scaled to range [0..360).</value>
        ''' <returns>Double in range [0..360).</returns>
        Public Property Hue() As Double
            Get
                Return _hue
            End Get
            Set(ByVal value As Double)
                _hue = value
                Do While _hue < 0.0
                    _hue += 360
                Loop
                Do While _hue >= 360.0
                    _hue -= 360
                Loop
            End Set
        End Property    ''' <summary>
        ''' Get or set saturation correction value.
        ''' </summary>
        ''' <value>Double in range [-100..+100]%.</value>
        ''' <returns>Double in range [-100..+100]%.</returns>
        ''' <res></res>
        Public Property Saturation() As Double
            Get
                Return _saturation
            End Get
            Set(ByVal value As Double)
                If ((value >= -100.0) And (value <= 100.0)) Then
                    _saturation = value
                End If
            End Set
        End Property    ''' <summary>
        ''' Get or set lightness correction value.
        ''' </summary>
        ''' <value>Double in range [-100..+100]%.</value>
        ''' <returns>Double in range [-100..+100]%.</returns>
        ''' <res></res>
        Public Property Lightness() As Double
            Get
                Return _lightness
            End Get
            Set(ByVal value As Double)
                If ((value >= -100.0) And (value <= 100.0)) Then
                    _lightness = value
                End If
            End Set
        End Property    ''' <summary>
        ''' Execute filter and return filtered image.
        ''' </summary>
        ''' <param name="img"></param>
        ''' <returns></returns>
        ''' <res></res>
        Public Overrides Function ExecuteFilter(ByVal img As System.Drawing.Image) As System.Drawing.Image
            Select Case img.PixelFormat
                Case PixelFormat.Format16bppGrayScale
                    Return img
                Case PixelFormat.Format24bppRgb, _
                         PixelFormat.Format32bppArgb, PixelFormat.Format32bppRgb
                    Return ExecuteRgb8(img)
                Case PixelFormat.Format48bppRgb
                    Return img
                Case Else
                    Return img
            End Select
        End Function    ''' <summary>
        ''' Execute filter on (A)RGB image with 8 bits per color.
        ''' </summary>
        ''' <param name="img"></param>
        ''' <returns></returns>
        ''' <res></res>
        Private Function ExecuteRgb8(ByVal img As System.Drawing.Image) As System.Drawing.Image
            Const c1o60 As Double = 1 / 60
            Const c1o255 As Double = 1 / 255
            Dim result As Bitmap = New Bitmap(img)
            result.SetResolution(img.HorizontalResolution, img.VerticalResolution)
            Dim bmpData As BitmapData = result.LockBits( _
                           New Rectangle(0, 0, result.Width, result.Height), _
                           ImageLockMode.ReadWrite, img.PixelFormat)
            Dim pixelBytes As Integer = _
                     System.Drawing.Image.GetPixelFormatSize(img.PixelFormat) \ 8
            'Get the address of the first line.
            Dim ptr As IntPtr = bmpData.Scan0
            Dim size As Integer = bmpData.Stride * result.Height
            Dim pixels(size - 1) As Byte
            Dim index As Integer
            Dim R, G, B As Double
            Dim H, S, L, H1 As Double
            Dim min, max, dif, sum As Double
            Dim f1, f2 As Double
            Dim v1, v2, v3 As Double
            Dim sat As Double = 127 * _saturation / 100
            Dim lum As Double = 127 * _lightness / 100
            'Copy the RGB values into the array.
            System.Runtime.InteropServices.Marshal.Copy(ptr, pixels, 0, size)
            'Main loop.
            For row As Integer = 0 To result.Height - 1
                For col As Integer = 0 To result.Width - 1
                    index = (row * bmpData.Stride) + (col * pixelBytes)
                    R = pixels(index + 2)
                    G = pixels(index + 1)
                    B = pixels(index + 0)
                    'Conversion to HSL space.
                    min = R
                    If (G < min) Then min = G
                    If (B < min) Then min = B
                    max = R : f1 = 0.0 : f2 = G - B
                    If (G > max) Then
                        max = G : f1 = 120.0 : f2 = B - R
                    End If
                    If (B > max) Then
                        max = B : f1 = 240.0 : f2 = R - G
                    End If
                    dif = max - min
                    sum = max + min
                    L = 0.5 * sum
                    If (dif = 0) Then
                        H = 0.0 : S = 0.0
                    Else
                        If (L < 127.5) Then
                            S = 255.0 * dif / sum
                        Else
                            S = 255.0 * dif / (510.0 - sum)
                        End If
                        H = (f1 + 60.0 * f2 / dif)
                        If H < 0.0 Then H += 360.0
                        If H >= 360.0 Then H -= 360.0
                    End If
                    'Apply transformation.
                    H = H + _hue
                    If H >= 360.0 Then H = H - 360.0
                    S = S + sat
                    If S < 0.0 Then S = 0.0
                    If S > 255.0 Then S = 255.0
                    L = L + lum
                    If L < 0.0 Then L = 0.0
                    If L > 255.0 Then L = 255.0
                    'Conversion back to RGB space.
                    If (S = 0) Then
                        R = L : G = L : B = L
                    Else
                        If (L < 127.5) Then
                            v2 = c1o255 * L * (255 + S)
                        Else
                            v2 = L + S - c1o255 * S * L
                        End If
                        v1 = 2 * L - v2
                        v3 = v2 - v1
                        H1 = H + 120.0
                        If (H1 >= 360.0) Then H1 -= 360.0
                        If (H1 < 60.0) Then
                            R = v1 + v3 * H1 * c1o60
                        ElseIf (H1 < 180.0) Then
                            R = v2
                        ElseIf (H1 < 240.0) Then
                            R = v1 + v3 * (4 - H1 * c1o60)
                        Else
                            R = v1
                        End If
                        H1 = H
                        If (H1 < 60.0) Then
                            G = v1 + v3 * H1 * c1o60
                        ElseIf (H1 < 180.0) Then
                            G = v2
                        ElseIf (H1 < 240.0) Then
                            G = v1 + v3 * (4 - H1 * c1o60)
                        Else
                            G = v1
                        End If
                        H1 = H - 120.0
                        If (H1 < 0.0) Then H1 += 360.0
                        If (H1 < 60.0) Then
                            B = v1 + v3 * H1 * c1o60
                        ElseIf (H1 < 180.0) Then
                            B = v2
                        ElseIf (H1 < 240.0) Then
                            B = v1 + v3 * (4 - H1 * c1o60)
                        Else
                            B = v1
                        End If
                    End If
                    'Save new values.
                    pixels(index + 2) = CByte(R)
                    pixels(index + 1) = CByte(G)
                    pixels(index + 0) = CByte(B)
                Next
            Next
            'Copy the RGB values back to the bitmap
            System.Runtime.InteropServices.Marshal.Copy(pixels, 0, ptr, size)
            'Unlock the bits.
            result.UnlockBits(bmpData)
            Return result
        End FunctionEnd Class
      

  3.   


    Imports System.Drawing
    Imports System.Drawing.Drawing2DPublic Class ResizeFilter
        Inherits BasicFilter    ''' <summary>
        ''' Width of new image.
        ''' </summary>
        Private _width As Integer = 0
        ''' <summary>
        ''' Height of new image.
        ''' </summary>
        Private _height As Integer = 0    ''' <summary>
        ''' Get or set output image width.
        ''' </summary>
        Public Property Width() As Integer
            Get
                Return _width
            End Get
            Set(ByVal value As Integer)
                _width = value
            End Set
        End Property    ''' <summary>
        ''' Get or set output image height.
        ''' </summary>
        Public Property Height() As Integer
            Get
                Return _height
            End Get
            Set(ByVal value As Integer)
                _height = value
            End Set
        End Property    ''' <summary>
        ''' Execute resize of given image.
        ''' </summary>
        ''' <param name="img">Image to be resized.</param>
        ''' <returns>Resized image.</returns>
        Public Overrides Function ExecuteFilter(ByVal img As System.Drawing.Image) As System.Drawing.Image
            If ((img.Width <= 0) Or (img.Height <= 0) Or _
                     (_width <= 0) Or (_height <= 0)) Then
                Return img
            End If
            Dim result As Bitmap = New Bitmap(_width, _height)
            Dim g As Graphics = Graphics.FromImage(result)
            g.InterpolationMode = Interpolation
            g.DrawImage(img, 0, 0, _width, _height)
            Return result
        End FunctionEnd Class
      

  4.   

    昨晚不能一次性贴完
    Imports System.Drawing
    Imports System.Drawing.Drawing2DPublic Interface IFilter    Function ExecuteFilter( _
                 ByVal inputImage As System.Drawing.Image) As System.Drawing.ImageEnd InterfacePublic MustInherit Class BasicFilter
        Implements IFilter    ''' <summary>
        ''' Background color. Default is a transparent background.
        ''' </summary>
        Private _bgColor As Color = Color.FromArgb(0, 0, 0, 0)
        ''' <summary>
        ''' Interpolation mode. Default is highest quality.
        ''' </summary>
        Private _interpolation As InterpolationMode = _
                 InterpolationMode.HighQualityBicubic    ''' <summary>
        ''' Get or set background color.
        ''' </summary>
        Public Property BackgroundColor() As Color
            Get
                Return _bgColor
            End Get
            Set(ByVal value As Color)
                _bgColor = value
            End Set
        End Property    ''' <summary>
        ''' Get or set resize interpolation mode.
        ''' </summary>
        Public Property Interpolation() As InterpolationMode
            Get
                Return _interpolation
            End Get
            Set(ByVal value As InterpolationMode)
                _interpolation = value
            End Set
        End Property    ''' <summary>
        ''' Execute filter function and return new filtered image.
        ''' </summary>
        ''' <param name="img">Image to be filtered.</param>
        ''' <returns>New filtered image.</returns>
        Public MustOverride Function ExecuteFilter( _
                 ByVal img As System.Drawing.Image) _
                 As System.Drawing.Image Implements IFilter.ExecuteFilterEnd Class
      

  5.   

    调用页面:Imports System.Drawing
    Imports System.Drawing.Imaging
    Partial Class _makepic
        Inherits System.Web.UI.Page
        Private _imgOriginal As Image
        Private _imgFiltered As Image
        Private _imgResized As Image
        Private _filterHSL As HSLFilter = New HSLFilter
        Public Shared Function GetEncoderInfo(ByVal format As ImageFormat) As ImageCodecInfo
            Dim j As Integer
            Dim encoders() As ImageCodecInfo
            encoders = ImageCodecInfo.GetImageEncoders()
            j = 0
            While j < encoders.Length
                If encoders(j).FormatID = format.Guid Then
                    Return encoders(j)
                End If
                j += 1
            End While
            Return Nothing
        End Function    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
            Dim picpath As String
            picpath = Server.MapPath(Session("picpath"))
            If picpath = Server.MapPath(".") Then Response.Redirect("ip.aspx")
            _imgOriginal = Image.FromFile(picpath)
            Dim scale As Double = 1
            If (_imgOriginal.Width > 280) Or (_imgOriginal.Height > 210) Then
                scale = System.Math.Min(280 / _imgOriginal.Width, 210 / _imgOriginal.Height)
            End If
            Dim imgFilter As ResizeFilter = New ResizeFilter
            imgFilter.Width = CInt(scale * _imgOriginal.Width)
            imgFilter.Height = CInt(scale * _imgOriginal.Height)
            _imgResized = imgFilter.ExecuteFilter(_imgOriginal)
            ' pnlOriginal.BackgroundImage = _imgResized
            'pnlFiltered.BackgroundImage = _imgResized
            Dim sliderH, sliderS, sliderL As Double
            sliderH = Request.QueryString("sliderH").ToString
            sliderS = Request.QueryString("sliderS").ToString
            sliderL = Request.QueryString("sliderL").ToString        _filterHSL.Hue = CDbl(sliderH)
            _filterHSL.ExecuteFilter(_imgResized)
            _filterHSL.Saturation = CDbl(sliderS)
            _filterHSL.ExecuteFilter(_imgResized)
            _filterHSL.Lightness = CDbl(sliderL)
            _filterHSL.ExecuteFilter(_imgResized)
            Dim ext As String = Mid(picpath, picpath.LastIndexOf(".") + 2)
            Dim myEncoderParameters As EncoderParameters = Nothing
            Dim myImageCodecInfo As ImageCodecInfo
            Select Case ext.ToLower()
                Case "jpg"
                    myImageCodecInfo = GetEncoderInfo(ImageFormat.Jpeg)
                    myEncoderParameters = New EncoderParameters(1)
                    myEncoderParameters.Param(0) = New EncoderParameter(Encoder.Quality, CType(90L, Int32))
                Case "gif"
                    myImageCodecInfo = GetEncoderInfo(ImageFormat.Gif)
                Case "png"
                    myImageCodecInfo = GetEncoderInfo(ImageFormat.Png)
                Case "bmp"
                    myImageCodecInfo = GetEncoderInfo(ImageFormat.Bmp)
                Case Else
                    Response.Write("Image format " & ext & " is not suported!")
                    Exit Sub
            End Select
            If Request("scale") = "small" Then
                _imgFiltered = _filterHSL.ExecuteFilter(_imgResized)
            Else
                imgFilter.Width = _imgOriginal.Width
                imgFilter.Height = _imgOriginal.Height
                _imgOriginal = imgFilter.ExecuteFilter(_imgOriginal)
                _imgFiltered = _filterHSL.ExecuteFilter(_imgOriginal)
            End If
            _imgFiltered.Save(Response.OutputStream, GetEncoderInfo(ImageFormat.Jpeg), myEncoderParameters)
        End Sub
    End Class