Dynamically generating images in ISAPI extension using GDI+ with live demo






3.88/5 (8 votes)
Oct 2, 2002
2 min read

65874

425
A class wrapper to write GDI+ images to the client browser using an ISAPI extension.
Introduction
Ever wanted to generate "on the heap" images on your web server and send them to the client? It is now possible to do it in your ISAPI extension in just 2 lines of code (well almost).
In fact, this article presents a helper class, to be used in an MFC ISAPI extension that writes GDI+ images to the client browser. All you have to do is to load or generate the GDI+ image!
Requisites
In this article I will suppose that:
- The reader has basic knowledge of GDI+. Here are some nice introductory articles on the CodeProject on this topic: GDI+ section.
- The reader has basic knowledge of MFC ISAPI extension. Here are some nice introductory articles on the CodeProject on this topic:
- What an ISPAPI extension is? by Mehdi Mousavi
- Discover ISAPI. Working with GET-POST data by Adrian Bacaianu
Rendering pipe
The rendering pipe is encapsulated in the WriteImage
function:
Note that with this method, there is no need to create temporary files on disk since they are directly written to the memory (hGlobal
).
Using CGDIpISAPI
Basic use
The use of the class is straight forward: build a CGDIpISAPI
object and call WriteImage
:
void CHttpServerDerviedClass::Default( CHttpServerContext* pCtxt) { // GDI+ namespace using namespace Gdiplus; // creating bitmap Bitmap bitmap(320,200); // drawing on this bitmap ... // sending bitmap to the browser CGDIpISAPI renderer( this, pCtxt, &bitmap ); // sending image renderer.WriteImage(); }
Output options
You can choose the image type (PNG, JPEG, BMP or TIFF). There is an enum
for the available codecs. You can also customize the quality for the PNG and JPEG files. It must be between 0 and 100.
All these options can be set at the construction or by setters.
- Setting BMP type
renderer.SetImageType( CGDIpISAPI::ImageBMP);
- Changing quality
renderer.SetQuality( 98 );
Initializing GDI+
Do not forget to initialize and de-initialize GDI+. I'm using a helper class for that: CGDIpInitializer
. It's use is self-explaining.
// extension declaration class CMyExtension : public CHttpServer { ... CGDIpInitializer m_GDIpInitializer; }
BOOL CMyExtension::GetExtensionVersion(HSE_VERSION_INFO* pVer)
{
CHttpServer::GetExtensionVersion(pVer);
// Initialize GDI+
m_GDIpInitializer.Initialize();
...
}
BOOL CMyExtension::TerminateExtension(DWORD dwFlags)
{
// Shutting down GDI+
m_GDIpInitializer.Deinitialize();
...
}
What not to do...
- When writing an image, do not write any text... So forget about
StartContent
,EndContent
,WriteClient
, etc...
Demo project
The demo projects is a MFC ISAPI extension (for VC7) that illustrates different options of CGDIpISAPI
. Note that you also use this class in VC6.
You can test all the features by viewing the test.html file. Of course, before that you must compile the project, put the DLL in your script directory, etc... Below is a screenshot of the output of test.htm:
Reference
Update history
- 4 October 2002
- Fixed a small bug in the
CGDIpISAPI
class (was always exporting as JPEG)
- Fixed a small bug in the