在c#中使用bitblt显示图片
2021-02-17 23:16
标签:word black tar runtime initial com ati else mode 使用bitblt比DrawImage有更好的性能,实际使用中,毛边现象比较严重。 在c#中使用bitblt显示图片 标签:word black tar runtime initial com ati else mode 原文地址:https://www.cnblogs.com/zhaogaojian/p/8365241.html
using
AForge.Video.DirectShow;
using
System;
using
System.Collections.Generic;
using
System.ComponentModel;
using
System.Data;
using
System.Drawing;
using
System.Drawing.Imaging;
using
System.Linq;
using
System.Runtime.InteropServices;
using
System.Text;
using
System.Windows.Forms;
namespace
HongYing.Test
{
public
partial
class
BitBltTester : Form
{
private
VideoCaptureDevice videoSource;
public
BitBltTester()
{
InitializeComponent();
#if GDIPlus
SetStyle(ControlStyles.OptimizedDoubleBuffer,
true
);
//默认启动双缓冲
SetStyle(ControlStyles.DoubleBuffer,
true
);
SetStyle(ControlStyles.UserPaint,
true
);
SetStyle(ControlStyles.ResizeRedraw,
true
);
SetStyle(ControlStyles.AllPaintingInWmPaint,
true
);
// 禁止擦除背景.
#endif
var
videoDevices =
new
FilterInfoCollection(FilterCategory.VideoInputDevice);
videoSource =
new
VideoCaptureDevice(videoDevices[1].MonikerString);
videoSource.NewFrame += _videoSource_NewFrame;
videoSource.Start();
}
protected
override
void
OnPaint(PaintEventArgs e)
{
base
.OnPaint(e);
#if GDIPlus
if
(frame !=
null
)
{
e.Graphics.DrawImage(frame, ClientRectangle);
}
#else
#endif
}
public
enum
TernaryRasterOperations :
uint
{
SRCCOPY = 0x00CC0020,
SRCPAINT = 0x00EE0086,
SRCAND = 0x008800C6,
SRCINVERT = 0x00660046,
SRCERASE = 0x00440328,
NOTSRCCOPY = 0x00330008,
NOTSRCERASE = 0x001100A6,
MERGECOPY = 0x00C000CA,
MERGEPAINT = 0x00BB0226,
PATCOPY = 0x00F00021,
PATPAINT = 0x00FB0A09,
PATINVERT = 0x005A0049,
DSTINVERT = 0x00550009,
BLACKNESS = 0x00000042,
WHITENESS = 0x00FF0062,
CAPTUREBLT = 0x40000000
//only if WinVer >= 5.0.0 (see wingdi.h)
}
Bitmap frame;
private
const
int
SRCCOPY = 0xCC0020;
void
_videoSource_NewFrame(
object
sender, AForge.Video.NewFrameEventArgs eventArgs)
{
frame = (Bitmap)eventArgs.Frame.Clone();
#if GDIPlus
Invalidate();
#else
Bitmap sourceBitmap = frame;
Graphics sourceGraphics = Graphics.FromImage(frame);
Graphics destGraphics = CreateGraphics();
IntPtr destDC = destGraphics.GetHdc();
IntPtr destCDC = CreateCompatibleDC(destDC);
IntPtr oldDest = SelectObject(destCDC, IntPtr.Zero);
IntPtr sourceDC = sourceGraphics.GetHdc();
IntPtr sourceCDC = CreateCompatibleDC(sourceDC);
IntPtr sourceHB = sourceBitmap.GetHbitmap();
IntPtr oldSource = SelectObject(sourceCDC, sourceHB);
int
success = StretchBlt(destDC, 0, 0, Width, Height, sourceCDC, 0, 0, sourceBitmap.Width, sourceBitmap.Height, (
int
)TernaryRasterOperations.SRCCOPY);
SelectObject(destCDC, oldDest);
SelectObject(sourceCDC, oldSource);
DeleteObject(destCDC);
DeleteObject(sourceCDC);
DeleteObject(sourceHB);
destGraphics.ReleaseHdc();
sourceGraphics.ReleaseHdc();
#endif
eventArgs.Frame.Dispose();
}
[System.Runtime.InteropServices.DllImportAttribute(
"gdi32.dll"
)]
public
static
extern
IntPtr CreateCompatibleDC(IntPtr hdc);
[System.Runtime.InteropServices.DllImport(
"gdi32.dll"
)]
private
static
extern
int
BitBlt(
IntPtr hdcDest,
// handle to destination DC (device context)
int
nXDest,
// x-coord of destination upper-left corner
int
nYDest,
// y-coord of destination upper-left corner
int
nWidth,
// width of destination rectangle
int
nHeight,
// height of destination rectangle
IntPtr hdcSrc,
// handle to source DC
int
nXSrc,
// x-coordinate of source upper-left corner
int
nYSrc,
// y-coordinate of source upper-left corner
System.Int32 dwRop
// raster operation code
);
[System.Runtime.InteropServices.DllImportAttribute(
"gdi32.dll"
)]
public
static
extern
IntPtr SelectObject(IntPtr hdc, IntPtr obj);
[System.Runtime.InteropServices.DllImportAttribute(
"gdi32.dll"
)]
public
static
extern
void
DeleteObject(IntPtr obj);
[DllImport(
"gdi32"
, EntryPoint =
"StretchBlt"
)]
public
static
extern
int
StretchBlt(
IntPtr hdc,
int
x,
int
y,
int
nWidth,
int
nHeight,
IntPtr hSrcDC,
int
xSrc,
int
ySrc,
int
nSrcWidth,
int
nSrcHeight,
int
dwRop
);
}
}