Issue in Capturing Screenshot using wxGraphicsContext

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
saranya
Earned a small fee
Earned a small fee
Posts: 13
Joined: Mon May 23, 2016 9:47 am

Issue in Capturing Screenshot using wxGraphicsContext

Post by saranya » Thu Apr 25, 2019 10:56 am

I am using wxGraphicsContext to draw a curve in wxPlotctrl. In the Background of a curve, drawing gridlines and some texts using WXDC.
And I am Capturing screenshot using wxClientDc,.
In the Captured Image, the curve which I have drawn using wxGraphicsContext is only visible, not the gridlines and texts.

User avatar
T-Rex
Moderator
Moderator
Posts: 1182
Joined: Sat Oct 23, 2004 9:58 am
Location: Zaporizhzhya, Ukraine
Contact:

Re: Issue in Capturing Screenshot using wxGraphicsContext

Post by T-Rex » Thu Apr 25, 2019 11:36 am

Post some source code maybe? So that we could see whether there is a problem in screen capturing logic.

User avatar
doublemax
Moderator
Moderator
Posts: 14088
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Issue in Capturing Screenshot using wxGraphicsContext

Post by doublemax » Thu Apr 25, 2019 11:43 am

Platform, wxWidgets version?

In any case, it's more reliable to render everything into a wxBitmap through a wxMemoryDC. Just rewrite your render code so that it takes a wxDC& as parameter and you can use it to render on screen as well as into any other device context.
Use the source, Luke!

Kvaz1r
Earned some good credits
Earned some good credits
Posts: 129
Joined: Tue Jun 07, 2016 1:07 pm

Re: Issue in Capturing Screenshot using wxGraphicsContext

Post by Kvaz1r » Thu Apr 25, 2019 11:52 am

I think with wxMemoryDC it would be much more straightforward. Just assosiate your xMemoryDC object with wxGraphicsContext and draw anyrhing you want:

Code: Select all

    wxGraphicsContext* gc = wxGraphicsContext::Create(mdc);//mds is  wxMemoryDC object
    if (gc)
    {
        //draw here
        delete gc;
    }

saranya
Earned a small fee
Earned a small fee
Posts: 13
Joined: Mon May 23, 2016 9:47 am

Re: Issue in Capturing Screenshot using wxGraphicsContext

Post by saranya » Thu Apr 25, 2019 12:32 pm

T-Rex wrote:
Thu Apr 25, 2019 11:36 am
Post some source code maybe? So that we could see whether there is a problem in screen capturing logic.
This is how I am capturing Screen:

Code: Select all

               wxClientDC dcScreen(m_pmainwind->GetCanvasPtr()); //GetCanvasPtr() returns wxGLCanvas
			
			wxSize WinSize = m_pmainwind->GetCanvasPtr()->GetSize();
			
			//Create a Bitmap that will later on hold the screenshot image
			//Note that the Bitmap must have a size big enough to hold the screenshot
			//-1 means using the current default colour depth
			wxBitmap screenshot(WinSize.GetWidth()-18, WinSize.GetHeight()-18, -1);

			//Create a memory DC that will be used for actually taking the screenshot
			wxMemoryDC memDC;
			//Tell the memory DC to use our Bitmap
			//all drawing action on the memory DC will go to the Bitmap now
			memDC.SelectObject(screenshot);
			//Blit (in this case copy) the actual screen on the memory DC
			//and thus the Bitmap
			memDC.Blit(0, //Copy to this X coordinate
				0, //Copy to this Y coordinate
				WinSize.GetWidth()-18, //Copy this width
				WinSize.GetHeight()-18, //Copy this height
				&dcScreen, //From where do we copy?
				0, //What's the X offset in the original DC?
				0  //What's the Y offset in the original DC?
				);
			//Select the Bitmap out of the memory DC by selecting a new
			//uninitialized Bitmap
			memDC.SelectObject(wxNullBitmap);

			//Our Bitmap now has the screenshot, so let's save it :-)
			//screenshot.SaveFile("screenshot.jpg", wxBITMAP_TYPE_JPEG);
			wxImage tempimg = screenshot.ConvertToImage();

saranya
Earned a small fee
Earned a small fee
Posts: 13
Joined: Mon May 23, 2016 9:47 am

Re: Issue in Capturing Screenshot using wxGraphicsContext

Post by saranya » Thu Apr 25, 2019 12:35 pm

Kvaz1r wrote:
Thu Apr 25, 2019 11:52 am
I think with wxMemoryDC it would be much more straightforward. Just assosiate your xMemoryDC object with wxGraphicsContext and draw anyrhing you want:

Code: Select all

    wxGraphicsContext* gc = wxGraphicsContext::Create(mdc);//mds is  wxMemoryDC object
    if (gc)
    {
        //draw here
        delete gc;
    }
I am actually Creating a wxGraphicsContext using wxMemoryDC only.

User avatar
doublemax
Moderator
Moderator
Posts: 14088
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Issue in Capturing Screenshot using wxGraphicsContext

Post by doublemax » Thu Apr 25, 2019 12:40 pm

//GetCanvasPtr() returns wxGLCanvas
My guess is that this is the main problem. When using hardware accelerated OpenGL, the OpenGL window is usually a hardware overlay that doesn't "live" in normal Windows GDI space. (Still assuming that you're under Windows). In addition to that, i don't think mixing OpenGL drawing and GDI is supported in general. Can't you draw everything with OpenGL?

In order to capture an OpenGL window, look up glReadBuffer(). I'm not an OpenGL expert, so i can't provide any more details.
Use the source, Luke!

saranya
Earned a small fee
Earned a small fee
Posts: 13
Joined: Mon May 23, 2016 9:47 am

Re: Issue in Capturing Screenshot using wxGraphicsContext

Post by saranya » Thu Apr 25, 2019 12:41 pm

doublemax wrote:
Thu Apr 25, 2019 11:43 am
Platform, wxWidgets version?

In any case, it's more reliable to render everything into a wxBitmap through a wxMemoryDC. Just rewrite your render code so that it takes a wxDC& as parameter and you can use it to render on screen as well as into any other device context.
Platform:Windows 8, Visual studio 2015.
Version: wxWidgets 3.0.2

saranya
Earned a small fee
Earned a small fee
Posts: 13
Joined: Mon May 23, 2016 9:47 am

Re: Issue in Capturing Screenshot using wxGraphicsContext

Post by saranya » Thu Apr 25, 2019 1:19 pm

doublemax wrote:
Thu Apr 25, 2019 12:40 pm
//GetCanvasPtr() returns wxGLCanvas
My guess is that this is the main problem. When using hardware accelerated OpenGL, the OpenGL window is usually a hardware overlay that doesn't "live" in normal Windows GDI space. (Still assuming that you're under Windows). In addition to that, i don't think mixing OpenGL drawing and GDI is supported in general. Can't you draw everything with OpenGL?

In order to capture an OpenGL window, look up glReadBuffer(). I'm not an OpenGL expert, so i can't provide any more details.
Now, I have also tried in wxPanel(GetCanvasPtr() returns wxPanel). still the Issue Exists.

Kvaz1r
Earned some good credits
Earned some good credits
Posts: 129
Joined: Tue Jun 07, 2016 1:07 pm

Re: Issue in Capturing Screenshot using wxGraphicsContext

Post by Kvaz1r » Thu Apr 25, 2019 1:55 pm

In this case can you show code where drawing the grid and the curve i.e. where the difference? The code above looks OK if the issue is really not in OpenGL.

User avatar
doublemax
Moderator
Moderator
Posts: 14088
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Issue in Capturing Screenshot using wxGraphicsContext

Post by doublemax » Thu Apr 25, 2019 2:04 pm

I'm a little confused that you could change from wxGLCanvas to wxPanel to easily. Do you use OpenGL or not?
Please show the code for the paint event handler.
Use the source, Luke!

saranya
Earned a small fee
Earned a small fee
Posts: 13
Joined: Mon May 23, 2016 9:47 am

Re: Issue in Capturing Screenshot using wxGraphicsContext

Post by saranya » Fri Apr 26, 2019 7:43 am

doublemax wrote:
Thu Apr 25, 2019 2:04 pm
I'm a little confused that you could change from wxGLCanvas to wxPanel to easily. Do you use OpenGL or not?
Please show the code for the paint event handler.
Actually, My software Application uses OpenGL.
For drawing curves, I am not using OpenGL. so, I have tried in another application which uses only wxPanel.

This is the code I am using to draw Curve:

Code: Select all

void wxPlotDrawerDataCurve::Draw(wxDC *dc, wxPlotData* curve, int curve_index)
{
	wxCHECK_RET(dc && m_owner && curve && curve->Ok(), wxT("invalid curve"));
	INITIALIZE_FAST_GRAPHICS

		// With wxWidgets 3.1+, CreateFromUnknownDC() could be used, but with 3.0
		// we need to find out what kind of DC we were given ourselves.
		std::unique_ptr<wxGraphicsContext> ctx;
	if (const wxWindowDC *windc = dynamic_cast<const wxWindowDC*>(dc))
		ctx.reset(wxGraphicsContext::Create(*windc));
	else if (const wxMemoryDC *memdc = dynamic_cast<const wxMemoryDC*>(dc))
		ctx.reset(wxGraphicsContext::Create(*memdc));
	else
	{
		wxFAIL_MSG(wxT("Unknown kind of wxDC, add an extra check for it"));
		return;
	}

	bool bCheck = ctx->SetInterpolationQuality(wxInterpolationQuality::wxINTERPOLATION_BEST);
	wxGraphicsPath path = ctx->CreatePath();
	wxPen currentPen = (curve_index == m_owner->GetActiveIndex()) ? curve->GetPen(wxPLOTPEN_ACTIVE).GetPen()
		: curve->GetPen(wxPLOTPEN_NORMAL).GetPen();
	ctx->SetPen(currentPen);

	AddPointsToPath(path, newn, Points, wxPoint(1, -1));//where newn is size. Points are wxPoints
	ctx->StrokePath(path);

}
// Helper function used in wxPlotDrawerDataCurve::Draw() to add the given
	// points offset by the specified amount to a graphics path.
	void
		AddPointsToPath(wxGraphicsPath& path,
		size_t n,
		const wxPoint* points,
		const wxPoint& offset)
	{
		path.MoveToPoint(points[0] + offset);
		for (size_t i = 1; i < n; ++i)
			path.AddLineToPoint(points[i] + offset);
	}

User avatar
doublemax
Moderator
Moderator
Posts: 14088
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Issue in Capturing Screenshot using wxGraphicsContext

Post by doublemax » Fri Apr 26, 2019 8:45 am

So your code can already render into a wxMemoryDC. Why don't you do that and forget about wxClientDC?

Or are you saying that the problem also occurs when rendering directly into a wxMemoryDC? In that case, please provide a minimal compilable sample that shows the issue.
Use the source, Luke!

saranya
Earned a small fee
Earned a small fee
Posts: 13
Joined: Mon May 23, 2016 9:47 am

Re: Issue in Capturing Screenshot using wxGraphicsContext

Post by saranya » Mon Apr 29, 2019 9:32 am

doublemax wrote:
Fri Apr 26, 2019 8:45 am
So your code can already render into a wxMemoryDC. Why don't you do that and forget about wxClientDC?

Or are you saying that the problem also occurs when rendering directly into a wxMemoryDC? In that case, please provide a minimal compilable sample that shows the issue.
I tried to Upload sample Solution(Zip file) containing 30MB which illustrates the Issue. I am unable to attach the file .It is showing an error message (HTTP Error)

Kvaz1r
Earned some good credits
Earned some good credits
Posts: 129
Joined: Tue Jun 07, 2016 1:07 pm

Re: Issue in Capturing Screenshot using wxGraphicsContext

Post by Kvaz1r » Tue Apr 30, 2019 6:20 am

I tried to Upload sample Solution(Zip file) containing 30MB which illustrates the Issue. I am unable to attach the file .It is showing an error message (HTTP Error)
You can load it on Github or something. But why it contains 30MB?

Post Reply