⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 photopropchanger.cs

📁 这是一个小型的相片管理器
💻 CS
字号:


using System;
using System.Drawing;
using System.Drawing.Imaging;

namespace VirtualPhotoOrganizer.Photo
{
	/// <summary>
	/// allows us to change brightness, contrast, saturation, grayscale, sepia and gamma
	/// </summary>
	internal class PhotoPropChanger
	{
		#region constants

		// grayscale values defined by the NTSC
		private const Single GRAYRED = 0.3086F;
		private const Single GRAYGREEN = 0.6094F;
		private const Single GRAYBLUE = 0.082F;

		// sepia consts
		private const Single SEPIARED = 0.2F;
		private const Single SEPIAGREEN = 0.14F;
		private const Single SEPIABLUE = 0.08F;

		#endregion

		public PhotoPropChanger() { }

		#region public methods

		/// <summary>
		/// Adjusts the brightness of the image according to the specified value
		/// </summary>
		public void AdjustBrightness(Bitmap image, int percent) {
			DrawImage(image, GetBrightnessMatrix(percent));
		}

		/// <summary>
		/// Adjusts the contrast of the image according to the specified value
		/// </summary>
		public void AdjustContrast(Bitmap image, int percent) {
			DrawImage(image, GetContrastMatrix(percent));
		}

		/// <summary>
		/// Adjusts the saturation of the image according to the specified value
		/// </summary>
		public void AdjustSaturation(Bitmap image, int percent) {
			DrawImage(image, GetSaturationMatrix(percent));
		}

		/// <summary>
		/// Converts the specified image to grayscale
		/// </summary>
		public void ConvertToGrayscale(Bitmap image) {
			DrawImage(image, GetGrayscaleMatrix());
		}

		/// <summary>
		/// Converts the image to sepia
		/// </summary>
		public void ConvertToSepia(Bitmap image) {
			DrawImage(image, GetSepiaMatrix());
		}

		/// <summary>
		/// Adjusts the image using the specified matrix
		/// </summary>
		public void AdjustUsingCustomMatrix(Bitmap image, Single[][] matrix) {
			DrawImage(image, matrix);
		}

		/// <summary>
		/// Adjusts the image using the specified attributes
		/// </summary>
		public void AdjustUsingCustomAttributes(Bitmap image, ImageAttributes attrib) {
			DrawImage(image, attrib);
		}

		/// <summary>
		/// Adjusts the gamma value of the image according to the specified value
		/// </summary>
		public void AdjustGamma(Bitmap image, int percent) {
			// setup attributes with gamma value
			ImageAttributes attrib = new ImageAttributes();
			attrib.SetGamma(GetGamma(percent));

			// update the image
			DrawImage(image, attrib);

			attrib.Dispose();
		}

		#endregion

		#region helper methods

		/// <summary>
		/// Returns the matrix for the specified brightness value
		/// </summary>
		public Single[][] GetBrightnessMatrix(int percent) {
			/*set brightness by setting the offset row in the matrix
			 * values can range from -1.0 (black) to 1.0 (white)
			 * map the percent to use 60% of the full range (-0.6 to 0.6)*/
			Single v = 0.006F * percent;

			// setup the matrix
			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}
			};

