在c#中使用bitblt显示图片

使用bitblt比DrawImage有更好的性能

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
        );
    }
}

参考:experts-exchange.com

时间: 2024-08-27 15:00:56

在c#中使用bitblt显示图片的相关文章

Android中高效的显示图片之一 ——加载大图

在网上看了不少文章,发现还是官方文档介绍最详细,把重要的东西简单摘要出来.详细可看官方文档地址 ( http://www.bangchui.org/read.php?tid=9 ) . 在应用中显示图片,如果不多加小心,很容易就会使应用因为异常“java.lang.OutofMemoryError:bitmap size exceeds VM budget”而导致crash.在android中加载图片需要一定的技巧性,主要是因为: 1.通常设备资源有限,安卓设备给每个应用只分配16M的空间.当然

Android中高效的显示图片之三——缓存图片

加载一张图片到UI相对比较简单,如果一次要加载一组图片,就会变得麻烦很多.像ListView,GridView,ViewPager等控件,需要显示的图片和将要显示的图片数量可能会很大. 为了减少内存使用,这类控件都重复利用移出屏幕的子视图,如果你没有持用引用,垃圾回收器也会回收你加载过的图片.这种做法很好,但是如果想要图片加载快速流畅且不想当控件拖回来时重新运算获取加载过的图片,通常会使用内存和磁盘缓存.这节主要介绍当加载多张图片时利用内存缓存和磁盘缓存使加载图片时更快. 一.使用内存缓存 内存

Android中高效的显示图片之二——在非UI线程中处理图片

在“加载大图”文章中提到的BitmapFactory.decode*方法,如果源数据是在磁盘.网络或其它任何不是在内存中的位置,那么它都不应该在UI线程中执行.因为它的加载时间不可预测且依赖于一系列因素(磁盘读写速度.图片大小.CPU频率等).如果在主线程中执行这个操作,一旦它阻塞了主线程,就会导致系统ANR.本节介绍使用AsyncTask在后台处理图片和演示怎么处理并发问题. 一.使用一个AsyncTask AsyncTask类提供一个简易的方法在后台线程中执行一些任务并把结果发布到UI线程.

七、在U-boot中让LCD显示图片

1. 编译U-boot 准备好U-boot压缩包urbetter-u-boot-1.1.6-v1.0.tgz,输入命令:tar -xvf urbetter-u-boot-1.1.6-v1.0.tgz 进入U-boot目录,按顺序执行以下命令: make clean make smdk6410_config make 会报出很多/usr/local/arm/arm-none-linux-gnueabi/bin/arm-none-linux-gnueabi-gcc: not found的错误,这是因

ionic ng-src 在网页显示,但是导出apk在android手机中运行不显示图片

解决方法参照: http://stackoverflow.com/questions/29896158/load-image-using-ng-src-in-android-ionic-aplication 步骤: (1)安装 cordova-plugin-whitelist [email protected]:myapp1$ cordova plugins add cordova-plugin-whitelist (2)确保config.xml配置文件 <access origin="*

将图片以二进制的方式保存在数据库中,并显示图片

http://www.aspnettutorials.com/tutorials/database/store-img-bins-asp4-cs/ http://stackoverflow.com/questions/18998763/how-to-retrieve-binary-image-from-database-using-c-sharp-in-asp-net 1. 创建一个数据表 CREATE TABLE [dbo].[SaveImageByBinary] ( [Id] INT NOT

我写的一个 Qt 显示图片的控件

Qt 中没有专门显示图片的控件,通常我们会使用QLabel来显示图片.但是QLabel 显示图片的能力还是有点弱.比如不支持图像的缩放一类的功能,使用起来不是很方便.因此我就自己写了个简单的类. 我这个类支持三种图像显示模式,我分别称之为:FIXED_SIZE, CENTRED,AUTO_ZOOM, AUTO_SIZE. FIXED_SIZE 模式下,显示的图像大小等于图像尺寸乘以缩放因子,如果控件的尺寸小于这个大小则多出的部分被裁切掉. FIX_SIZE_CENTRED模式与FIXED_SIZ

OpenCV 2.2版本以上显示图片到 MFC 的 Picture Control 控件中

OpenCV 2.2 以及后面的版本取消掉了 CvvImage.h 和CvvImage.cpp 两个文件,直接导致了苦逼的程序员无法调用里面的显示函数来将图片显示到 MFC 的 Picture Control 控件中.为此,网上很多人表示只要将那两个文件人为的提取出来然后放到工程里面就解决问题了,也提供了两个文件的下载,但是这麻烦不说,还会导致一些奇奇怪怪的报错(至少本人是这样的,很崩溃!).所以在了解了一些gdi绘图之后结合网上的代码写了如下的函数,只需调用就可以将OpenCV的图片显示在上面

在DevExpress GridControl的一列中显示图片

最近做项目的时候用到了将GridControl中一列设置为PictureEdit类型,然后通过这一列来显示图片.经过尝试发现有以下两种方式可行. 方法一.知道图片的路径与名称 比如:在数据库中存储了图片的路径(包括:本地路径.服务器路径),那么在可以通过非绑定列的方式来实现. 1.创建了一个非绑定列并设置其相应的属性,属性设置如下: FieldName设为 Photo(该字段名必须是唯一的) UnboundType设为 UnboundColumnType.Object ColumnEdit设为R