public static Image CreateImage(int angle, double hueShift, double saturationAdjust, double lightnessAdjust, double contrast, double scaleX, double scaleY, string fileName) { TransformedBitmap transformBmp = new TransformedBitmap(); BitmapSource bitmapSource; if (hueShift == 0 && saturationAdjust == 0 && lightnessAdjust == 0 && contrast == 0) { BitmapImage bmpImage = new BitmapImage(); bmpImage.BeginInit(); bmpImage.UriSource = new Uri(fileName, UriKind.RelativeOrAbsolute); bmpImage.EndInit(); bitmapSource = bmpImage; } else { BitmapDecoder dec = BitmapDecoder.Create(new Uri(fileName), BitmapCreateOptions.None, BitmapCacheOption.Default); BitmapFrame firstFrame = dec.Frames[0]; const int bytesPerPixel = 4; byte[] pixels = new byte[firstFrame.PixelWidth * firstFrame.PixelHeight * bytesPerPixel]; firstFrame.CopyPixels(pixels, firstFrame.PixelWidth * bytesPerPixel, 0); for (int i = 0; i < pixels.Length / 4; ++i) { int index = i * 4; const int blueOffset = 0; const int greenOffset = 1; const int redOffset = 2; const int alphaOffset = 3; byte b = pixels[index + blueOffset]; byte g = pixels[index + greenOffset]; byte r = pixels[index + redOffset]; byte a = pixels[index + alphaOffset]; HueSatLight hueSatLight = new HueSatLight(Color.FromArgb(a, r, g, b)); if (hueShift != 0) { hueSatLight.HueShiftDegrees(hueShift); } if (saturationAdjust != 0) { hueSatLight.AdjustSaturation(saturationAdjust); } if (lightnessAdjust != 0) { hueSatLight.AdjustLightness(lightnessAdjust); } if (contrast != 0) { hueSatLight.AdjustContrast(contrast, (lightnessAdjust + 100) / 200); } Color shifted = hueSatLight.AsRGB; pixels[index + blueOffset] = shifted.B; pixels[index + greenOffset] = shifted.G; pixels[index + redOffset] = shifted.R; pixels[index + alphaOffset] = shifted.A; } // Write the modified pixels into a new bitmap and set that to the source var writeableBitmap = new WriteableBitmap(firstFrame.PixelWidth, firstFrame.PixelHeight, firstFrame.DpiX, firstFrame.DpiY, PixelFormats.Pbgra32, null); writeableBitmap.WritePixels(new Int32Rect(0, 0, firstFrame.PixelWidth, firstFrame.PixelHeight), pixels, firstFrame.PixelWidth * bytesPerPixel, 0); bitmapSource = writeableBitmap; } transformBmp.BeginInit(); transformBmp.Source = bitmapSource; RotateTransform rotation = new RotateTransform(angle); ScaleTransform scaling = new ScaleTransform(scaleX, scaleY); TransformGroup group = new TransformGroup(); group.Children.Add(scaling); group.Children.Add(rotation); transformBmp.Transform = group; transformBmp.EndInit(); Image result = new Image(); result.Source = transformBmp; return(result); }
/// <summary> /// Creates an Image with specified adjustments based on an image file on disk. /// </summary> /// <param name="angle">The angle to rotate the image. One of 0, 90, 180, or 270.</param> /// <param name="hueShift">The degrees to rotate the hue.</param> /// <param name="saturationAdjust">A value between -100 and 100. Negative values reduce saturation; positive values increase saturation.</param> /// <param name="lightnessAdjust">A value between -100 and 100. Negative values darken the color; positive values lighten the color.</param> /// <param name="contrast">A value between -100 and 100. Negative values reduce contrast (move more toward the threshold value); positive values increase the contrast (move away from the threshold value).</param> /// <param name="scaleX">The horizontal scale of the image.</param> /// <param name="scaleY">The vertical scale of the image.</param> /// <param name="fileName">The image file to load.</param> /// <returns></returns> public static Image CreateImage(int angle, double hueShift, double saturationAdjust, double lightnessAdjust, double contrast, double scaleX, double scaleY, string fileName) { TransformedBitmap transformBmp = new TransformedBitmap(); BitmapSource bitmapSource; if (hueShift == 0 && saturationAdjust == 0 && lightnessAdjust == 0 && contrast == 0) { BitmapImage bmpImage = new BitmapImage(); bmpImage.BeginInit(); bmpImage.UriSource = new Uri(fileName, UriKind.RelativeOrAbsolute); bmpImage.EndInit(); bitmapSource = bmpImage; } else { BitmapDecoder dec = BitmapDecoder.Create(new Uri(fileName), BitmapCreateOptions.None, BitmapCacheOption.Default); BitmapFrame firstFrame = dec.Frames[0]; const int bytesPerPixel = 4; int stride = firstFrame.PixelWidth * bytesPerPixel; byte[] pixels = new byte[stride * firstFrame.PixelHeight]; firstFrame.CopyPixels(pixels, stride, 0); for (int i = 0; i < pixels.Length / 4; ++i) { int index = i * 4; const int blueOffset = 0; const int greenOffset = 1; const int redOffset = 2; const int alphaOffset = 3; // Diagnostic pixel testing: //int y = i / firstFrame.PixelWidth; //int x = i - y * firstFrame.PixelWidth; //if (x == 229 && y == 254) //{ // System.Diagnostics.Debugger.Break(); //} byte b = pixels[index + blueOffset]; byte g = pixels[index + greenOffset]; byte r = pixels[index + redOffset]; byte a = pixels[index + alphaOffset]; if (a == 0) { continue; } HueSatLight hueSatLight = new HueSatLight(Color.FromArgb(a, r, g, b)); if (hueShift != 0) { hueSatLight.HueShiftDegrees(hueShift); } if (saturationAdjust != 0) { hueSatLight.AdjustSaturation(saturationAdjust); } if (lightnessAdjust != 0) { hueSatLight.AdjustLightness(lightnessAdjust); } if (contrast != 0) { hueSatLight.AdjustContrast(contrast, (lightnessAdjust + 100) / 200); } Color shifted = hueSatLight.AsRGB; pixels[index + blueOffset] = shifted.B; pixels[index + greenOffset] = shifted.G; pixels[index + redOffset] = shifted.R; pixels[index + alphaOffset] = shifted.A; } bitmapSource = CreateBitmap(firstFrame, stride, pixels); } transformBmp.BeginInit(); transformBmp.Source = bitmapSource; RotateTransform rotation = null; if (angle != 0) { rotation = new RotateTransform(angle); } ScaleTransform scaling = null; if (scaleX != 1 || scaleY != 1) { scaling = new ScaleTransform(scaleX, scaleY); } if (scaling != null || rotation != null) { TransformGroup group = new TransformGroup(); if (scaling != null) { group.Children.Add(scaling); } if (rotation != null) { group.Children.Add(rotation); } transformBmp.Transform = group; } transformBmp.EndInit(); Image result = new Image(); result.Source = transformBmp; return(result); }