			// return the matrix
			return matrix;
		}

		/// <summary>
		/// Returns the matrix for the specified contrast
		/// </summary>
		public Single[][] GetContrastMatrix(int percent) {
			// get contrast by settings the scale and offset at the same time

			// calculate the scale
			Single v;
			if (percent > 0) {
				// may range from 0.0 (no change) to 3.8 (high contrast)
				v = 0.0195F * percent;
				v *= v;
			} else	// negative value, -1.0 is gray and 0.0 is no change
				v = 0.009F * percent;

			Single scale = 1 + v;
			Single offset = v / 2;

			// setup the matrix;
			Single[][] matrix = 
			{
				new Single[] {scale, 0, 0, 0, 0},
				new Single[] {0, scale, 0, 0, 0},
				new Single[] {0, 0, scale, 0, 0},
				new Single[] {0, 0, 0, 1, 0},
				new Single[] {-offset, -offset, -offset, 0, 1}
			};

			return matrix;
		}

		/// <summary>
		/// Returns the matrix for the specified saturation
		/// </summary>
		public Single[][] GetSaturationMatrix(int percent) {
			/* set the saturation by scaling the red, green and blue values
			 * a value of 0 is grayscale, 1.0 is the orginial (no change) and 
			 * above 2.0 starts to look unnatural*/

			// calculate the scaling offset to apply to the red, green and blue colors
			Single v;
			if (percent > 0)
				v = 1.0F + (0.015F * percent);	// range from 1 (no change) to 2.5 (a lot of saturation)
			else
				v = 1.0F - (0.0075F * -percent);	// range from 0.25 (almost grayscale) to 1 (no change)

			Single red = (1.0F - v) * GRAYRED;
			Single green = (1.0F - v) * GRAYGREEN;
			Single blue = (1.0F - v) * GRAYBLUE;

			// setup matrix
			Single[][] matrix =
			{
				new Single[] {red + v, red, red, 0, 0},
				new Single[] {green, green + v, green, 0, 0},
				new Single[] {blue, blue, blue + v, 0, 0},
				new Single[] {0, 0, 0, 1, 0},
				new Single[] {0, 0, 0, 0, 1}
			};

			return matrix;
		}

		/// <summary>
		/// Returns the matrix for grayscale
		/// </summary>
		/// <returns></returns>
		public Single[][] GetGrayscaleMatrix() {
			// set the luminosity of the colors using grayscale weighting
			Single[][] matrix =
			{
				new Single[] {GRAYRED, GRAYRED, GRAYRED, 0, 0},
				new Single[] {GRAYGREEN, GRAYGREEN, GRAYGREEN, 0, 0},
				new Single[] {GRAYBLUE, GRAYBLUE, GRAYBLUE, 0, 0},
				new Single[] {0, 0, 0, 1, 0},
				new Single[] {0, 0, 0, 0, 1}
			};

			return matrix;
		}

		/// <summary>
		/// Returns the matrix for sepia
		/// </summary>
		public Single[][] GetSepiaMatrix() {
			/*sepia looks better if you first darken the image, the matrix values 
			 * (combination of brightness and sepia) could be hard coded, 
			 * but are left in code to make it easy to modify*/
			Single[][] brightness = GetBrightnessMatrix(-25);

			/*setup the matrix - sepia is grayscale with a slight offset in the red, 
			 * green and blue colors*/
			Single[][] sepia = 
			{
				new Single[] {GRAYRED, GRAYRED, GRAYRED, 0, 0},
				new Single[] {GRAYGREEN, GRAYGREEN, GRAYGREEN, 0, 0},
				new Single[] {GRAYBLUE, GRAYBLUE, GRAYBLUE, 0, 0},
				new Single[] {0, 0, 0, 1, 0},
				new Single[] {SEPIARED, SEPIAGREEN, SEPIABLUE, 0, 1}
			};

			return sepia;
		}

		/// <summary>
		/// Returns a combination of the tow specified matrices, while still maintaining the order information
		/// </summary>
		public Single[][] CombineMatrices(Single[][] m1, Single[][] m2) {
			// create a new empty matrix
			Single[][] matrix = 
			{
				new Single[] {0, 0, 0, 0, 0},
				new Single[] {0, 0, 0, 0, 0},
				new Single[] {0, 0, 0, 0, 0},
				new Single[] {0, 0, 0, 0, 0},
				new Single[] {0, 0, 0, 0, 0}
			};

			// combine the two matrices
			for (int i = 0; i < 5; i++) {
				for (int j = 0; j < 5; j++) {
					matrix[j][i] =
						m1[j][0] * m2[0][i] +
						m1[j][1] * m2[1][i] +
						m1[j][2] * m2[2][i] +
						m1[j][3] * m2[3][i] +
						m1[j][4] * m2[4][i];
				}
			}

			return matrix;
		}

		/// <summary>
		/// Returns the gamma value for the specified percent value
		/// </summary>
		public Single GetGamma(int percent) {
			// the gamma value can range from 0.1 (bright) to 5.0 (dark)
			// we'll only allow the range of 0.15 to 3.5, since the other values don't make much sense
			Single v;
			if (percent > 0)
				v = 1.0F - (0.0085F * percent);	// range from 1.0 (no change) to 0.15 (brighter)
			else
				v = 1.0F + (0.025F * -percent);	// range from 3.5 (darker) to 1.0 (no change)

			return v;
		}

		private void DrawImage(Bitmap image, ImageAttributes attrib) {
			// create the required graphics object from our image
			Graphics g = Graphics.FromImage(image);

			// draw the image using the specified attributes
			Rectangle destRect = new Rectangle(0, 0, image.Width, image.Height);
			g.DrawImage(image, destRect, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, attrib);

			// dispose the graphics object
			g.Dispose();
		}

		/// <summary>
		/// Draw an image using the specified matrix
		/// </summary>
		private void DrawImage(Bitmap image, Single[][] matrix) {
			// create a new attributes class with the specified matrix
			ColorMatrix cm = new ColorMatrix(matrix);
			ImageAttributes attrib = new ImageAttributes();
			attrib.SetColorMatrix(cm);

			// draw the image and dispose the attrib object
			DrawImage(image, attrib);
			attrib.Dispose();
		}

		#endregion
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -