Victor Image Processing Library How-to Tips

Create an ActiveX with the Victor Library and use ASP to create and deliver an image




The image created by sendimage.asp

To access Victor Library functions from an Active Server Page (ASP) running on a Windows NT/2000 web server we create an ActiveX dll using Visual Basic (victorAXdemo.dll) or C/C++ (victorAXdemovc.dll). And an ASP page, sendimage.asp or sendimagevc.asp delivers the JPEG image to the browser with a Response.BinaryWrite.

The ActiveX dll, creates a graphic image from the text string, "hello," saves it to a JPEG file format stored in memory, and delivers it on demand to the ASP page.

The sequence of Victor functions in the ActiveX dll is:

    allocimage(myimage, 325, 140, 8)  ' Create the image (325 x 140, 8-bit grayscale)
    zeroimage(255, myimage)           ' Give it a white background
    textinimage myimage, "hello"      ' Put the text string into the image
    savejpgtobuffer(bufferaddress, myimage, 50) ' Put the image into JPEG form in a buffer
In the ASP page the JPEG data are the assigned to the jpegbuffer property for easy delivery from the ASP page to a browser.

VB Source Code | C/C++ Source Code

Download the VB source code and corresponding ASP page for this example: vicaxdemo.zip (11 kb)

Create an ActiveX dll that delivers a JPEG from memory, the VB source code

In this dll we create an image and place it in memory as JPEG data. Requires Victor Image Processing Library for 32-bit Windows v 5.3 or higher.
' Definitions and declarations 
' Image descriptor
Type imgdes
   ibuff As Long
   stx As Long
   sty As Long
   endx As Long
   endy As Long
   buffwidth As Long
   palette As Long
   colors As Long
   imgtype As Long
   bmh As Long
   hBitmap As Long
End Type
Private Const NO_ERROR = 0
' Victor Library functions
Private Declare Function allocimage Lib "VIC32.DLL" (image As imgdes, ByVal wid As Long, ByVal leng As Long, ByVal BPPixel As Long) As Long
Private Declare Sub freeimage Lib "VIC32.DLL" (image As imgdes)
Private Declare Function savejpgtobuffer Lib "VIC32.DLL" (ByRef buffaddr As Long, srcimg As imgdes, ByVal quality As Long) As Long
Private Declare Function zeroimage Lib "VIC32.DLL" (ByVal level As Long, image As imgdes) As Long
' Windows API functions
Private Declare Function GlobalHandle Lib "kernel32" (ByVal Addr As Long) As Long
Private Declare Function GlobalSize Lib "kernel32" (ByVal hMem As Long) As Long
Private Declare Function GlobalFree Lib "kernel32" (ByVal hMem As Long) As Long
Private Declare Sub RtlMoveMemory Lib "kernel32" (ByVal des As Long, ByVal src As Long, ByVal cnt As Long)
Private Declare Sub Copyjpegtobytearray Lib "kernel32" Alias "RtlMoveMemory" (ByRef des As Byte, ByVal src As Long, ByVal cnt As Long)
' Properties
Private jpeginmemory() As Byte
Private buffersize As Long
Public Property Get jpegbuffer() As Byte()
   jpegbuffer = jpeginmemory
End Property
Public Property Get bsize() As Long
   bsize = buffersize
End Property
' The function deliverjpeg does all the work
Public Function deliverjpeg() As Long
Dim rcode As Long
Dim myimage As imgdes
Dim bufferaddress As Long
Dim buffhandle As Long
    rcode = allocimage(myimage, 325, 140, 8)  ' Create the image
    
    buffersize = 0
    
    If (rcode = NO_ERROR) Then
        rcode = zeroimage(255, myimage) ' White background
        textinimage myimage, "hello"    ' Put the text string into the image
        
        rcode = savejpgtobuffer(bufferaddress, myimage, 50) ' Put the image into JPEG form in a buffer
        freeimage myimage  ' Free the image
        If (rcode = NO_ERROR) Then
            buffhandle = GlobalHandle(bufferaddress)
            buffersize = GlobalSize(buffhandle)
            ReDim jpeginmemory(0 To buffersize) As Byte  ' Allocate a byte array to hold the JPEG data
            Copyjpegtobytearray jpeginmemory(0), bufferaddress, buffersize  ' Copy the JPEG data to a byte array
            rcode = GlobalFree(buffhandle)  ' Free the original JPEG buffer
        End If
    End If
    
    deliverjpeg = rcode
