728x90
728x170
▶ BitmapHelper.cs
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;
using System.Runtime.InteropServices;
namespace TestProject
{
/// <summary>
/// 비트맵 헬퍼
/// </summary>
public static class BitmapHelper
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Metohd
////////////////////////////////////////////////////////////////////////////////////////// Static
//////////////////////////////////////////////////////////////////////////////// Public
#region 비트맵 구하기 - GetBitmap(sourceBitmap, targetWidth)
/// <summary>
/// 비트맵 구하기
/// </summary>
/// <param name="sourceBitmap">소스 비트맵</param>
/// <param name="targetWidth">타겟 너비</param>
/// <returns>비트맵</returns>
public static Bitmap GetBitmap(Bitmap sourceBitmap, int targetWidth)
{
int maximumSide = sourceBitmap.Width > sourceBitmap.Height ? sourceBitmap.Width : sourceBitmap.Height;
float ratio = (float)maximumSide / (float)targetWidth;
Bitmap targetBitmap = (sourceBitmap.Width > sourceBitmap.Height ? new Bitmap(targetWidth, (int)(sourceBitmap.Height / ratio)) :
new Bitmap((int)(sourceBitmap.Width / ratio), targetWidth));
using(Graphics targetGraphics = Graphics.FromImage(targetBitmap))
{
targetGraphics.CompositingQuality = CompositingQuality.HighQuality;
targetGraphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
targetGraphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
targetGraphics.DrawImage
(
sourceBitmap,
new Rectangle(0, 0, targetBitmap.Width, targetBitmap.Height),
new Rectangle(0, 0, sourceBitmap.Width, sourceBitmap.Height),
GraphicsUnit.Pixel
);
targetGraphics.Flush();
}
return targetBitmap;
}
#endregion
#region 색상 균형 필터 적용하기 - ApplyColorBalanceFilter(sourceBitmap, blueLevel, greenLevel, redLevel)
/// <summary>
/// 색상 균형 필터 적용하기
/// </summary>
/// <param name="sourceBitmap">소스 비트맵</param>
/// <param name="blueLevel">청색 레벨</param>
/// <param name="greenLevel">녹색 레벨</param>
/// <param name="redLevel">적색 레벨</param>
/// <returns>비트맵</returns>
public static Bitmap ApplyColorBalanceFilter(Bitmap sourceBitmap, byte blueLevel, byte greenLevel, byte redLevel)
{
BitmapData sourceBitmapData = sourceBitmap.LockBits
(
new Rectangle(0, 0, sourceBitmap.Width, sourceBitmap.Height),
ImageLockMode.ReadOnly,
PixelFormat.Format32bppArgb
);
byte[] targetByteArray = new byte[sourceBitmapData.Stride * sourceBitmapData.Height];
Marshal.Copy(sourceBitmapData.Scan0, targetByteArray, 0, targetByteArray.Length);
sourceBitmap.UnlockBits(sourceBitmapData);
float blue = 0;
float green = 0;
float red = 0;
for(int i = 0; i + 4 < targetByteArray.Length; i += 4)
{
blue = 255.0f / (float)blueLevel * (float)targetByteArray[i ];
green = 255.0f / (float)greenLevel * (float)targetByteArray[i + 1];
red = 255.0f / (float)redLevel * (float)targetByteArray[i + 2];
if(blue > 255)
{
blue = 255;
}
else if(blue < 0)
{
blue = 0;
}
if(green > 255)
{
green = 255;
}
else if(green < 0)
{
green = 0;
}
if(red > 255)
{
red = 255;
}
else if(red < 0)
{
red = 0;
}
targetByteArray[i ] = (byte)blue;
targetByteArray[i + 1] = (byte)green;
targetByteArray[i + 2] = (byte)red;
}
Bitmap targetBitmap = new Bitmap(sourceBitmap.Width, sourceBitmap.Height);
BitmapData targetBitmapData = targetBitmap.LockBits
(
new Rectangle(0, 0, targetBitmap.Width, targetBitmap.Height),
ImageLockMode.WriteOnly,
PixelFormat.Format32bppArgb
);
Marshal.Copy(targetByteArray, 0, targetBitmapData.Scan0, targetByteArray.Length);
targetBitmap.UnlockBits(targetBitmapData);
return targetBitmap;
}
#endregion
}
}
728x90
▶ MainForm.cs
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Windows.Forms;
namespace TestProject
{
/// <summary>
/// 메인 폼
/// </summary>
public partial class MainForm : Form
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Field
////////////////////////////////////////////////////////////////////////////////////////// Private
#region Field
/// <summary>
/// 소스 비트맵
/// </summary>
private Bitmap sourceBitmap = null;
/// <summary>
/// 미리보기 비트맵
/// </summary>
private Bitmap previewBitmap = null;
/// <summary>
/// 타겟 비트맵
/// </summary>
private Bitmap targetBitmap = null;
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
////////////////////////////////////////////////////////////////////////////////////////// Private
#region 생성자 - MainForm()
/// <summary>
/// 생성자
/// </summary>
public MainForm()
{
InitializeComponent();
this.blueTrackBar.ValueChanged += colorTrackBar_ValueChanged;
this.greenTrackBar.ValueChanged += colorTrackBar_ValueChanged;
this.redTrackBar.ValueChanged += colorTrackBar_ValueChanged;
this.loadImageButton.Click += loadImageButton_Click;
this.saveImageButton.Click += saveImageButton_Click;
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Private
//////////////////////////////////////////////////////////////////////////////// Event
#region 색상 트랙바 값 변경시 처리하기 - colorTrackBar_ValueChanged(sender, e)
/// <summary>
/// 색상 트랙바 값 변경시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void colorTrackBar_ValueChanged(object sender, EventArgs e)
{
this.blueValueLabel.Text = this.blueTrackBar.Value.ToString();
this.greenValueLabel.Text = this.greenTrackBar.Value.ToString();
this.redValueLabel.Text = this.redTrackBar.Value.ToString();
ApplyFilter(true);
}
#endregion
#region 이미지 로드 버튼 클릭시 처리하기 - loadImageButton_Click(sender, e)
/// <summary>
/// 이미지 로드 버튼 클릭시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void loadImageButton_Click(object sender, EventArgs e)
{
OpenFileDialog openFileDialogfd = new OpenFileDialog();
openFileDialogfd.Title = "이미지 파일 로드";
openFileDialogfd.Filter = "PNG 이미지(*.png)|*.png|JPEG 이미지(*.jpg)|*.jpg|비트맵 이미지(*.bmp)|*.bmp";
if(openFileDialogfd.ShowDialog() == DialogResult.OK)
{
StreamReader reader = new StreamReader(openFileDialogfd.FileName);
this.sourceBitmap = (Bitmap)Bitmap.FromStream(reader.BaseStream);
reader.Close();
this.previewBitmap = BitmapHelper.GetBitmap(this.sourceBitmap, this.pictureBox.Width);
this.pictureBox.Image = this.previewBitmap;
ApplyFilter(true);
}
}
#endregion
#region 이미지 저장 버튼 클릭시 처리하기 - saveImageButton_Click(sender, e)
/// <summary>
/// 이미지 저장 버튼 클릭시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void saveImageButton_Click(object sender, EventArgs e)
{
ApplyFilter(false);
if(this.targetBitmap != null)
{
SaveFileDialog saveFileDialog = new SaveFileDialog();
saveFileDialog.Title = "이미지 파일 저장";
saveFileDialog.Filter = "PNG 이미지(*.png)|*.png|JPEG 이미지(*.jpg)|*.jpg|비트맵 이미지(*.bmp)|*.bmp";
if(saveFileDialog.ShowDialog() == DialogResult.OK)
{
string fileExtension = Path.GetExtension(saveFileDialog.FileName).ToUpper();
ImageFormat imageFormat = ImageFormat.Png;
if(fileExtension == "BMP")
{
imageFormat = ImageFormat.Bmp;
}
else if (fileExtension == "JPG")
{
imageFormat = ImageFormat.Jpeg;
}
StreamWriter writer = new StreamWriter(saveFileDialog.FileName, false);
this.targetBitmap.Save(writer.BaseStream, imageFormat);
writer.Flush();
writer.Close();
this.targetBitmap = null;
}
}
}
#endregion
//////////////////////////////////////////////////////////////////////////////// Function
#region 필터 적용하기 - ApplyFilter(preview)
/// <summary>
/// 필터 적용하기
/// </summary>
/// <param name="preview">미리보기 여부</param>
private void ApplyFilter(bool preview)
{
if(this.previewBitmap == null)
{
return;
}
byte blue = (byte)this.blueTrackBar.Value;
byte green = (byte)this.greenTrackBar.Value;
byte red = (byte)this.redTrackBar.Value;
if(preview == true)
{
this.pictureBox.Image = BitmapHelper.ApplyColorBalanceFilter(this.previewBitmap, blue, green, red);
}
else
{
this.targetBitmap = BitmapHelper.ApplyColorBalanceFilter(this.sourceBitmap, blue, green, red);
}
}
#endregion
}
}
728x90
그리드형(광고전용)
'C# > WinForm' 카테고리의 다른 글
[C#/WINFORM] PictureBox 클래스 : 배경 이미지 위에 낙서하기 (0) | 2021.03.10 |
---|---|
[C#/WINFORM] Bitmap 클래스 : 오버레이 비트맵 혼합하기 (0) | 2021.03.09 |
[C#/WINFORM] Bitmap 클래스 : 색상 대체하기 (0) | 2021.03.08 |
[C#/WINFORM] Bitmap 클래스 : ARGB 색상 채널 교환하기 (0) | 2021.03.08 |
[C#/WINFORM] Bitmap 클래스 : 부분 색상 반전하기 (0) | 2021.02.24 |
[C#/WINFORM] Screen 클래스 : 모니터 핸들 구하기 (0) | 2021.02.05 |
[C#/WINFORM] 잠금 화면 설정하기 (기능 개선) (0) | 2021.02.02 |
[C#/WINFORM] 잠금 화면 설정하기 (0) | 2021.02.01 |
[C#/WINFORM] Bitmap 클래스 : 바이-톤 필터(Bi-tonal Filter) 사용하기 (0) | 2021.01.30 |
[C#/WINFORM] Bitmap 클래스 : 색조 필터(Color Tint Filter) 사용하기 (0) | 2021.01.28 |