728x90
728x170
▶ BitmapHelper.cs
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
using System.Drawing.Drawing2D;
namespace TestProject
{
/// <summary>
/// 비트맵 헬퍼
/// </summary>
public static class BitmapHelper
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// 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 바이-톤 필터 적용하기 - ApplyBitonalFilter(sourceBitmap, darkColor, lightColor, threshold)
/// <summary>
/// 바이-톤 필터 적용하기
/// </summary>
/// <param name="sourceBitmap">소스 비트맵</param>
/// <param name="darkColor">어두운 색상</param>
/// <param name="lightColor">밝은 색상</param>
/// <param name="threshold">임계치</param>
/// <returns>비트맵</returns>
public static Bitmap ApplyBitonalFilter(Bitmap sourceBitmap, Color darkColor, Color lightColor, int threshold)
{
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);
for(int i = 0; i + 4 < targetByteArray.Length; i += 4)
{
if (targetByteArray[i] + targetByteArray[i + 1] + targetByteArray[i + 2] <= threshold)
{
targetByteArray[i ] = darkColor.B;
targetByteArray[i + 1] = darkColor.G;
targetByteArray[i + 2] = darkColor.R;
}
else
{
targetByteArray[i ] = lightColor.B;
targetByteArray[i + 1] = lightColor.G;
targetByteArray[i + 2] = lightColor.R;
}
}
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
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - MainForm()
/// <summary>
/// 생성자
/// </summary>
public MainForm()
{
InitializeComponent();
this.darkColorPanel.Click += colorPanel_Click;
this.lightColorPanel.Click += colorPanel_Click;
this.thresholdTrackBar.ValueChanged += thresholdTrackBar_ValueChanged;
this.loadImageButton.Click += localImageButton_Click;
this.saveImageButton.Click += saveImageButton_Click;
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Private
//////////////////////////////////////////////////////////////////////////////// Event
#region 색상 패널 클릭시 처리하기 - colorPanel_Click(sender, e)
/// <summary>
/// 색상 패널 클릭시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void colorPanel_Click(object sender, EventArgs e)
{
if(sender is Panel)
{
Panel panel = (Panel)sender;
ColorDialog colorDialog = new ColorDialog();
colorDialog.AllowFullOpen = true;
colorDialog.Color = panel.BackColor;
colorDialog.FullOpen = true;
if(colorDialog.ShowDialog() == DialogResult.OK)
{
panel.BackColor = colorDialog.Color;
ApplyFilter(true);
}
}
}
#endregion
#region 임계치 트랙바 값 변경시 처리하기 - thresholdTrackBar_ValueChanged(sender, e)
/// <summary>
/// 임계치 트랙바 값 변경시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void thresholdTrackBar_ValueChanged(object sender, EventArgs e)
{
this.thresholdValueLabel.Text = this.thresholdTrackBar.Value.ToString();
ApplyFilter(true);
}
#endregion
#region 이미지 로드 버튼 클릭시 처리하기 - localImageButton_Click(sender, e)
/// <summary>
/// 이미지 로드 버튼 클릭시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void localImageButton_Click(object sender, EventArgs e)
{
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Title = "이미지 파일 로드";
openFileDialog.Filter = "PNG 이미지(*.png)|*.png|JPEG 이미지(*.jpg)|*.jpg|비트맵 이미지(*.bmp)|*.bmp";
if(openFileDialog.ShowDialog() == DialogResult.OK)
{
StreamReader streamReader = new StreamReader(openFileDialog.FileName);
this.sourceBitmap = Bitmap.FromStream(streamReader.BaseStream) as Bitmap;
streamReader.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 streamWriter = new StreamWriter(saveFileDialog.FileName, false);
this.targetBitmap.Save(streamWriter.BaseStream, imageFormat);
streamWriter.Flush();
streamWriter.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;
}
if(preview == true)
{
this.pictureBox.Image = BitmapHelper.ApplyBitonalFilter
(
this.previewBitmap,
this.darkColorPanel.BackColor,
this.lightColorPanel.BackColor,
this.thresholdTrackBar.Value
);
}
else
{
this.targetBitmap = BitmapHelper.ApplyBitonalFilter
(
this.sourceBitmap,
this.darkColorPanel.BackColor,
this.lightColorPanel.BackColor,
this.thresholdTrackBar.Value
);
}
}
#endregion
}
}
728x90
그리드형(광고전용)
'C# > WinForm' 카테고리의 다른 글
[C#/WINFORM] Bitmap 클래스 : 부분 색상 반전하기 (0) | 2021.02.24 |
---|---|
[C#/WINFORM] Bitmap 클래스 : 색상 균형 필터(Color Balance Filter) 사용하기 (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 클래스 : 색조 필터(Color Tint Filter) 사용하기 (0) | 2021.01.28 |
[C#/WINFORM] Bitmap 클래스 : 색상 음영 필터(Color Shading Filter) 사용하기 (0) | 2021.01.27 |
[C#/WINFORM] Bitmap 클래스 : 열화 필터(Solar Filter) 사용하기 (0) | 2021.01.27 |
[C#/WINFORM] Form 클래스 : 높은 DPI에서 흐릿하게 출력 방지하기 (0) | 2021.01.23 |
[C#/WINFORM] Bitmap 클래스 : 대비 필터(Contrast Filter) 사용하기 (0) | 2021.01.14 |