End Function
Public Function releasejpeg() As Long
   ReDim jpeginmemory(0 To 0) As Byte  ' Release the byte array holding the JPEG data
   releasejpeg = 0
End Function
Private Sub textinimage(timage As imgdes, caption As String)
            ' textinimage function source is not shown here 
   ' but is in zipped source file vicaxdemo.zip
End Sub


The ASP page delivers the JPEG image to the browser, the source code

<html>
<head>
<title>Sendimage.asp: Victor Library creates and delivers a jpeg image to browser</title>
</head>
<body>

<!---
This is a demonstration of ASP access to the Victor Library through an ActiveX control created with Visual Basic
    
Put sendimage.asp and victoraxdemo.dll together in the same directory on the server.
Register victoraxdemo.dll using regsvr32.exe
Put vic32.dll into the windows/system directory on the server. 
(An eval copy of vic32.dll is available at http://www.catenary.com/download/vic5e.html)   
For more info about the Victor Library visit www.catenary.com
--->

<%
   Dim vt           ' the class "victest1"
   Dim rcode        ' the value returned from a function call in victest1
   dim vicjpegimage ' jpeg buffer 
   
      Set vt = Server.CreateObject("victorAXdemo.victest1")
      
      rcode = vt.deliverjpeg()  ' Create the JPEG data 
      vicjpegimage = vt.jpegbuffer  ' Get the JPEG data 
      Response.Expires = 0
      Response.Buffer = true
      Response.Clear
      Response.ContentType = "image/jpeg"
      Response.BinaryWrite(vicjpegimage)  ' Send the JPEG data to the browser
      Response.End
      
      rcode = vt.releasejpeg()   ' Release the memory
%>
</body>
</html>


Download the C/C++ source code and corresponding ASP page for this example: vicaxdemovc.zip (19 kb)

Create an ActiveX dll that delivers a JPEG from memory, the C/C++ source code

In this dll we create an image and place it in memory as JPEG data. Requires Victor Image Processing Library for 32-bit Windows v 5.3 or higher.
// victest1.cpp : Implementation of Cvictest1
#include "stdafx.h"
#include "atlbase.h"
#include "VictorAXdemoVC.h"
#include "victest1.h"
#include <vicdefs.h>
void textinimage(imgdes *timage, char *caption);
            /////////////////////////////////////////////////////////////////////////////
// Cvictest1
// Global variables
int Buffersize = 0;
UCHAR *Bufferaddress;
VARIANT Jpeginmemory;
STDMETHODIMP Cvictest1::deliverjpeg()
{
   int rcode;
   imgdes myimage;  
   HGLOBAL buffhandle;
   SAFEARRAYBOUND  rgsabound[1];
    rcode = allocimage(&&myimage, 325, 140, 8);
    Buffersize = 0;
    
    if (rcode == NO_ERROR) {
        zeroimage(255, &myimage);  // White background
        textinimage(&myimage, "hello");
        rcode = savejpgtobuffer(&Bufferaddress, &myimage, 50);
        freeimage (&myimage);
        if (rcode == NO_ERROR) {
            buffhandle = GlobalHandle(Bufferaddress);
            Buffersize = GlobalSize(buffhandle);
            if (Buffersize > 0) {
               VariantInit(&Jpeginmemory);
               Jpeginmemory.vt = VT_ARRAY | VT_UI1;
               rgsabound[0].cElements = Buffersize;
               rgsabound[0].lLbound = 0;
               Jpeginmemory.parray = SafeArrayCreate(VT_UI1,1,rgsabound);
               if(Jpeginmemory.parray != NULL) {
                  void * pArrayData = NULL;
            //Get a pointer to beginning of data area in Jpeginmemory
                   SafeArrayAccessData(Jpeginmemory.parray,&pArrayData);
            //Copy jpeg data to it
                   memcpy(pArrayData, Bufferaddress, Buffersize);
                   GlobalFree(buffhandle);
            //Unlock the data
                   SafeArrayUnaccessData(Jpeginmemory.parray);
                   }
                rcode = S_OK;    // S_OK same as NO_ERROR
                }
         else
            rcode = S_FALSE;
           }
       }
    return (rcode);
}
STDMETHODIMP Cvictest1::releasejpeg()
{
   if(Buffersize > 0) {
      VariantClear(&Jpeginmemory);
      return (S_OK);
      }
   else
      return (S_FALSE);
}
STDMETHODIMP Cvictest1::get_jpegbuffer(VARIANT *pVal)
{
   
   if(Buffersize > 0) {
      *pVal = Jpeginmemory;  
      return (S_OK);
      }
   else
      return (S_FALSE);
}
STDMETHODIMP Cvictest1::get_jpegsize(VARIANT *pVal)
{
    CComVariant bsize((long)Buffersize);
   
   *pVal = bsize;
    return (S_OK);
}
void textinimage(imgdes *timage, char *caption)
{
   static LOGFONT lf = {  // Use font described by LOGFONT struct
   0, 0, 0, 0, FW_HEAVY, 0, 0, 0,
   ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
   DEFAULT_QUALITY, DEFAULT_PITCH | FF_SWISS, "ARIAL"
   };
   HANDLE hFont, hOldFont;
   HANDLE hOldBitmap;
   HWND hWnd;
   HDC hdc, hMemDC;
   RECT rc; 
   int captionHt, captionWd, imageareaHt, imageareaWd;
   int rcode;
  
   lf.lfHeight = 100;
   
   hWnd = GetActiveWindow();
   hdc = GetDC(hWnd);
   hMemDC = CreateCompatibleDC(hdc);
   hFont = CreateFontIndirectA(&lf);  // Create our font
   SetBkMode(hMemDC, TRANSPARENT);
   hOldFont = (HANDLE)::SelectObject(hMemDC, hFont);  // Select font into DC
            // Don't write any text, just fill rc with text dimensions
   DrawText(hMemDC, caption, -1, &rc, DT_CALCRECT | DT_LEFT | DT_EXPANDTABS | DT_NOPREFIX);
            // Calculate the text size
   captionHt = rc.bottom - rc.top + 1;
   captionWd = rc.right - rc.left + 1;
   
            // Calculate image area size
   imageareaHt = timage->endy - timage->sty + 1;
   imageareaWd = timage->endx - timage->stx + 1;
   
            // Set the rect for adding the text
            // Center text in image if text is smaller than image area
   SetRect(&rc, 0, 0, timage->endx, timage->endy);
   if (captionHt < imageareaHt) 
    rc.top = (imageareaHt - captionHt) / 2;
   if (captionWd < imageareaWd) 
    rc.left = (imageareaWd - captionWd) / 2;
 
            // Select image into the memory DC
   hOldBitmap = (HANDLE)::SelectObject(hMemDC, timage->hBitmap);
            // Write the text
   rcode = ::DrawText(hMemDC, caption, -1, &rc, DT_LEFT | DT_EXPANDTABS | DT_NOPREFIX);
            // Restore the original bitmap and font and delete the new font
   SelectObject(hMemDC, hOldBitmap);
   DeleteObject (SelectObject(hMemDC, hOldFont));
   DeleteDC (hMemDC);         // Delete memory DC
   ReleaseDC(hWnd, hdc);
}


The ASP page delivers the JPEG image to the browser, the source code

<html>
<head>
<title>Sendimagevc.asp: Victor Library creates and delivers a jpeg image to browser</title>
</head>
<body>

<!---
This is a demonstration of ASP access to the Victor Library through an ActiveX control created with C/C++
    
Put sendimagevc.asp and victoraxdemovc.dll together in the same directory on the server.
Register victoraxdemovc.dll using regsvr32.exe
Put vic32.dll into the windows/system directory on the server. 
(An eval copy of vic32.dll is available at http://www.catenary.com/download/vic5e.html)   
For more info about the Victor Library visit www.catenary.com
--->

<%
   Dim vt           ' the class "victest1"
   Dim rcode        ' the value returned from a function call in victest1
   dim vicjpegimage ' jpeg buffer 
   
      Set vt = Server.CreateObject("victorAXdemovc.victest1")
      
      rcode = vt.deliverjpeg()  ' Create the JPEG data 
      vicjpegimage = vt.jpegbuffer  ' Get the JPEG data 
      Response.Expires = 0
      Response.Buffer = true
      Response.Clear
      Response.ContentType = "image/jpeg"
      Response.BinaryWrite(vicjpegimage)  ' Send the JPEG data to the browser
      Response.End
      
      rcode = vt.releasejpeg()   ' Release the memory
%>
</body>
</html>
Victor Image Processing Library

Victor Image Processing Library homepage | Victor Product Summary | more source code




Copyright © 2001 Catenary Systems Inc. All rights reserved. Victor Image Processing Library is a trademark of Catenary Systems.