📄 vpobitmap.cs
字号:
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;
namespace VirtualPhotoOrganizer.Photo
{
/// <summary>
/// the program's custom bitmap class that allows easy editing
/// image property changes, such as brightness, contrast, and saturation are first grouped together to be then applied all at once
/// </summary>
internal class VPOBitmap
{
private Bitmap _Image = null; // the bitmap image contained in the VPOBitmap
private Bitmap _OrigImage = null;// the bitmap that contains the original image
private Resizer Resizer; // the resizer required for the zooming process
private PhotoPropChanger PropChanger; // required for changing brightness, contrast, etc.
private Image Img;
private int OrigImageWidth = 0; // the original width of the image
private int OrigImageHeight = 0; // the original height of the image
private int Brightness; // the current brightness value
private int Contrast; // the current contrast value
private int Saturation; // the current saturation value
private int Gamma; // the current gamma value
private bool Grayscale; // is the current image grayscale?
private bool Sepia; // is the current image sepia?
private bool _Cropping; // are we currently cropping?
private CropAssistant CropA; // the cropAssistant
// the cropping values
private int CropTop;
private int CropBottom;
private int CropLeft;
private int CropRight;
public VPOBitmap(string path) {
Img = Bitmap.FromFile(path);
_Image = new Bitmap(Img);
_OrigImage = (Bitmap) _Image.Clone();
OrigImageWidth = _OrigImage.Width;
OrigImageHeight = _OrigImage.Height;
Resizer = new Resizer();
PropChanger = new PhotoPropChanger();
CropA = new CropAssistant();
Img.Dispose();
ResetValues();
}
/// <summary>
/// first disposes _Image and then makes it hold a clone of the OrigImage and resets the property values
/// </summary>
private void ReloadOrigImage() {
// restore the original image
_Image.Dispose();
_Image = (Bitmap) OrigImage.Clone();
}
/// <summary>
/// reset the property values
/// </summary>
public void ResetValues() {
Brightness = 0;
Contrast = 0;
Saturation = 0;
Gamma = 0;
CropTop = 0;
CropBottom = 0;
CropLeft = 0;
CropRight = 0;
Grayscale = false;
Sepia = false;
Cropping = false;
}
#region ApplyChanges
/// <summary>
/// applies all property changes to _Image after reloading the original
/// </summary>
private void ApplyChanges() {
// load the original image
ReloadOrigImage();
// create a new empty null matrix
Single[][] matrix = null;
// find out if the image should be converted to grayscale and do the conversion if necessarry
if (Grayscale == true)
PropChanger.ConvertToGrayscale(_Image);
// find out if the image should be converted to sepia and do the conversion if necessarry
if (Sepia == true)
PropChanger.ConvertToSepia(_Image);
// find out if the contrast needs to be adjusted and add the contrast matrix to matrix if it does
if (Contrast != 0) {
if (matrix != null) // find out if the matrix already contains some values - if it does add the new matrix to the existing one
matrix = PropChanger.CombineMatrices(matrix, PropChanger.GetContrastMatrix(Contrast));
else // else the matrix will be set to the contrast matrix
matrix = PropChanger.GetContrastMatrix(Contrast);
}
// find out if the brightness needs to be adjusted and load the brightness matrix into the empty matrix
if (Brightness != 0) {
if (matrix != null) // find out if the matrix already contains some values - if it does add the new matrix to the existing one
matrix = PropChanger.CombineMatrices(matrix, PropChanger.GetBrightnessMatrix(Brightness));
else // the matrix will be set to the brightness matrix
matrix = PropChanger.GetBrightnessMatrix(Brightness);
}
// find out if the saturation needs to be adjusted and add the contrast matrix to matrix if it does
if (Saturation != 0) {
if (matrix != null) // find out if the matrix already contains some values - if it does add the new matrix to the existing one
matrix = PropChanger.CombineMatrices(matrix, PropChanger.GetSaturationMatrix(Saturation));
else // the matrix will be set to the saturation matrix
matrix = PropChanger.GetSaturationMatrix(Saturation);
}
// find out if gamma needs to be adjusted and adjust together with the other values if necessarry - otherwise only adjust using the other values
if (Gamma != 0) {
ImageAttributes attrib = new ImageAttributes();
if (matrix != null) {
ColorMatrix cm = new ColorMatrix(matrix);
attrib.SetColorMatrix(cm);
}
attrib.SetGamma(PropChanger.GetGamma(Gamma));
PropChanger.AdjustUsingCustomAttributes(_Image, attrib);
} else {
if (matrix != null)
PropChanger.AdjustUsingCustomMatrix(_Image, matrix);
}
// find out if a cropping previw needs to be applied and apply one if necessarry
if (Cropping == true)
CropA.GetCropPreview(_Image, CropTop, CropBottom, CropLeft, CropRight);
}
#endregion
#region public methods
/// <summary>
/// Resets the Image to OrigImage
/// </summary>
public void Reset() {
ReloadOrigImage();
ResetValues();
}
/// <summary>
/// Resizes the specified image to the specified size with the specified InterpolationMode
/// </summary>
public void Resize(int width, int height, InterpolationMode interpolationMode) {
// create a temporary buffer and copy the buffer to _Image after the operation completes
Bitmap buffer = Resizer.Resize(_Image, width, height, interpolationMode);
_Image.Dispose();
_Image = (Bitmap) buffer.Clone();
buffer.Dispose();
}
/// <summary>
/// Crops the Image
/// </summary>
public void Crop(Rectangle cropArea) {
// create a temporary buffer and copy the buffer to _Image after the operation completes
Bitmap buffer = Resizer.Crop(_OrigImage, cropArea);
_Image.Dispose();
_Image = (Bitmap) buffer.Clone();
buffer.Dispose();
// set the cropping preview var to false
Cropping = false;
}
/// <summary>
/// adds a crop preview to the image
/// </summary>
public void PreviewCrop(int top, int bottom, int left, int right) {
Cropping = true;
CropTop = top;
CropBottom = bottom;
CropLeft = left;
CropRight = right;
ApplyChanges();
}
/// <summary>
/// Adjusts the brightness of the image according to the specified value
/// </summary>
public void AdjustBrightness(int percent) {
Brightness = percent;
ApplyChanges();
}
/// <summary>
/// Adjusts the contrast of the image according to the specified value
/// </summary>
public void AdjustContrast(int percent) {
Contrast = percent;
ApplyChanges();
}
/// <summary>
/// Adjusts the saturation of the image according to the specified value
/// </summary>
public void AdjustSaturation(int percent) {
Saturation = percent;
ApplyChanges();
}
/// <summary>
/// Converts the image to grayscale
/// </summary>
public void ConvertToGrayscale() {
if (Grayscale == false)
Grayscale = true;
else
Grayscale = false;
ApplyChanges();
}
/// <summary>
/// Converts the image to sepia
/// </summary>
public void ConvertToSepia() {
if (Sepia == false)
Sepia = true;
else
Sepia = false;
ApplyChanges();
}
/// <summary>
/// Adjusts the image using the specified matrix
/// </summary>
public void AdjustUsingCustomMatrix(Single[][] matrix) {
ReloadOrigImage();
PropChanger.AdjustUsingCustomMatrix(_Image, matrix);
}
/// <summary>
/// Adjusts the gamma value of the image according to the specified value
/// </summary>
public void AdjustGamma(int percent) {
Gamma = percent;
ApplyChanges();
}
public void Dispose() {
_Image.Dispose();
_OrigImage.Dispose();
}
#endregion
#region accessors
public Bitmap Image {
get { return _Image; }
}
public Bitmap OrigImage {
get { return _OrigImage; }
}
public int Width {
get { return Image.Width; }
}
public int Height {
get { return Image.Height; }
}
public bool Cropping {
get { return _Cropping; }
set { _Cropping = value; }
}
#endregion
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -