C# 将图形对象转换为位图

C# 将图形对象转换为位图,c#,image,graphics,bitmap,C#,Image,Graphics,Bitmap,我的图形对象有以下问题 编辑: 我有一个picturebox_image(imageRxTx),它是一个来自摄像机的实时流。我在paint事件中所做的是在imageRxTx图像的顶部绘制一些线(下面的代码中未显示)。到目前为止,这一切都没有问题 现在我需要检查imageRxTx中的圆,因此我必须使用方法ProcessImage(),它需要一个位图作为参数。不幸的是,我没有位图图像,而是我的imageRxTx的句柄(hDC) 问题:如何从图形对象中获取imageRxTx并将其“转换”为位图图像,我

我的图形对象有以下问题

编辑:

我有一个picturebox_image(imageRxTx),它是一个来自摄像机的实时流。我在paint事件中所做的是在imageRxTx图像的顶部绘制一些线(下面的代码中未显示)。到目前为止,这一切都没有问题

现在我需要检查imageRxTx中的圆,因此我必须使用方法ProcessImage(),它需要一个位图作为参数。不幸的是,我没有位图图像,而是我的imageRxTx的句柄(hDC)

问题:如何从图形对象中获取imageRxTx并将其“转换”为位图图像,我需要在方法处理图像(位图)中使用该图像?为了检查我的相机(imageRxTx)的实时流,需要在绘制事件中不断调用此方法

这是我的代码:

    private void imageRxTx_paint(object sender, PaintEventArgs e)
    {
        var settings = new Settings();

        // Create a local version of the graphics object for the PictureBox.
        Graphics Draw = e.Graphics;
        IntPtr hDC = Draw.GetHdc(); // Get a handle to image_RxTx.           

        Draw.ReleaseHdc(hDC); // Release image_RxTx handle.


        //Here I need to send the picturebox_image 'image_RxTx' to ProcessImage as Bitmap
        AForge.Point center = ProcessImage( ?....? );    
    }


    // Check for circles in the bitmap-image
    private AForge.Point ProcessImage(Bitmap bitmap)
    {
        //at this point I should read the picturebox_image 'image_RxTx'
        ...
视频图像在此处更新:

    private void timer1_Elapsed(object sender, EventArgs e)
    {
        // If Live and captured image has changed then update the window
        if (PIXCI_LIVE && LastCapturedField != pxd_capturedFieldCount(1))
        {
            LastCapturedField = pxd_capturedFieldCount(1);
            image_RxTx.Invalidate();
        }
    }

方法
Graphics.CopyFromScreen
可能就是您要寻找的

var rect = myControl.DisplayRectangle;
var destBitmap = new Bitmap(rect.Width, rect.Height, PixelFormat.Format24bppRgb);
using (var gr = Graphics.FromImage(destBitmap))
{
    gr.CopyFromScreen(myControl.PointToScreen(new Point(0, 0)), new Point(0, 0), rect.Size);
}

正如标题所示,您的主要问题是对
图形
对象的(常见)误解

到目前为止,我可以毫无问题地绘制图形对象

  • 不!“
    Graphics
    ”对象不包含任何图形。它只是用于在相关位图上绘制图形的工具。因此您根本不需要绘制
    图形
    对象;您可以使用它来绘制
    imageRxTx
    ,不管是什么,可能是一些
    控件的表面
    表单

  • 这一行使用的是一种经常令人困惑的、毫无用处的
    位图格式


最后一个参数是doing,几乎为零;其唯一功能是复制
Dpi
设置。特别是,它不会克隆或复制“Draw”中的任何内容,正如您现在所知,
Graphics
对象也没有任何其他设置。因此,是的,
bmp位图
在那之后仍然是空的

如果要绘制到
bmp
中,则需要使用实际绑定到它的
图形
对象:

using (Graphics G = Graphics.FromImage(bmp)
{
   // draw now..
   // to draw an Image img onto the Bitmap use
   G.DrawImage(img, ...); 
   // with the right params for source and destination!
}
Paint
事件中可能不会发生这种情况!但是所有的准备代码都不清楚你真正想做什么。您应该解释什么是图形的源,什么是目标

相反,如果您想将绘制的内容放到图像上
image\u RxTx
a
位图
,您可以使用此方法在(!)之外的某个地方绘制
事件:

Bitmap bmp = new Bitmap(image_RxTx.Width, image_RxTx.Height);
image_RxTx.DrawToBitmap(bmp, image_RxTx.ClientRectangle);
这将使用
绘制
事件将控件绘制到
位图中。并不是说结果包括整个
:背景图像
图像
和曲面图


更新:要获得
图片盒
组合内容,即它的
图像
和你在表面上绘制的内容,你应该使用上面的代码(最后两行)在
定时器的
事件中,勾选
定时器的
事件,或在触发
绘制
事件的行之后勾选
事件。(您没有向我们展示这是如何发生的。)您不能将其准确地放入
绘制
事件本身,因为它将使用
绘制
事件,因此将导致无限循环

是的,这可以工作,但我只得到一个白色图像时,保存位图。也许它在实现上做错了什么。我的代码是:
//从图形对象var rect=image\u RxTx.DisplayRectangle创建位图;var destBitmap=新位图(rect.Width、rect.Height、PixelFormat.Format24bppRgb);使用(var gr=Graphics.FromImage(destBitmap)){gr.CopyFromScreen(image_RxTx.PointToScreen(new Point(0,0)),new Point(0,0),rect.Size);}AForge.Point center=ProcessImage(destBitmap)我可以为“myControl”使用pictureBox图像吗?我想问题在这里:IntPtr hDC=Draw.GetHdc();//获取图像的句柄。我需要使用这个句柄并将其转换为位图图像,但是如何?如果您只得到一个白色图像,那么可能您的控件尚未绘制到屏幕上。事件处理程序可能在操作系统已填充背景色但图像尚未绘制时启动。请注意,操作系统不会将控件的位图“保存”到屏幕以外的任何位置。如果你的控件被另一个窗口遮挡(如果你正在运行一个调试器,调试器总是弹出到前台,这可能会有问题!),那么在你抓取它之前,它必须被重新绘制。谢谢你的详细解释。。!我编辑了我的问题以便澄清。我需要的是我的image_RxTx(源picturebox)的位图,作为ProcessImage(位图)方法的输入参数。也请看我的编辑-谢谢。好的,我已经更新了anwser。绘画活动的名称是什么?您是否在某个地方有一个Invalidate(),或者它在照相机代码中?我希望视频实际上是在图片盒中,而不仅仅是叠加。。能否进行屏幕复制?绘制事件在程序开始时在InitializeComponent()中生成,因此在启动程序后继续调用。-嗯,那没有道理。问题是什么时候叫它?(画图通常由系统调用,当它需要重新绘制窗口时,或者由您的代码调用,例如当要绘制的内容发生更改时,例如对象发生了移动..啊,这是有意义的。因此,插入两行,可能还有第三行,以便保存或调用您的方法
Bitmap bmp = new Bitmap(image_RxTx.Width, image_RxTx.Height);
image_RxTx.DrawToBitmap(bmp, image_RxTx.ClientRectangle);