Measurement Studio for VC++

cancel
Showing results for 
Search instead for 
Did you mean: 

how to get a bitmap from CNiGraph in VC++

I want to get bitmap of measurement graph control somthing like the CVI function GetCtrlBitmap in VC++.
I tried m_Graph.Images("Plot Area"), no function in CNiImage class to get bitmap, the same case for the CNiPicture class.
 
 
0 Kudos
Message 1 of 8
(6,818 Views)

You can use the CNiGraph::ControlImage method, which will return a metafile of the graph.

- Elton

0 Kudos
Message 2 of 8
(6,805 Views)
CNiGraph::ControIImage will return a CNiPicture object, the peoblem is I want save a bitmap file which contain the image of the graph control on disk. I found no class method in CNiPicture can achieve this.
0 Kudos
Message 3 of 8
(6,803 Views)

The CNiPicture that is returned from CNiGraph::ControlImage wraps an enhanced metafile. The handle to the metafile is provided by the CNiPicture::Handle property. Therefore, you can create a bitmap and then play the metafile to the bitmap. For example, add the following to your stdafx.h:

#include "atlimage.h"

Assuming that you have a CNiGraph variable called graph, the following code will create a bitmap of the graph and save it to a .bmp file in the root directory of your C: drive called graph.bmp:

// Determine dimensions of the control.
RECT controlBounds;
graph.GetClientRect(&controlBounds);
int bmpWidth = controlBounds.right - controlBounds.left;
int bmpHeight = controlBounds.bottom - controlBounds.top;

// Create the bitmap with the same dimensions of the control.
CImage bmp;
bmp.Create(bmpWidth, bmpHeight, 24);

// Play the enhanced metafile from the CNiPicture to the bitmap.
RECT imageBounds = { 0, 0, bmpWidth, bmpHeight };
CNiPicture controlImage = graph.ControlImage();
HDC bmpDC = bmp.GetDC();
::PlayEnhMetaFile(bmpDC, reinterpret_cast<HENHMETAFILE>(controlImage.Handle), &imageBounds);
bmp.ReleaseDC();

// Save bitmap to a .bmp file.
bmp.Save(_T("C:\\graph.bmp"));

Hope this helps.

- Elton

Message 4 of 8
(6,779 Views)

Wonderful!

It works. Thanks a lot! I got the whole image of the graph control.

I would like to get only the plot area or in another word except the graph boundary.

So I do following:

CNiImage image = m_Graph.Images("Plot Area");

CNiPicture picture;

picture = image.GetPicture();

int iWidth, iHeight;

iWidth = picture.GetWidth();

iHeight = picture.GetHeight();

CImage NewImage;

NewImage.Create(picture.GetWidth(), picture.GetHeight(), 24);

RECT imageBounds = {0, 0, picture.GetWidth(), picture.GetHeight()};

HDC bmpDC;

bmpDC = NewImage.GetDC();

::PlayEnhMetaFile(bmpDC, reinterpret_cast<HENHMETAFILE>(picture.GetHandle()), &imageBounds);

NewImage.ReleaseDC();

NewImage.Save("F:\\2.bmp");

problem happens since line 5: iWidth = picture.GetWidth();

iWidth is always 0, seems no picture information exist inside. Does Ni Class really support getting a picture from plot area?

0 Kudos
Message 5 of 8
(6,770 Views)
one more question,
in visual studio .net there is such a CImage class but not in visual studio 6. So what can I do with visual studio 6?
0 Kudos
Message 6 of 8
(6,769 Views)

Getting the plot area image from the Images collection really means the image for the plot area background. You're getting an image with a width of 0 because you haven't specified a plot area background image. There's not a way to get an image of just the plot area with the plot area background, plots, cursors, annotations, etc.

- Elton

0 Kudos
Message 7 of 8
(6,741 Views)

For Visual C++ 6.0, I would recommend updating to a recent Platform SDK to get the GDI+ C++ API. To create a bitmap from a graph with the GDI+ C++ API, first add this to your stdafx.h:

#include "gdiplus.h"
using namespace Gdiplus;
#pragma comment(lib, "gdiplus.lib")

Next, add the GetEncoderClsid helper function from the MSDN article Retrieving the Class Identifier for an Encoder to your project. Once you've updated the stdafx.h and added the GetEncoderClsid helper function to your project, the following example demonstrates how to do the equivalent of the previous example with the GDI+ C++ API:

// Determine dimensions of the control.
RECT controlBounds;
graph.GetClientRect(&controlBounds);
int bmpWidth = controlBounds.right - controlBounds.left;
int bmpHeight = controlBounds.bottom - controlBounds.top;

// Start GDI+
ULONG_PTR gdiPlusToken;
GdiplusStartupInput gdiPlusStartupInput;
::GdiplusStartup(&gdiPlusToken, &gdiPlusStartupInput, NULL);

// Define a scope so that GDI+ objects will get cleaned-up before
// GdiplusShutdown is called.
{
    // Create the bitmap with the same dimensions of the control.
    Bitmap bmp(bmpWidth, bmpHeight);

    // Create a GDI+ Metafile object for the enhanced metafile returned
    // by CNiGraph::ControlImage.
    CNiPicture controlImage = graph.ControlImage();
    Metafile controlMetafile(reinterpret_cast<HENHMETAFILE>(controlImage.Handle));

    // Draw the metafile to the bitmap with the control dimensions.
    std::auto_ptr<Graphics> pGraphics(Graphics::FromImage(&bmp));
    pGraphics->DrawImage(&controlMetafile, 0, 0, bmpWidth, bmpHeight);

    // Get the encoder CLSID for bitmaps.
    CLSID bmpClsid;
    ::GetEncoderClsid(L"image/bmp", &bmpClsid);

    // Save the bitmap to a file with the bitmap encoder CLSID.
    bmp.Save(L"C:\\graph.bmp", &bmpClsid);
}

// Shutdown GDI+
::GdiplusShutdown(gdiPlusToken);

- Elton

0 Kudos
Message 8 of 8
(6,741 Views)