Double Buffering
Bitmap을 생성하여 이를 활용한다.
class CustomControl : Control
{
private Bitmap DoubleBufferImage
{
get
{
if (bmDoubleBuffer == null)
{
bmDoubleBuffer = new Bitmap(this.ClientSize.Width, this.ClientSize.Height);
}
return bmDoubleBuffer;
}
set
{
if (bmDoubleBuffer != null)
bmDoubleBuffer.Dispose();
bmDoubleBuffer = value;
}
}
protected override void OnResize(EventArgs e)
{
DoubleBufferImage = new Bitmap(this.ClientSize.Width, this.ClientSize.Height);
base.OnResize(e);
}
// Override this method with no code to avoid flicker
protected override void OnPaintBackground(PaintEventArgs e) { }
protected override void OnPaint(PaintEventArgs e)
{
using (Graphics gOff = Graphics.FromImage(DoubleBufferImage))
{
gOff.Draw....
g.DrawImage(DoubleBufferImage, 0, 0);
}
}
ImageAttributes 의 제약 사항
DrawImage의 마지막 parameter로 넘겨주어 color-adjustment, grayscale, transparency, color-map table, color-threadhold등의 manipulation을 할 수 있도록 한다.
그러나, .NET Cf에서는 ImageAttributes.SetColorKey()를 통해서 transparency만 조절할 수 있다. 한 가지 색깔만 transparency로 설정할 수 있다.
Alphablend가 필요할 경우 Pinvoke를 사용해야 한다.
GradientFill이 필요할 경우 Pinvoke를 사용해야 한다.
회전된 Text 표시하기
LogFont 를 이용하여 Font에 효과를 주어 그림을 그릴 수 있다.
private Font CreateRotatedFont(string fontname, int angleInDegree)
{
LogFont logf = new LogFont();
using (Graphics g = this.CreateGraphics())
{
logf.Height = (int)(-18f * g.DpiY / curDPI);
logf.Escapement = angleInDegree * 10;
logf.Orientation = logf.Escapement;
logf.FaceName = fontname;
logf.CharSet = LogFontCharSet.Default;
logf.OutPrecision = LogFontPrecision.Default;
logf.ClipPrecision = LogFontClipPrecision.Default;
logf.Quality = LogFontQuality.ClearType;
logf.PitchAndFamily = LogFontPitchAndFamily.Default;
}
return Font.FromLogFont(logf);
}
Bitmap 데이터를 직접 건드리려는 경우에는 LockBits를 사용한다.
이 때 bitmap data의 pointer는 unmanaged pointer이므로 Marshal.Copy를 사용한다.
private void MakeMoreBlue(Bitmap bmp)
{
PixelFormat pxf = PixelFormat.Format24bppRgb;
// Lock the bitmap's bits
Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
BitmapData bmpData = bmp.LockBits(rect, ImageLockMode.ReadWrite, pxf);
IntPtr ptr = bmpData.Scan0;
int numBytes = bmpData.Stride * bmp.Height;
byte[] rgbValues = new byte[numBytes];
Marshal.Copy(ptr, rgbValues, 0, numBytes);
for (int counter = 0; counter < rgbValues.Length; counter += 6)
{
rgbValues[counter] = 255;
}
Marshal.Copy(rgbValues, 0, ptr, numBytes);
bmp.UnlockBits(bmpData);
}
댓글 없음:
댓글 쓰기