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 열화 필터 적용하기 - ApplySolarFilter(sourceBitmap, blue, green, red)
/// <summary>
/// 열화 필터 적용하기
/// </summary>
/// <param name="sourceBitmap">소스 비트맵</param>
/// <param name="blue">청색</param>
/// <param name="green">녹색</param>
/// <param name="red">적색</param>
/// <returns>비트맵</returns>
public static Bitmap ApplySolarFilter(Bitmap sourceBitmap, byte blue, byte green, byte red)
{
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);
byte maximumValue = 255;
for(int i = 0; i + 4 < targetByteArray.Length; i += 4)
{
if(targetByteArray[i] < blue)
{
targetByteArray[i] = (byte)(maximumValue - targetByteArray[i]);
}
if(targetByteArray[i + 1] < green)
{
targetByteArray[i + 1] = (byte)(maximumValue - targetByteArray[i + 1]);
}
if(targetByteArray[i + 2] < red)
{
targetByteArray[i + 2] = (byte)(maximumValue - targetByteArray[i + 2]);
}
}
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.ApplySolarFilter(this.previewBitmap, blue, green, red);
}
else
{
this.targetBitmap = BitmapHelper.ApplySolarFilter(this.sourceBitmap, blue, green, red);
}
}
#endregion
}
}
728x90
그리드형(광고전용)
'C# > WinForm' 카테고리의 다른 글
[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 |
[C#/WINFORM] Bitmap 클래스 : 색상 음영 필터(Color Shading Filter) 사용하기 (0) | 2021.01.27 |
[C#/WINFORM] Form 클래스 : 높은 DPI에서 흐릿하게 출력 방지하기 (0) | 2021.01.23 |
[C#/WINFORM] Bitmap 클래스 : 대비 필터(Contrast Filter) 사용하기 (0) | 2021.01.14 |
[C#/WINFORM] Bitmap 클래스 : 이미지 비트 단위 블렌딩하기 (0) | 2021.01.13 |
[C#/WINFORM] Bitmap 클래스 : 이미지 연산하기 (0) | 2021.01.12 |
[C#/WINFORM] Bitmap 클래스 : 키르시 3X3 가장자리 탐지 필터(Kirsch 3X3 Edge Detection Filter) 사용하기 (0) | 2021.01.11 |