728x90
반응형
728x170
▶ BitmapPixelHelper.cs
using System;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;
namespace TestProject
{
/// <summary>
/// 비트맵 픽셀 헬퍼
/// </summary>
/// <remarks>BGRA32 포맷</remarks>
public class BitmapPixelHelper
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Field
////////////////////////////////////////////////////////////////////////////////////////// Public
#region Field
/// <summary>
/// 너비
/// </summary>
public int Width;
/// <summary>
/// 높이
/// </summary>
public int Height;
#endregion
////////////////////////////////////////////////////////////////////////////////////////// Private
#region Field
/// <summary>
/// 픽셀 바이트 배열
/// </summary>
private byte[] pixelByteArray;
/// <summary>
/// 스트라이드
/// </summary>
/// <remarks>행당 바이트 수</remarks>
private int stride;
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - BitmapPixelHelper(width, height)
/// <summary>
/// 생성자
/// </summary>
/// <param name="width">너비</param>
/// <param name="height">높이</param>
public BitmapPixelHelper(int width, int height)
{
Initialize(width, height);
}
#endregion
#region 생성자 - BitmapPixelHelper(bitmap)
/// <summary>
/// 생성자
/// </summary>
/// <param name="bitmap">쓰기 가능 비트맵</param>
public BitmapPixelHelper(WriteableBitmap bitmap)
{
Initialize(bitmap);
}
#endregion
#region 생성자 - BitmapPixelHelper(uri)
/// <summary>
/// 생성자
/// </summary>
/// <param name="uri">URI</param>
public BitmapPixelHelper(Uri uri)
{
BitmapImage bitmapImage = new BitmapImage(uri);
WriteableBitmap bitmap = new WriteableBitmap(bitmapImage);
Initialize(bitmap);
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 픽셀 구하기 - GetPixel(x, y, red, green, blue, alpha)
/// <summary>
/// 픽셀 구하기
/// </summary>
/// <param name="x">X</param>
/// <param name="y">Y</param>
/// <param name="red">적색</param>
/// <param name="green">녹색</param>
/// <param name="blue">청색</param>
/// <param name="alpha">알파</param>
public void GetPixel(int x, int y, out byte red, out byte green, out byte blue, out byte alpha)
{
int index = y * this.stride + x * 4;
blue = this.pixelByteArray[index++];
green = this.pixelByteArray[index++];
red = this.pixelByteArray[index++];
alpha = this.pixelByteArray[index];
}
#endregion
#region 청색 구하기 - GetBlue(x, y)
/// <summary>
/// 청색 구하기
/// </summary>
/// <param name="x">X</param>
/// <param name="y">Y</param>
/// <returns>청색</returns>
public byte GetBlue(int x, int y)
{
return this.pixelByteArray[y * this.stride + x * 4];
}
#endregion
#region 녹색 구하기 - GetGreen(x, y)
/// <summary>
/// 녹색 구하기
/// </summary>
/// <param name="x">X</param>
/// <param name="y">Y</param>
/// <returns>녹색</returns>
public byte GetGreen(int x, int y)
{
return this.pixelByteArray[y * this.stride + x * 4 + 1];
}
#endregion
#region 적색 구하기 - GetRed(x, y)
/// <summary>
/// 적색 구하기
/// </summary>
/// <param name="x">X</param>
/// <param name="y">Y</param>
/// <returns>적색</returns>
public byte GetRed(int x, int y)
{
return this.pixelByteArray[y * this.stride + x * 4 + 2];
}
#endregion
#region 알파 구하기 - GetAlpha(x, y)
/// <summary>
/// 알파 구하기
/// </summary>
/// <param name="x">X</param>
/// <param name="y">Y</param>
/// <returns>알파</returns>
public byte GetAlpha(int x, int y)
{
return this.pixelByteArray[y * this.stride + x * 4 + 3];
}
#endregion
#region 픽셀 설정하기 - SetPixel(x, y, red, green, blue, alpha)
/// <summary>
/// 픽셀 설정하기
/// </summary>
/// <param name="x">X</param>
/// <param name="y">Y</param>
/// <param name="red">적색</param>
/// <param name="green">녹색</param>
/// <param name="blue">청색</param>
/// <param name="alpha">알파</param>
public void SetPixel(int x, int y, byte red, byte green, byte blue, byte alpha)
{
int index = y * this.stride + x * 4;
this.pixelByteArray[index++] = blue;
this.pixelByteArray[index++] = green;
this.pixelByteArray[index++] = red;
this.pixelByteArray[index++] = alpha;
}
#endregion
#region 청색 설정하기 - SetBlue(x, y, blue)
/// <summary>
/// 청색 설정하기
/// </summary>
/// <param name="x">X</param>
/// <param name="y">Y</param>
/// <param name="blue">청색</param>
public void SetBlue(int x, int y, byte blue)
{
this.pixelByteArray[y * this.stride + x * 4] = blue;
}
#endregion
#region 녹색 설정하기 - SetGreen(x, y, green)
/// <summary>
/// 녹색 설정하기
/// </summary>
/// <param name="x">X</param>
/// <param name="y">Y</param>
/// <param name="green">녹색</param>
public void SetGreen(int x, int y, byte green)
{
this.pixelByteArray[y * this.stride + x * 4 + 1] = green;
}
#endregion
#region 적색 설정하기 - SetRed(x, y, red)
/// <summary>
/// 적색 설정하기
/// </summary>
/// <param name="x">X</param>
/// <param name="y">Y</param>
/// <param name="red">적색</param>
public void SetRed(int x, int y, byte red)
{
this.pixelByteArray[y * this.stride + x * 4 + 2] = red;
}
#endregion
#region 알파 설정하기 - SetAlpha(x, y, alpha)
/// <summary>
/// 알파 설정하기
/// </summary>
/// <param name="x">X</param>
/// <param name="y">Y</param>
/// <param name="alpha">적색</param>
public void SetAlpha(int x, int y, byte alpha)
{
this.pixelByteArray[y * this.stride + x * 4 + 3] = alpha;
}
#endregion
#region 색상 설정하기 - SetColor(red, green, blue, alpha)
/// <summary>
/// 색상 설정하기
/// </summary>
/// <param name="red">적색</param>
/// <param name="green">녹섹</param>
/// <param name="blue">청색</param>
/// <param name="alpha">알파</param>
public void SetColor(byte red, byte green, byte blue, byte alpha)
{
int byteCount = Width * Height * 4;
int index = 0;
while(index < byteCount)
{
this.pixelByteArray[index++] = blue;
this.pixelByteArray[index++] = green;
this.pixelByteArray[index++] = red;
this.pixelByteArray[index++] = alpha;
}
}
#endregion
#region 색상 설정하기 - SetColor(red, green, blue)
/// <summary>
/// 색상 설정하기
/// </summary>
/// <param name="red">적색</param>
/// <param name="green">녹섹</param>
/// <param name="blue">청색</param>
public void SetColor(byte red, byte green, byte blue)
{
SetColor(red, green, blue, 255);
}
#endregion
#region 비트맵 구하기 - GetBitmap(dpiX, dpiY)
/// <summary>
/// 비트맵 구하기
/// </summary>
/// <param name="dpiX">DPI X</param>
/// <param name="dpiY">DPI Y</param>
/// <returns>쓰기 가능 비트맵</returns>
public WriteableBitmap GetBitmap(double dpiX, double dpiY)
{
WriteableBitmap bitmap = new WriteableBitmap
(
Width,
Height,
dpiX,
dpiY,
PixelFormats.Bgra32,
null
);
Int32Rect rectangle = new Int32Rect(0, 0, Width, Height);
bitmap.WritePixels(rectangle, this.pixelByteArray, this.stride, 0);
return bitmap;
}
#endregion
////////////////////////////////////////////////////////////////////////////////////////// Private
#region 초기화하기 - Initialize(width, height)
/// <summary>
/// 초기화하기
/// </summary>
/// <param name="width">너비</param>
/// <param name="height">높이</param>
private void Initialize(int width, int height)
{
Width = width;
Height = height;
this.pixelByteArray = new byte[width * height * 4];
this.stride = width * 4;
}
#endregion
#region 초기화하기 - Initialize(bitmap)
/// <summary>
/// 초기화하기
/// </summary>
/// <param name="bitmap">쓰기 가능 비트맵</param>
private void Initialize(WriteableBitmap bitmap)
{
int width = Convert.ToInt32(bitmap.Width);
int height = Convert.ToInt32(bitmap.Height);
Initialize(width, height);
Int32Rect rectangle = new Int32Rect(0, 0, Width, Height);
bitmap.CopyPixels(rectangle, this.pixelByteArray, this.stride, 0);
}
#endregion
}
}
728x90
▶ MainWindow.xaml
<Window x:Class="TestProject.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="800"
Height="600"
Title="WriteableBitmap 클래스 : 비트맵 픽셀 조작하기"
FontFamily="나눔고딕코딩"
FontSize="16">
<Grid Margin="10">
<Image Name="image" Stretch="None" />
</Grid>
</Window>
300x250
▶ MainWindow.xaml.cs
using System;
using System.Windows;
using System.Windows.Media.Imaging;
namespace TestProject
{
/// <summary>
/// 메인 윈도우
/// </summary>
public partial class MainWindow : Window
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - MainWindow()
/// <summary>
/// 생성자
/// </summary>
public MainWindow()
{
InitializeComponent();
Loaded += Window_Loaded;
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Private
#region 윈도우 로드시 처리하기 - Window_Loaded(sender, e)
/// <summary>
/// 윈도우 로드시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void Window_Loaded(object sender, RoutedEventArgs e)
{
Uri uri = new Uri("IMAGE/Smiley.png", UriKind.Relative);
BitmapPixelHelper helper = new BitmapPixelHelper(uri);
int cellWidth = helper.Width / 4;
int cellHeight = helper.Height / 4;
int columnCount = helper.Width / cellWidth;
int rowCount = helper.Height / cellHeight;
for(int row = 0; row < rowCount; row++)
{
for(int column = 0; column < columnCount; column++)
{
for(int i = 0; i < cellWidth; i++)
{
for(int j = 0; j < cellHeight; j++)
{
int x = column * cellWidth + j;
int y = row * cellHeight + i;
if((x < helper.Width) && (y < helper.Height))
{
byte red;
byte green;
byte blue;
byte alpha;
helper.GetPixel(x, y, out red, out green, out blue, out alpha);
if((column + row) % 2 == 0)
{
red = (byte)(255 - (255 - red ) * 0.75);
green = (byte)(255 - (255 - green) * 0.75);
blue = (byte)(255 - (255 - blue ) * 0.75);
}
else
{
red = (byte)(red * 0.75);
green = (byte)(green * 0.75);
blue = (byte)(blue * 0.75);
}
helper.SetPixel(x, y, red, green, blue, alpha);
}
}
}
}
}
WriteableBitmap bitmap = helper.GetBitmap(96, 96);
this.image.Source = bitmap;
}
#endregion
}
}
728x90
반응형
그리드형(광고전용)
'C# > WPF' 카테고리의 다른 글
[C#/WPF] BulletDecorator 엘리먼트 사용하기 (0) | 2020.08.08 |
---|---|
[C#/WPF] DrawingVisual 클래스 사용하기 (0) | 2020.08.07 |
[C#/WPF] UIElement 엘리먼트 : Clip 속성 사용하기 (0) | 2020.08.07 |
[C#/WPF] DrawingContext 클래스 : PushClip 메소드를 사용해 클리핑 영역 설정하기 (0) | 2020.08.06 |
[C#/WPF] Storyboard 클래스 : 이미지 슬라이드 쇼 보여주기 (0) | 2020.08.06 |
[C#/WPF] Trigger 엘리먼트 : 버튼 클릭시 배경색 변경하기 (0) | 2020.08.06 |
[C#/WPF] Mouse 클래스 : GetPosition 정적 메소드를 사용해 마우스 위치 구하기 (0) | 2020.08.06 |
[C#/WPF] SystemParameters 클래스 : IsMouseWheelPresent 정적 속성을 사용해 마우스 휠 존재 여부 구하기 (0) | 2020.08.06 |
[C#/WPF] FormatConvertedBitmap 클래스 사용하기 (0) | 2020.08.05 |
[C#/WPF] CachedBitmap 클래스 사용하기 (0) | 2020.08.05 |
댓글을 달아 주세요