Victor Library User's Guide
Getting Started
System Requirements
The Victor Image Processing Library and the device support modules are Dynamic Link Libraries (DLLs) and your programming environment must be able to produce an application capable of calling functions contained in a DLL.
The Victor Image Processing Library for 32-bit Windows requires the presence of Windows NT/2000/XP or Windows 9x /ME.
Desktop Applications: A 32-bit programming language (for example, C/C++, C#, VB6, VB.NET) is required to create a 32-bit Victor desktop application.
Online Server Applications: A 32-bit Windows server supporting ASP.NET (programming in C# or VB.NET) is required to create a 32-bit Victor internet application that can be run by users using any browser.
Registration
Please fill out the online registration card.
Software Installation
Unzip all the downloaded files and place them in a new directory named \vicwin32 .
For use with Visual Basic place VIC32.DLL and VICTW32.DLL in the subdirectory with the VB executable program, vb5.exe or vb6.exe. It is not necessary to register the Victor Library. It is not a COM object. It is not an ActiveX control.
For use with VB.NET place VIC32.DLL and VICTW32.DLL in the \bin subdirectory under the application you are creating. It is not necessary to register the Victor Library. It is not a COM object. It is not an ActiveX control.
Double click on VicDemo.exe to run the VicDemo demonstration program.
Victor Features
The Victor Image Processing Library for Windows can be used to create applications for working with images in the Microsoft Windows environment.
Capabilities that can be built into a Windows desktop or web server application by using the Victor Library include:
- Load and save BMP/GIF/JPEG/PCX/PNG/TGA/TIFF file formats
- Powerful image processing of grayscale and color images
- Combining and comparing images
- Changing an image's size and orientation
- Color reduction and promotion to change pixel depth of images
- Image analysis using histograms, correlations, and sorting of pixel data
- Easy display and scrolling of images
- Print single or multiple images on a page
- Support for TWAIN compliant devices for image capture
- Unicode support
These features are described in the pages that follow. The implementation is straightforward and easily accomplished by reading the function description and following the examples.
How to Use this Manual
Begin this manual by loading viclibquide.html into your browser.
This manual was written with the assumption that you are generally familiar with Windows programming. Good elementary Windows programming texts are Programming Windows 95, by Charles Petzold, Microsoft Press 1996 and Advanced Windows NT , by Jeffrey Richter, Microsoft Press 1994.
The first section of this manual is the User's Guide and provides information necessary to successfully incorporate Victor functions into Windows programs. It should be read and understood.
The second section is the Library Reference which begins in viclibref-a-c.html. This reference contains detailed information about all Victor functions.
The Return Codes list contains the summary of function return codes and the Data Types list contains all the user-defined data structures used by the library.
Additional Versions of the 32-bit Library
The standard Victor Library is a DLL that is dynamically linked to your application at run time.
The Victor Library for 32-bit Windows is also available as a static link library. This static library is a form of the Victor Library that is a linkable library for including victor functions in your own C/C++ executable ActiveX or application file. The advantage of using this form of the library is that there is no need to distribute a Victor DLL with your app and only those functions that you actually use will be included in your program.
Contact Catenary Systems for information about this option.
Demonstration Programs
The Victor Library demonstration programs include the source code for C#, Visual Basic, VB.NET, ASP.NET, Java, and C/C++ desktop and web server applications that run under 32-bit Windows. To download the latest example programs visit
www.catenary.com
Free Downloads
Apps & Extras
VicImager, VB ASP.NET
The advanced image processing application VicImager demonstrates the use of the Victor Library on a remote server for fast and easy image processing. Source code for VicImager is included with purchase of the Victor Library.
Other aspx demo programs with source code are Image Cropping, Simple Image Processing, and Select Process.
Tiffpageview, C# ASP.NET
Tiffpageview is a C# .NET server application accessing the Victor Library through the viclib namespace. Use this app to load and display any page from a tiff multipage file.
Comparator, C#
Comparator is a C# .NET MDI desktop application accessing the Victor Library through the viclib namespace. Use this app to combine, compare, and analyze multiple images.
Vicnet1, VB.Net
Vicnet1 is a VB.NET desktop application to load, save, display, scan, print images.
Loadpic, VB6
Loadpic is a Visual Basic program to load and save, display, and print an image. It also includes Twain support to select a source and capture an image. Loadpic allows you to load and save bmp, gif, jpeg, png, and tiff files. It will automatically convert between file types as necessary.
This is the first program you should create using Visual Basic and the Victor Library to make sure VB can find all the necessary components.
Place the VIC32.DLL and VICTW32.DLL in the subdirectory with the VB executable program, vb6.exe.
LoadNSho, C/C++
LoadNSho is a simple program to load and display a single image. This is the first program you should compile using your C compiler and the Victor Library to make sure the compiler can find all the necessary components. Project files are included for Microsoft and Borland compilers.
VicDemo, C/C++
VicDemo is a fully functional image processing program that can be used for scanning, printing, file conversion, and enhancing images.
VicDemo illustrates some of the features and functions available in the Victor Library, and provides practical examples of using Victor functions. It should be used as a guide in calling Victor routines in your applications.
For information about the VicDemo commands and image processing tips and techniques select the Help command. VicDemo has an extensive Help system describing the program and the library.
VicDemo is a multi-module program. The source code is provided. Refer to the project file to compile the modules and link the program.
Programming Considerations
Your application can call Victor functions as easily as it calls Windows functions, because the Victor Library for Windows is a dynamic link library (DLL).
Dynamic Link Libraries
DLLs contain the Victor functions called by your application during execution. The image handling functions are in a single DLL, VIC32.DLL. Additional functions for special processing and analysis are contained in VICFX.DLL and VICSTATS.DLL. To download these visit the website www.catenary.com .
TWAIN and support functions are contained in VICTW32.DLL. This DLL is only necessary if your application includes TWAIN device support.
| Victor 32-bit library | Contains |
| VIC32.DLL | Image processing & file load/save |
| VICFX.DLL | Additional multi-image processing |
| VICSTATS.DLL | Image analysis |
| VICTW32.DLL | TWAIN support |
Namespace File
The namespace file VICLIB.DLL is used for .Net programming with VB or C#. VICLIB.DLL is the interface into the Victor Library dlls.
Include Files
The include files are used when programming directly into the Victor Library dlls. These files contain function declarations, data structure definitions, and error codes for different programming languages.
| Language | Include file |
| ASP.NET | VICDEFS.ASPX |
| C# | VICDEFS.CS |
| C/C++ | VICDEFS.H |
| VB6 | VICDEF32.BAS |
| VB.NET | VICDEF32.VB |
Import Libraries
Import libraries are used with the C/C++ programming language only. The import library is linked to your application at compilation time and relates function calls to actual entry points in the corresponding DLL.
| Victor 32-bit import library | Corresponding DLL |
| VIC32MS.LIB | VIC32.CLL |
| VICFXMS.LIB | VICFX.CLL |
| VICSTATSMS.LIB | VICSTATS.CLL |
| VCTW32MS.LIB | VICTW32.DLL |
Creating an ASP.NET Application
The Victor Library functions are accessed through the viclib namespace.
Place the viclib.dll, vic32.dll, vicfx.dll, and vicstats.dll in the \bin subdirectory of your application.Follow these steps to create your application:
-
Add the Victor Library namespace, viclib.dll, to your project.
Project- Add Reference
- Browse ...
- viclib.dll (files of type *.dll)
-
At the top of your aspx page place
<%@ import namespace="viclib" %>
- Write your application with Victor function calls. Use Victor functions just as if they were defined in your program. Place the "vicwin." prefix on every function call.
- Create your application as you normally would to create an ASP.NET application. You will probably create three aspx files: a source file with the user interface and event handlers, a viewer file for displaying an image, and global.asax for keeping global variables.
- See http://catenarysystems.com/tiffpageview.aspx for a simple C# .NET server application accessing the Victor Library through the viclib namespace. Use this app to load and display any page from a tiff multipage file.
Creating a VB.NET Desktop Application
The Victor Library functions are accessed through the viclib namespace.
Follow these steps to create your application:
- Place viclib.dll, vic32.dll (commercial release or eval version), vicfx.dll, vicstats.dll, and victw32.dll into your application \bin directory.
- Write your application with Victor function calls. Use Victor functions just as if they were defined in your program. Place the "vicwin." prefix on every function call.
- Add the Victor Library namespace to your project:
Project-
Add Reference
-
Browse ...
-
viclib.dll (files of type *.dll)
- Insert the Imports directive at the top of your source code files:
Imports viclib
Creating a C# Desktop Application
The Victor Library functions are accessed through the viclib namespace.
Follow these steps to create your application:
- Place viclib.dll, vic32.dll (commercial release or eval version), vicfx.dll, vicstats.dll, and victw32.dll into your application \bin directory.
- Add the Victor Library namespace to your project:
Project-
Add Reference
-
Browse ...
-
viclib.dll (files of type *.dll)
- Write your application with Victor function calls. Use Victor functions just as if they were defined in your program. Place the "vicwin." prefix on every function call.
- Insert the using directive at the top of your source code files:
using viclib;
Creating a C/C++ Application
There are three Victor Library components necessary for creating a C/C++ application: dynamic link libraries, import libraries, and the header file, VICDEFS.H .
Follow these steps to create your application:
- Write your program with Victor function calls. Use Victor functions just as if they were defined in your program.
- Include the Victor header file, VICDEFS.H, in each source module that calls a Victor function.
- Create any resource (RC) and module definition (DEF) files necessary for your application. These files are not affected by the use of Victor Library functions.
- Create a project file and include all source, resource, module definition, and Victor import libraries as project elements. Or, if using command line compilation, list the Victor import library files after the Windows import library files on your link line.
- For the creation of a 32-bit Windows application, make sure that WIN32 is #defined in the project or make file.
- To create an app that supports Unicode #define UNICODE TRUE
- Compile and link your application as you normally would to create a Windows application.
For additional information on compiling and linking your application see the README.DOC file.
Creating a Visual Basic Application
Place the VIC32.DLL and any other required dlls in the subdirectory with the Visual Basic executable program, vb6.exe. Before creating your own application using Victor functions, run the LOADPIC sample. This will ensure that VIC32.DLL, VICTW32.DLL, and the source files can be found by VB. To run LOADPIC, start Visual Basic, load the project file LOADPIC, and choose Run Start.
Follow these steps to create your own application:
- Write your program with Victor function calls. Use Victor functions just as if they were defined in your program.
- Include VICDEF32.BAS as a module in your project.
- Create your application as you normally would to create a Windows application.
For additional information on compiling and linking your application see the VBREAD.DOC file.
Creating a Java Application
Create your app and at the top of the app source file insert
import vic.*;
To invoke a Victor function from a Java app precede the function name with the prefix "vic.vic32jni." Precede the definition of any Victor data structures with the prefix "vic."
Place the dlls:
-
vic32.dll in x:\java\bin
victw32.dll in x:\java\bin
vic32jni.dll in the same subdirectory as the application
javac -classpath x:\java myapp.java java -classpath x:\java;x:\java\vic myapp
For complete information on compiling and linking your application see the vic32jni.txt file.
Creating an App with Unicode Support
To create a C/C++ application with Unicode support place the following two lines at the top of each source file:
#include <tchar.h> #define UNICODE TRUE
(Normally, you would also #define _UNICODE TRUE for proper Unicode string handling in your app.)
This will cause the Unicode version of Victor functions to be used. If Unicode is defined it is not possible to use the ANSI version of a Victor function, the Unicode version will always be used.
Or you may call the Unicode version of the Victor function directly. The Unicode version of a Victor function has a "W" appended to the end of the function name. For example, bmpinfo takes an ANSI string as the first argument, and bmpinfoW takes a Unicode character string as the first argument.
Troubleshooting
Windows can be a difficult environment to program under. If you have problems using Victor functions in your application you may benefit from the following suggestions.
Make sure your application can find the Victor Library dlls.
- When using Visual Studio and .Net add a reference in your project to the viclib.dll by browsing to the directory where it resides.
- When using Visual Studio and C/C++ add the import libraries, vic32ms.lib and vctw32ms.lib, to your project browsing to the directory where they reside. Place the dlls in the directory with the application.
- When using VB6 place the dlls in the directory with VB6.EXE when developing your app. Place them in the directory with your app when compiling to the executable.
If a Victor function returns a value other than NO_ERROR or the function doesn't behave as you expect it to, examine the data being sent to the function.
Trace program execution and examine variables and Windows messages. Most problems result from incorrect data being passed to functions. Examine the contents of the image descriptor and make sure the element values are reasonable.
Several Victor Functions allocate memory for image buffers or file data buffers. Every allocimage() should be balanced with a freeimage() when done with the image and every savefiletobuffer() should be balanced with a freebuffer() so that excessive memory is not consumed by your application.
Technical Support
Visit the website http://www.catenary.com for more code examples of using Victor to accomplish various tasks:
http://www.catenary.com
Sample Code
If you need additional assistance using the Victor Library you may contact Catenary Systems for technical support during normal business hours 9 am to 5 pm (USA Central Time) Monday through Friday:
voice: (623) 285-9624
e-mail: support@catenary.com
url: www.catenary.com
Victor Images
Device Independent Bitmap (DIB) Review
Victor Library functions operate on an image stored in memory as an uncompressed Device IndependentBitmap (DIB).
The Microsoft Windows Programmer's Reference defines a DIB as follows:
"A Windows DIB consists of two distinct parts: a BITMAPINFO structure, which describes the dimensions and colors of the bitmap, and an array of bytes defining the pixels of the bitmap. The bits in the array are packed together, but each scan line must be zero-padded to end on a LONG boundary. Segment boundaries, however, can appear anywhere in the bitmap. The origin of the bitmap is the lower-left corner."
A DIB provides a uniform format for moving bitmaps between different devices. Windows uses a DIB to create a bitmap or display image data on a display device.
The DIB is composed of header, palette, and pixel data. There are two forms of DIB, the original packed DIB and the newer DIB Section. Victor functions operate on both types.
The original packed DIB format has all the image data together in a single contiguous block of memory. The packed DIB is used when a DIB is placed in the Windows clipboard and the data is referred to as type CF_DIB. This was the only type of DIB available in 16-bit Windows
The DIB Section is only available in 32-bit Windows and has the header and palette data in one memory location while the pixel data reside in another location. This DIB format also includes a bitmap handle that makes the DIB usable with the Windows graphics functions.
How Victor Images Differ from Windows DIBs
Victor functions operate on a subset of Windows DIBs. The differences lie in compression, bits per pixel, and palette.
- A Windows DIB may be compressed or uncompressed. Victor Library functions can operate only on an uncompressed DIB. This allows Victor functions to operate on any rectangular section of a DIB.
- Windows allows a DIB to have 1, 4, 8, 16, 24, or 32 bits per pixel. Victor functions can operate only on a DIB with 1, 8, or 24 bits per pixel. When an image file is opened, the pixel depth is used to automatically convert the image into 1, 8, or 24 bits per pixel.
- Windows allows the palette table of a DIB to be an array of unsigned integers that specify indexes into the currently realized logical palette. Victor does not. Victor requires explicit RGB values, not palette indexes. This lets Victor functions know the actual color associated with each pixel.
The Image Descriptor Defined
Victor's most important data structure is the image descriptor. All of the information necessary for a Victor function to operate on an image area is contained in the image descriptor data structure that describes that image. The image descriptor is defined in VICDEFS.H as type imgdes and is a required argument for most Victor functions. The image descriptor is defined as follows:
typedef struct {
unsigned char huge *ibuff; Image buffer address
unsigned stx, sty, endx, endy; Image area of interest
unsigned buffwidth; Image buffer width in bytes
RGBQUAD far *palette; Palette address
int colors; Number of palette colors
int imgtype; Image type: bit 0 = 1
if image is grayscale
BITMAPINFOHEADER far *bmh; BITMAPINFOHEADER address
HBITMAP hBitmap; Device Independent Bitmap handle
} imgdes;
The Elements of the Image Descriptor
- ibuff
- The ibuff element of the image descriptor holds the address of the image bits. The data is organized by rows of pixels beginning with the bottom row. Each row begins with the leftmost pixel and may be right-padded so the number of bytes in the row is a multiple of four.
- The format of the image data is dependent on bits per pixel contained in the BITMAPINFOHEADER element biBitCount. Bits per pixel refers to the number of bits necessary to represent the value of a single picture element. 1, 8, and 24 bits per pixel are supported by Victor functions.
- 1-bit images (bilevel or monochrome images) contain two colors, typically black and white. Each pixel is represented by 1 bit and each byte represents 8 pixels. The leftmost pixel is the most significant bit of the first byte. A 0 bit represents a pixel color given by the first entry in the palette, and a 1 bit represents a pixel color given by the second entry.
- 8-bit images (grayscale or palette color) contain up to 256 colors. Each pixel is represented by a single byte and can range from 0 to 255. The pixel value is an index into the 256 entries in the palette.
- 24-bit images (RGB) contain up to 16 million colors. Each pixel is represented by 3 bytes containing the relative intensities of blue, green, and red for that pixel. (Note that the byte order in an RGB pixel is blue, green, red.) A 24-bit image has no palette.
The origin of the bitmap is the lower-left corner. This means that the address ibuff
represents is the first pixel in the last row of image data as viewed on the
screen.
stx, sty, endx, endy
- Upper left and lower right corners of the image area of interest in pixels. (0,0) represents the upper left corner of the image as displayed on the screen. Unlike some Windows GDI functions, such as Rectangle, Victor functions process every pixel within the image area. Thus the processed area width and length are:
- area width = endx - stx + 1
-
area length = endy - sty + 1
- buffwidth
- Width of the image buffer in bytes. The buffer width is always a multiple of 4 to end on a LONG boundary, and is calculated:
- buffwidth = (image width * bitcount + 31) / 32 * 4
-
palette - The palette element contains the address of the palette data stored as an array of RGBQUADs. Each color is described by one RGBQUAD, defined in WINDOWS.H as:
- typedef struct tagRGBQUAD {
- BYTE rgbBlue;
- BYTE rgbGreen;
- BYTE rgbRed;
- BYTE rgbReserved;
- } RGBQUAD;
- colors
- Number of colors in the palette, dependent on bits per pixel:
| Bits per pixel | Maximum palette colors | |
|
|
1 | 2 |
|
|
8 | 256 |
|
|
16 | 0 |
|
|
24 | 0 |
-
For a 1-bit per pixel image, colors must be 0 or 2. Palette holds the address of the 2-member array of RGBQUADs (the array size is 8 bytes). -
For an 8-bit per pixel image, colors must be between 0 and 256. Palette contains the address of the 256-member array of RGBQUADs (the array size is 1024 bytes). -
For a 16- or 24-bit per pixel image, there is no palette data. Colors and palette are ignored by Victor functions. -
imgtype - Image type: bit 0 is set to 1 if the image is grayscale. This is used primarily when saving grayscale images. The remaining bits are not used.
- bmh
- Address of the BITMAPINFO and the BITMAPINFOHEADER structures. This is also used as the address of the DIB. The structures are defined in WINDOWS.H as:
typedef struct tagBITMAPINFO {
BITMAPINFOHEADER bmiHeader;
RGBQUAD bmiColors[1];
} BITMAPINFO;
typedef struct tagBITMAPINFOHEADER {
DWORD biSize;
DWORD biWidth;
DWORD biHeight;
WORD biPlanes;
WORD biBitCount;
DWORD biCompression;
DWORD biSizeImage;
DWORD biXPelsPerMeter;
DWORD biYPelsPerMeter;
DWORD biClrUsed;
DWORD biClrImportant;
} BITMAPINFOHEADER;
- hBitmap
-
The hBitmap element contains the handle to the device independent bitmap
(DIB). This element is used only in Victor for 32-bit Windows. hBitmap can
be used with Windows GDI functions for drawing on the DIB, displaying the DIB,
or whenever the handle to a bitmap is required.
A nonzero value of hBitmap indicates that the image is a DIB section. A value of zero indicates that the image is a packed DIB.
Using Victor Functions in a Windows Application
When working with images, a general procedure to follow is
- Allocate memory for the image
- Load the image
- Set the image area to be modified
- Modify the image area
- Display/save/print the image
- Free the image
Allocating Memory for an Image
To allocate an image buffer and assign the elements of an image descriptor, use the allocimage function. Allocimage allocates space for the image, including the header, palette, and image data.
Allocimage enters the correct values into the image descriptor and DIB header and the image buffer is ready to receive an image.
For example, to allocate space for a 8-bit image the following code can be used:
imgdes image1; // Define an image descriptor
int width=640, length=480; // Desired image buffer size (pixels)
int bppixel=8; // 8 bits per pixel
// Allocate space for the image
rcode = allocimage(&image1, width, length, bppixel);
// If allocimage() returns an error, handle it
. . .
// Ready to load an image
Loading and Saving an Image
After an image buffer has been allocated, a Victor loadfile function can be called to place the image in the buffer. For example, to load an 8-bit TIFF image into the previously allocated image buffer:
rcode = loadtif("CAR.TIF", &image1);
The Victor Library supports all the popular image file formats to load and save bilevel, grayscale, and color images. Table 1 lists the supported file formats and the corresponding Victor functions.
| Table 1. Image File Formats Supported by Victor | ||
| Format | Function | Description |
| BMP | loadbmp loadbmpfrombuffer savebmp |
loads 1-, 4-, 8-, 16-, 24-, and 32-bit saves 1-, 8-, and 24-bit |
| TIFF | loadtif
loadtiffrombuffer loadtifpage loadtifpagebyindex loadtifwithalpha savetif savetifpage savetiftobuffer |
loads 1-, 4-, 8-, 16-, 24-, and 32-bit
saves 1-, 8-, and 24-bit |
| EPS | saveeps | saves 8-bit |
| JPEG | loadjpg
loadjpgex loadjpgfrombuffer loadjpgfrombufferex loadjpgthumbnail loadjpgthumbnailfrombuffer savejpg savejpgex savejpgtobuffer savejpgtobufferex |
loads 8- and 24-bit
saves 8- and 24-bit |
| GIF | loadgif
loadgifframe loadgifframefrombuffer loadgiffrombuffer savegif savegifex savegifframe savegifframetobuffer savegiftobufferex |
loads 1- through 8-bit
saves 1- and 8-bit saves 1- through 8-bit |
| PCX | loadpcx
savepcx |
loads 1-, 4-, 8-, and 24-bit
saves 1- and 8-bit |
| PNG | loadpng
loadpngfrombuffer savepng savepngex savepngtobuffer |
loads 1-, 4-, 8-, 16-, 24-, and 32-bit
saves 1-, 8-, and 24-bit |
| BIF | loadbif
savebif |
loads 8-bit
saves 8-bit |
| TGA | loadtga
loadtgawithalpha savetga |
loads 8-, 16-, 24-, and 32-bit
saves 24-bit |
To determine the size of the image before loading and to allocate exactly the correct amount of space to hold the image use one of the fileinfo functions. For example for the TIFF image:
imgdes image1; // Define an image descriptor
TiffData tdat; // TIFF info data structure
int width, length; // Desired image size (pixels)
int bppixel ; // 8 bits per pixel
int rcode;
// Get image info on the file we're to load
rcode = tiffinfo(fname, &tdat);
if(rcode != NO_ERROR) {
MessageBox(hWnd,"Error in reading file", 0, MB_OK);
return(rcode);
}
width = tdat.width;
length = tdat.length;
bppixel = tdat.vbitcount;
// Allocate space for the image
allocimage(&image1, width, length, bppixel);
rcode = loadtif("CAR.TIF", &image1);
If (rcode == NO_ERROR)
// Image is in memory ready to display or process
To save an 8-bit TIFF image after processing:
rcode = savetif("NEWCAR.TIF", &image1, compression=0);
The Victor file functions automatically load and save any palette data along
with the image data.
Setting an Image Area
The coordinate system describing the image buffer places the origin, (0,0), at the upper left of the image as displayed on the computer screen. Victor functions require valid starting and ending coordinates that define the image area. The image area is defined by the image descriptor elements stx, sty, endx, and endy . All coordinates are in pixels.
Operations can be performed on any rectangular area within the image buffer. When an image buffer is allocated with allocimage, the allocation function sets the image area to include the entire image, that is:
- stx = 0,
- sty = 0,
- endx = bmh.biWidth - 1, and
- endy = bmh.biHeight - 1
A smaller image area can be set with the setimagearea or recttoimagearea functions. For example, to define an image area 100 x 200 within the image image1 starting at (0,0) use:
setimagearea(&image1, 0, 0, 99, 199);
To set an area based on values contained in a RECT structure:
SetRect(&rect, 0, 0, 99, 199); recttoimagearea(&rect, &image1);
Alternatively, the image area coordinates can be set with individual assignment statements:
image1.stx = 0; image1.sty = 0; image1.endx = 99; image1.endy = 199;
Modifying an Image with Victor Functions
Images may be modified using Victor image processing or manipulation functions. These functions require that source and result image descriptors be specified. The data of the source image is used to create the result image. Functions that combine two images to produce the result, like wtaverage, require an operator image descriptor as well. It is always the address of the image descriptor that is used as the argument to Victor functions.
Image data is read from the specified image area in the source buffer and written to the image area in the result buffer. If the same image descriptor can be used for both source and result, the source data will be replaced by the result data. For example, to sharpen an image and increase its brightness by 10 use:
sharpen(&image1, &image1); changebright(10, &image1, &image1);
If the source and result image areas overlap in memory (but are not identical),
the source data may be corrupted during an image processing operation by the
result data. In this case, first copy the source image area to the result image
area with the copyimage function. The copyimage function will
work correctly, even if the source and result areas overlap. Then process the
result image area.
Displaying an Image
When creating desktop apps using VB6, VB.NET, or C# the easiest way to disply an image is to put it into a PictureBox. The sample applications include the functions to display the image.
| Sample application functions to display an image | |
|---|---|
| C# | vicimagetoPicturebox(myimgdes, pictureBox1); |
| VB.NET | vicimagetopicturebox(vimage, PictureBox1) |
| VB6 | MainWnd.Picture1 = image_to_picturebox(vimage) |
Using C/C++ or other programming languages, you have to display the image
manually. A Victor image can be displayed easily with the viewimageex function.
For example, to view the image loaded from the TIFF file above:
HDC hDC; PAINTSTRUCT ps; HPALETTE hpal; hDC = BeginPaint(hWnd, &ps); /* Display the image beginning at (0,0) */ viewimageex(hWnd, hDC, &hpal, 0, 0, &image1,0,0,VIEWDITHER); EndPaint(hWnd, &ps);
The viewimageex function displays the image in the window and automatically uses color reduction if necessary. You can also specify the starting position for the image and the scroll positions.
-
VB programming: instead of calling viewimage, place the image into a VB
Picture Box by calling the image_to_picturebox function defined in the Victor
Library VB6 application loadpic.
Your program can also use viewimage or the Windows functions SetDIBitstoDevice, StretchDIBits, or CreateDIBitmap to display an image.
The viewimageex function automatically uses color reduction to display a
24-bit image on in a display mode limited to 256 or fewer colors. The color
reduction method will be one of the following defined constants:
| VIEWOPTPAL | creates an optimized palette | |
| VIEWDITHER | a fast ordered dither using a standard palette | |
| VIEWSCATTER | a diffusion scatter pattern using a standard palette |
Freeing an Image
Call freeimage to release memory associated with an image after the image is no longer needed. Failure to release memory may cause memory shortages. To release the memory associated with the image image1, use:
freeimage(&image1);
Range Checking
All functions that access an image buffer call the function checkrange_ to perform range checking. The source code for checkrange_ is included with the library in the module VICCORE.C. (All functions and variables that are used internally by Victor contain a trailing underscore as part of the name.)
If a range error occurs, the function returns BAD_RANGE (defined in VICDEFS.H). This indicates that one of the following conditions exists:
- An image dimension is out of range, either
- endx >= bmh->biWidth,
- endx >= XLIMIT, defined in VICDEFS.H,
- endy >= bmh->biHeight, or
- endy >= 32768
- Image buffer does not exist, either
- ibuff == 0, or
- bmh == 0
- Image width is larger than buffer width
- bmh->biWidth * bmh->biBitCount / 8 > buffwidth
If necessary, checkrange_ also reorders x and y coordinate data so that the starting position of an area is at upper left, and the ending position is at lower right.
Range checking also includes pointer validation to make sure the image buffer address passed to Victor functions is valid. That is, that the image buffer can be read and written. This should help catch uninitialized or corrupted image descriptors before they cause General Protection Faults or access violations. If checkrange_ determines that the image buffer address is invalid, a BAD_IBUF error code will be returned.
Color Palettes
What is a Color Palette?
In a 1- or 8-bit image, each pixel value is an index into a color lookup table -- the palette. The palette is arranged as an array of RGBQUADs, in which four bytes (blue, green, red, and reserved) represent each palette color. The byte values represent the relative intensities of blue, green, and red, and can range from 0 to 255.
For example, to access the components of an individual color, use the image descriptor element palette which points to the palette table.
red = image.palette[color_number].rgbRed; green = image.palette[color_number].rgbGreen; blue = image.palette[color_number].rgbBlue;
A 24-bit RGB image does not have a color palette since each pixel consists of blue, green, and red bytes that represent the color intensities.
Creating a Palette
Version 6.0 of the Victor Library introduces a new function to create a palette, makepalette. The makepalette function takes palette index values and the corresponding red, green, and blue intensities. These are defined in an array of PALETTEPOINT data structures. If you supply 256 elements you can explicitly define each palette entry. If you supply fewer elements the makepalette function will create a smooth gradation of color between the explicitly defined entries.
For example, to create a 256-level grayscale palette define the first palette entry with index zero and the last palette entry with index set to 255. The makepalette function will create all the entries in between:
PALETTEPOINT ppa[2]; int j; ppa[0].index = 0; ppa[0].red = 0; ppa[0].green = 0; ppa[0].blue = 0; ppa[1].index = 255; ppa[1].red = 255; ppa[1].green = 255; ppa[1].blue = 255; rcode = makepalette(&Image, ppa, 2);
Changing a Palette
Each red, green, or blue value can range from 0 (no intensity) to 255 (maximum intensity). To increase the red, green, or blue contribution of a color, add a quantity to the rgbRed, rgbGreen, or rgbBlue element of the corresponding RGBQUAD. For example, to increase by 20 the red contribution to color number 43:
red = image.palette[43].rgbRed; red = red + 20; if(red > 255) red = 255; image.palette[43].rgbRed = red;
With color palette images a quick method of brightening an image is to increase the intensity of the entire palette. To brighten an individual color add the same amount to the red, green, and blue components. To brighten an entire image add the same amount to the red, green, and blue components of every color in the palette.
For example, to brighten an image by 30:
void altermypalette(imgdes *image)
{
int j, red, green, blue;
for(j = 0; j < 256; j++) {
red = image->palette[j].rgbRed;
red = red + 30;
if(red > 255) red = 255;
image->palette[j].rgbRed = red;
green = image->palette[j].rgbGreen;
green = green + 30;
if(green > 255) green = 255;
image->palette[j].rgbGreen = green;
blue = image->palette[j].rgbBlue;
blue = blue + 30;
if(blue > 255) blue = 255;
image->palette[j].rgbBlue = blue;
}
}
Displaying an Altered Palette
In a C/C++ desktop application it is necessary to tell Windows that the palette has changed. To redisplay the image with the altered palette, use victowinpal to create a Windows logical palette. Then select the palette into the device context and realize the palette. A palette has to be "realized" for its color entries to be added to the system palette.
Modern programming languages like VB6, VB.NET, and C# do not require this "realization."
HPALETTE hpal; hDC = GetDC(hWnd); // Convert palette associated with image to a Windows palette victowinpal(&image, &hpal); // Select the palette into the DC and realize the palette holdpal = SelectPalette(hDC, hpal, 0); RealizePalette(hDC); // Deselect the palette before releasing DC SelectPalette(hDC, holdpal, 0); DeleteObject(hpal); ReleaseDC(hWnd, hDC);
Color Reduction: Creating a Palette Color Image from an RGB Image
A 24-bit RGB image can be converted to an 8-bit palette color image by several Victor functions. The main reason to use color reduction is to reduce the image storage requirements. Converting an image from 24-bit to 8-bit automatically reduces the image size to one-third of the original.
The choice of color reduction function depends upon your requirements for speed of execution, image quality, and ability to display multiple images at the same time. The Victor color reduction functions and performance estimates are listed in Table 2.
| Table 2. Color Reduction Functions | |||
| Function | Speed | Quality | Description |
| colordither(16)1 | very fast | fair | 16 standard colors |
| colordither(256)1 | very fast | good | 256 standard colors |
| colorscatter(16)1 | fast | fair | 16 standard colors |
| colorscatter(256)1 | fast | very good | 256 standard colors |
| matchcolorimage | good | varies based on palette specified | programmer specifies palette, uses error diffusion |
| matchcolorimageex 2 | good | varies based on palette specified | programmer specifies palette, error diffusion is optional |
| convertrgbtopal | good | excellent | creates optimum palette |
| convertrgbtopalex 2 | good | excellent | creates optimum palette, diffusion is optional |
| colortogray | fast | excellent | 256 shades of gray |
|
1 The numbers in parentheses refer to the size of the standard
palette. Refer to individual function descriptions in the Victor Library
Reference for additional information.
2 These functions allow you to specify the color matching method and whether or not error diffusion scatter is used. |
|||
To convert an RGB image into a palette color image with optimized palette and
save it as a TIFF file, use the following sequence:
// Allocate an 8-bit image
allocimage(&image8, (int)rgbimage.bmh->biWidth,
(int)rgbimage.bmh->biHeight, 8);
// Convert RGB to 8-bit image
convertrgbtopal(256, &rgbimage, &image8);
savetif("ANY.TIF", &image8, compression = 0); // Save the image
freeimage(&image8);
Where rgbimage is a 24-bit RGB color image and image8 is an 8-bit palette color image.
To convert an RGB image into a palette color image with an existing palette and save it as a TIFF file, use the following sequence:
// Allocate an 8-bit image
allocimage(&image8, (int)rgbimage.bmh->biWidth,
(int)rgbimage.bmh->biHeight, 8);
// Copy an existing palette to the new image
copyimagepalette(&anotherimage, &image8);
// Convert RGB to 8-bit image
matchcolorimage(&rgbimage, &image8);
savetif("NEW.TIF", &image8, compression); // Save the image
freeimage(&image8);
Where rgbimage is a 24-bit RGB color image, anotherimage is an existing image with the palette of interest, and image8 is an 8-bit palette color image.
DIBs, Bitmaps, and Images
Converting an Existing DIB to an Image
A device independent bitmap can be operated on by Victor functions if the DIB is Victor compatible and is described by an image descriptor. A Victor-compatible DIB is a DIB that is 1-, 8-, or 24-bits per pixel, uncompressed, and contains explicit RGB palette values.
To make a DIB Victor-compatible, select the function based on the type of DIB.
| DIB Description | Victor Library Function | |
| Victor-compatible packed DIB
1-, 8-, or 24-bits per pixel uncompressed RGB palette |
setupimgdes | |
| Any packed DIB | dibtoimage | |
| DIB section | dibsecttoimage |
Converting a Victor-compatible packed DIB
The setupimgdes function provides an easy way to enter the correct values into an image descriptor for a Victor-compatible DIB. For example, to save an existing DIB as a TIFF image directly from the clipboard, the following code can be used:
int SaveClippingasTiff(HWND hwnd, char *fname)
{
unsigned char huge *dib;
int rcode=NO_ERROR;
HGLOBAL hMem;
imgdes image;
OpenClipboard(hwnd); // Open clipboard
// Get DIB from clipboard
hMem = GetClipboardData(CF_DIB);
// Get address of DIB
dib = (unsigned char huge *)GlobalLock(hMem);
// Fill in an image descriptor for the Victor-compatible DIB
rcode = setupimgdes(dib, &image);
if(rcode == NO_ERROR)
rcode = savetif(fname, &image, 0);
if(hMem) // Unlock memory before closing the clipboard
GlobalUnlock(hMem);
CloseClipboard(); // Close the clipboard
return(rcode);
}
Converting any packed DIB
If a DIB is not Victor compatible (i.e., it is 4-bits per pixel or compressed), a Victor image has to be created from the DIB for Victor functions to operate on it. The dibtoimage function creates a Victor image based on any packed DIB.
In the following example, a new image is created and saved as a BMP file from a DIB on the clipboard.
int SaveClippingasBMP(HWND hwnd, char *fname)
{
unsigned char huge *dib;
imgdes image;
int rcode=NO_ERROR;
HGLOBAL hMem;
// Open clipboard
OpenClipboard(hwnd);
// Get DIB from clipboard
if(hMem = GetClipboardData(CF_DIB)) {
// Get address of DIB
dib = (unsigned char huge *)GlobalLock(hMem);
// Create a new image from the DIB
rcode = dibtoimage(dib, &image);
if(rcode == NO_ERROR) {
savebmp(fname, &image, 0);
// Free memory allocated by dibtoimage
freeimage(&image);
}
GlobalUnlock(hMem);
}
CloseClipboard();
return(rcode);
}
Converting a DIB Section
A DIB section is a Win 32 system object with an HBITMAP handle. To convert a DIB section into a Victor image use the dibsecttoimage function. For example, to save an existing DIB section as a TIFF file use the following:
int SaveDIBSectToTiffFile(HBITMAP hBitmap)
{
int rcode;
imgdes timage;
char *fname = "bitmap.tif";
rcode = dibsecttoimage(hBitmap, &timage);
if(rcode == NO_ERROR) {
// Save captured image
rcode = savetif(fname, &timage, 0);
freeimage(&timage);
}
return(rcode);
}
Converting a Device Dependent Bitmap to an Image
A device dependent bitmap is a Windows system object represented by a bitmap handle. Victor functions can operate on a device dependent bitmap only if it is first converted into a Victor image. Use the ddbtoimage function to create a Victor image. For example, to save a bitmap as a TIFF file use the following:
int SaveHBitmaptoTiffFile(HBITMAP hBitmap)
{
int rcode;
imgdes timage;
char *fname = "bitmap.tif";
HPALETTE hPal = 0;
rcode = ddbtoimage(hBitmap, hPal, &timage);
if(rcode == NO_ERROR) {
// Save captured image
rcode = savetif(fname, &timage, 0);
freeimage(&timage);
}
return(rcode);
}
In the above example, a palette handle is one of the arguments to ddbtoimage. By specifying zero for the palette handle the Windows system palette is used.
Converting a dot Net bitmap to a Victor Image
A dot Net bitmap is an object that holds image data and has its own functions for accessing the data. To prepare to copy the pixel data we use the bitmap functions to set the access to read and write, and to lock the bitmap while we access the data. Then simply copy the data into a Victor Image.
' Declaration of the copy function Declare Sub CopyBitmaptoVicImage Lib "kernel32" Alias "RtlMoveMemory" \ (ByVal des As Integer, Byval src As system.intptr, ByVal cnt As Integer) '''''''''''''''''''''''' ... '''''''''''''''''''''''' width = 400 length = 200 bpp = 24 ' Allocate a Victor Image rcode = allocimage(tempimage, width, length, bpp) ' Create a bitmap of the same dimensions bm = New bitmap(width, length) ' For this example fill the rect with green g1 = graphics.fromimage(bm) g1.fillrectangle(brushes.green, 0, 0, width, length) ' Lock the bitmap and get a pointer to the pixel data bmrect.width = width bmrect.height = length mode = imagelockmode.readwrite format = pixelformat.Format24bppRgb bmd = bm.lockbits(bmrect, mode, format) bitmapbuff = bmd.scan0 ' Copy pixel data from the bitmap to the Victor image CopyBitmaptoVicImage(tempimage.ibuff, bitmapbuff, width * length * bpp / 8) ' Release the bitmap memory bm.unlockbits(bmd)
In the above VB.NET example, a dot Net bitmap is created and filled with pixel data then copied into a Victor Image for processing.
Converting a Victor Image to a Device Dependent Bitmap
In the 32-bit Victor Library an image allocated with the allocimage function has a DIB handle, that is, the hBitmap element of the image descriptor is non-zero. This hBitmap can be used wherever a device dependent bitmap handle is requested, thus eliminating the need to convert to a device dependent bitmap (DDB).
But if the hBitmap element is zero and a device dependent bitmap is required then it is necessary to convert a Victor image to a DDB. The following function creates a device dependent bitmap from a Victor image:
int ConvertImageToBitmap(HDC hDC, imgdes *image, HBITMAP *hBitmap)
{
int rcode;
HPALETTE hPal;
// Create a logical palette from Victor palette
rcode = victowinpal(image, &hPal);
if(rcode == NO_ERROR) {
if(image->bmh->biBitCount <= 8) {
// Select and realize the palette
hPal = SelectPalette(hDC, hPal, 0);
RealizePalette(hDC);
}
// Convert the DIB into a DDB
// and return the DDB handle in hBitmap
rcode = dibtobitmap(hDC,
(UCHAR huge *)image->bmh, hBitmap);
if(image->bmh->biBitCount <= 8)
// Remove logpalette before releasing DC
SelectPalette(hDC, hPal, 0);
}
return(rcode);
}
The bits per pixel of the resulting bitmap is dependent upon the display mode,
i.e., a 256-color display mode produces an 8-bit DDB, and a 16-color display
mode produces a 4-bit DDB. This is independent of the bits per pixel of the
source image.
Converting a Victor Image to a dot Net bitmap
To convert a Victor Image into a dot Net bitmap we get the address of the image data (ibuff element of the image descriptor) and use it as one of the paramenters in the bitmap constructor.
getbmhfromimage(bmh, myimage) width = bmh.biWidth length = bmh.biHeight bpp = bmh.biBitCount bitmapbuff = IntPtr.op_Explicit(myimage.ibuff) ' Create a bitmap inside a Victor image select case bpp case "1" format = pixelformat.Format1bppIndexed exit select case "8" format = pixelformat.Format8bppIndexed exit select case "24" format = pixelformat.Format24bppRgb exit select end select bm = New bitmap(width, length, myimage.buffwidth, format, bitmapbuff)
In the above VB.NET example, a dot Net bitmap is created inside a Victor image and ready
to be operated on by any .NET graphics functions.
Adding Graphic Elements to an Image
Graphics elements such as text, lines, rectangles, and ellipses can be added to an image using the dot Net graphics functions.
getbmhfromimage(bmh, myimage)
width = bmh.biWidth
length = bmh.biHeight
bpp = bmh.biBitCount
bitmapbuff = IntPtr.op_Explicit(myimage.ibuff)
' Create a bitmap inside a Victor image
select case bpp
case "1"
format = pixelformat.Format1bppIndexed
exit select
case "8"
format = pixelformat.Format8bppIndexed
exit select
case "24"
format = pixelformat.Format24bppRgb
exit select
end select
bm = New bitmap(width, length, myimage.buffwidth, format, bitmapbuff)
g1 = graphics.fromimage(bm)
action_requested = input_string
if(action_requested <> "") then ' Add a graphic
select case action_requested
' Add .NET graphic element
case "rectangle"
g1.drawrectangle(pens.red, 50, 50, width-100, length-100)
exit select
case "block"
g1.fillrectangle(brushes.blue, 270, 200, 40, 30)
exit select
case "text"
g1.drawstring("hello", drawfont, brushes.green, 10, 10 )
exit select
end select
end if
savetif("changedimage.tif", myimage, 0)
In the above VB.NET example, a dot Net bitmap is created inside a Victor image, a graphics object is created, and graphic elements and text are added to it. The changed image is saved as a tif file.
Windows DIB Functions
Windows provides the functions SetDIBitsToDevice, StretchDIBits, CreateDIBitmap,
SetDIBits, and GetDIBits for working with device independent bitmaps. These
functions can be used directly with Victor images. The use of image descriptor
elements as arguments to the Windows functions is illustrated below.
SetDIBitsToDevice
SetDIBitsToDevice sets the bits from a DIB directly on a device context. This function copies a rectangle of image data from the DIB to a device context. To display the image beginning at (8,8) on a device context:
SetDIBitsToDevice(hdc, 8, 8, // x,y position on device context (unsigned)image.bmh->biWidth, // Image width (unsigned)image.bmh->biHeight, // Image height 0, 0, // Starting x,y in image 0U, // Starting scanline (unsigned)image.bmh->biHeight, // Number of lines to display image.ibuff, // Address of image buffer (BITMAPINFO far *)image.bmh, // Address of BITMAPINFO DIB_RGB_COLORS); // Color usage constant
StretchDIBits
StretchDIBits moves a source rectangle from a DIB into a rectangle on a device context, stretching or compressing the image data to fit the dimensions of the destination rectangle.
When using this function to stretch an image area, remember that the parameters describing the DIB's starting x and y coordinates are in an upside down system. This function assumes y = 0 is at the bottom of the image.
To resize an image area to fit a 640 x 480 area beginning at (8,8) on a device context:
StretchDIBits(hdc, 8, 8, // x,y position on device context 640, 480, // Width, height of DC rect image.stx, // Starting x in image image.bmh->biHeight - 1 - image.endy, // Starting y pos in DIB image.endx - image.stx + 1, // Image area width image.endy - image.sty + 1, // Image area height image.ibuff, // Address of image buffer (BITMAPINFO far *)image.bmh, // Address of BITMAPINFO DIB_RGB_COLORS, // Color usage constant SRCCOPY); // Raster op
CreateDIBitmap
CreateDIBitmap creates a device dependent bitmap from a DIB.
To create a device dependent bitmap from an entire image:
CreateDIBitmap(hdc, // Device context (BITMAPINFOHEADER far *)image.bmh, // BITMAPINFOHEADER CBM_INIT, // Initialize bitmap image.ibuff, // Address of image buffer (BITMAPINFO far *)image.bmh, // Address of BITMAPINFO DIB_RGB_COLORS); // Color usage constant
SetDIBits
SetDIBits sets the bits of a bitmap to the values given in a DIB. That is, this
function copies a specified number of rows of image data from a DIB to a device
dependent bitmap.
GetDIBits
GetDIBits converts the bits in a device dependent bitmap into device independent format, and stores the values in a specified number of rows in a DIB. See Converting a Device Dependent Bitmap to an Image above for an example.
If GetDiBits is called with the lpBits parameter set to NULL, no image data is returned, only the biSizeImage field and color table of a BITMAPINFO structure are filled in.
Using the Windows Clipboard
The Windows clipboard is a common area for exchanging data between applications. The clipboard supports passing image data as DIB, bitmap, and palette objects.
When working with the clipboard, it is very important to remember that the clipboard maintains ownership of all objects passed to it. When passing an image to the clipboard, always pass a copy of the image. And when receiving an image from the clipboard, make a copy of the image owned by the clipboard.
Copying an Image to the Clipboard as a DIB
In the following code imagetodib allocates space for a new DIB and copies the image area into the new DIB for passing to the clipboard.
void CopyDIBToClipboard(HWND hWnd, imgdes *image)
{
unsigned char huge *dib;
int rcode;
HGLOBAL hMem;
if(OpenClipboard(hWnd)) {
EmptyClipboard(); // Clean clipboard of contents
// Create a new DIB to pass to the clipboard
rcode = imagetodib(image, &dib);
if(rcode == NO_ERROR) {
// Get a handle to the new DIB
hMem = (HGLOBAL)GlobalHandle(dib);
// Unlock the handle to the DIB
// Handle passed to clipboard must be unlocked!
GlobalUnlock(hMem);
// Copy the DIB to the clipboard
SetClipboardData(CF_DIB, hMem);
CloseClipboard();
}
}
else
MessageBox(hWnd,"Could not open clipboard", 0, MB_OK);
}
Copying an Image to the Clipboard as a Bitmap
The above routine can be modified to create a device dependent bitmap. In the code that follows, the bitmap handle to be passed to the clipboard is returned in the variable hBitmap.
HBITMAP hBitmap;
. . .
hdc = GetDC(hWnd);
// Convert image to a bitmap
rcode = ConvertImageToBitmap(hdc, image, &hBitmap);
if(rcode == NO_ERROR)
// Copy the bitmap to the clipboard
SetClipboardData(CF_BITMAP, hBitmap);
ReleaseDC(hWnd, hdc);
The ConvertImageToBitmap function was presented in the earlier section, see Converting an Image to a Device Dependent Bitmap.
Copying a Palette to the Clipboard
The victowinpal function converts the palette associated with an image into a logical palette object and enters the logical palette handle in the hPal variable. The logical palette is then copied to the clipboard.
void CopyPaletteToClipboard(HWND hWnd, imgdes *image)
{
HPALETTE hPal;
if(OpenClipboard(hWnd)) {
EmptyClipboard(); // Clean clipboard of contents
// Create a PALETTE object from the image
victowinpal(image, &hPal);
if(hPal) {
// Copy the palette to the clipboard
SetClipboardData(CF_PALETTE, hPal);
CloseClipboard();
}
}
else
MessageBox(hWnd,"Could not open clipboard", 0, MB_OK);
}
Pasting a DIB from the Clipboard
The dibtoimage function is used to allocate space for a new image and copy the DIB from the clipboard into the new image buffer.
// Get clipping from clipboard
void PasteDIBfromClipboard(HWND hWnd, imgdes *image)
{
unsigned char huge *dib;
int rcode=NO_ERROR;
HGLOBAL hMem;
if(OpenClipboard(hWnd)) {
// Get DIB from clipboard
if((hMem = GetClipboardData(CF_DIB)) != 0) {
// Get address of DIB
dib = (unsigned char huge *)GlobalLock(hMem);
// Create a new image from the DIB
dibtoimage(dib, image);
// Unlock memory before closing
GlobalUnlock(hMem);
}
else
MessageBox(hWnd, "No DIB on clipboard", 0, MB_OK);
CloseClipboard(); // Close the clipboard
}
else
MessageBox(hWnd, "Could not open clipboard", 0,
MB_OK);
}
Scanning Images
TWAIN Support
Victor TWAIN functions allow you to easily create an application to import images from any device that has a TWAIN data source (a broad range of scanners and video capture devices). An added benefit is that an optimal user interface is provided so you don't have to design a new interface for each device.
TWAIN Architecture
There are four components in the TWAIN architecture:
- Your application,
- The Victor TWAIN module, which intercedes between your application and the source manager. The Victor TWAIN support module is VICTW32.DLL.
- The source manager, which manages the interactions between the Victor TWAIN module and data source(s), and
- The data source, which controls the imaging device.
This relationship can be depicted as follows:
Application
|
|
Victor TWAIN module
|
|
TWAIN Source Manager
/ \
/ \
Data Source 1 Data Source 2
Additional files necessary to acquire an image from a TWAIN data source are listed below.
| Filename | Description |
| TWAIN.DLL | TWAIN 16-bit source manager |
| TWAIN_32.DLL | TWAIN 32-bit source manager |
| TWUNK_32.EXE | Thunking module |
| TWUNK_16.EXE | Thunking module |
| MSVCRT20.DLL | Runtime library used by the source manager |
| xxx.DS | TWAIN 16- or 32-bit data source for device xxx |
The thunking modules allow a 16- or 32-bit application to use a 16- or 32-bit data source. Data sources are available from the device manufacturers.
The first four files listed above should be installed in the \Windows directory. MSVCRT20.DLL should be installed in the \Windows\System directory (Windows 9x) or in the \Windows\System32 directory (Windows NT). Data source files xxx.DS should be in the \Windows\Twain or \Windows\Twain_32 directory.
Using the Victor TWAIN functions
The most common method of using the Victor TWAIN functions is to add two menu items to an application under the File menu: Select Source, which will call TWselectsource or TWselectsourcebyname and Acquire, which will call one of the Victor scan functions. You may also want to use TWdetecttwain to enable or disable these menu items.
The Victor scan functions are
| TWscanimage | Capture one image |
| TWscanimageex | Capture one image without displaying the acquire dialog box |
| TWscancountimages | Capture one or more images without displaying the acquire dialog box |
| TWscanmultipleimages | Capture one or more images |
| TWscanmultipleimagesex | Capture one or more images without displaying the acquire dialog box |
The get-parameter functions (TWgetbrightness, TWgetcontrast, TWgetmeasurementunit, TWgetpixeltype, TWgetxresolution, TWgetyresolution ) are used to get the valid range of parameter values before calling the set-parameter functions. The get functions may not be able to verify a parameter change made by a set function because the new value to set is not sent to the device until a scan image function is called.
It is important to recognize that using a set-parameter function (TWsetbrightness, TWsetcontrast, TWsetmeasurementunit, TWsetpixeltype, TWsetxresolution, TWsetyresolution) does not guarantee a change in that parameter. A TWAIN device is under no obligation to allow a parameter to be modified. This is especially true if an acquire dialog box is displayed, since the user may change the selected parameter anyway. To learn more about TWAIN, the TWAIN toolkit may be downloaded from ftp://caere.com/pub/twain.
A TWAIN Example
Here is an example of a simple implementation to acquire an image from a TWAIN device.
// Select source command selected
void DoMenuSelectSource(HWND hWnd)
{
int rcode;
// Call the TWAIN source manager to select a source
// for image acquisition
rcode = TWselectsource(hWnd);
if(rcode != NO_ERROR)
// Handle any errors here
}
// Acquire command selected
void DoMenuAcquire(HWND hWnd,
imgdes far *simage) // Store captured image in simage
{
int rcode;
// Use App name to display in Source dialog box.
TWsetproductname("MyApp");
// Display the device user interface dialog box and
// capture an image
rcode = TWscanimage(hWnd, simage);
if(rcode != NO_ERROR)
// Handle any errors here
}
For additional examples see the individual scan functions in the Library
Reference section.
Victor Functions by Category
Memory Management
These functions allocate or free global memory for image storage.
allocDIB allocate space for an image in memory allocimage allocate space for an image in global memory freebuffer release memory from a savefiletobuffer function freeimage free an allocated image getbuffersize determine size of a buffer from a savefiletobuffer function
File Handling
The save and load operations transfer image data between an image area and the
disk. The info routines provide information about a file before loading.
Binary, BMP, GIF, JPEG, PCX, TGA and TIFF file formats are supported.
loadbif load binary image data file
loadbmp load BMP or DIB file
loadbmpfrombuffer load BMP or DIB file from memory
loadbmppalette load BMP palette
loadbmppalettefrombuffer load BMP palette from memory
loadgif load GIF image
loadgifframe load GIF image from multiframe file
loadgifframefrombuffer load GIF image from multiframe file in memory
loadgiffrombuffer load GIF file from memory
loadgifpalette load GIF palette
loadgifpalettefrombuffer load GIF palette from memory
loadgifglobalpalette load GIF global palette
loadgifglobalpalettefrombuffer load GIF global palette from memory
loadgifframepalette load GIF frame palette
loadgifframepalettefrombuffer load GIF frame palette from memory
loadjpg load JPEG file
loadjpgex load JPEG file without converting from ycc to rgb
loadjpgfrombuffer load JPEG file from memory buffer
loadjpgfrombufferex load JPEG file without converting from ycc to rgb
loadjpgthumbnail load a thumbnail image from a JPEG file
loadjpgthumbnailfrombuffer load a thumbnail image from a JPEG file in memory
loadpcx load PCX file
loadpcxpalette load PCX palette
loadpng load PNG file
loadpngfrombuffer load PNG file from memory
loadpngpalette load PNG palette
loadpngpalettefrombuffer load PNG palette from memory
loadtga load TGA file
loadtgapalette load TGA palette
loadtgawithalpha load TGA image and alpha channel
loadtif load TIFF file
loadtiffrombuffer load image from TIFF file in memory
loadtifpage load image from TIFF multipage file
loadtifpagebyindex load image from TIFF multipage file
loadtifpagebyindexfrombuffer load image from TIFF multipage file in memory
loadtifpagebyindexfrombufferwithalpha load image and alpha channel image from file in memory
loadtifpalette load palette from TIFF file
loadtifpalettefrombuffer load palette from TIFF file from memory
loadtifpalettepage load palette from TIFF multipage file
loadtifpalettepagebyindex load palette from TIFF multipage file
loadtifwithalpha load TIFF image and alpha channel
savebif save image as binary data file
savebmp save image as BMP file
savebmptobuffer save image as BMP file in memory
saveeps save image as EPS file
savegif save image as GIF file
savegifex save image as GIF file with transparency and interlace options
savegiftobufferex save image as GIF file with transparency,
interlace, and compression options to memory
savegifframe save image as a frame in a multiframe GIF file
savegifmultiframetobuffer save images as frames in a multiframe GIF file in memory
savejpg save image as JPEG file
savejpgex save image as JPEG file with mode option
savejpgtobuffer save image as JPEG file in memory
savejpgtobufferex save image as JPEG file with mode option in memory
savepcx save image as PCX file
savepng save image as PNG file
savepngex save image as PNG with transparent color
savepngtobuffer save image as PNG file to memory
savepngtobufferex save image as PNG with transparent color to memory
savetga save image as TGA file
savetif save image as TIFF file
savetifpage save image in a multipage TIFF file
savetiftobuffer save image as TIFF file to memory
getgifcomment read comment from a GIF file
getpngcomment read comment from a PNG file
setgifcomment set comment and version for saving a GIF file
bmpinfo BMP file information
bmpinfofrombuffer BMP file information from memory
gifframecount get number of frames in GIF file
gifframecountfrombuffer get number of frames in GIF file in memory
gifinfo GIF file information
gifinfoallframes get image info about all frames in GIF file
gifinfoallframesfrombuffer get image info about all frames in GIF file in memory
gifinfoframe get image info about one frame in GIF file
gifinfoframefrombuffer get image info about one frame in GIF file in memory
gifinfofrombuffer GIF file information from memory
jpeginfo JPEG file information
jpeginfoex JPEG file information
jpeginfofrombuffer JPEG file information from memory buffer
jpeginfofrombufferex JPEG file information from memory buffer
jpegsetthumbnailsize set JPEG thumbnail size
jpegsetxyresolution set resolution dta for saving JPEG files
pcxinfo PCX file information
pnginfo PNG file information
pnginfofrombuffer PNG file information from memory
pnggetxyresolution get resolution data from a PNG file
pngsetxyresolution set resolution data for saving PNG files
tgainfo TGA file information
tiffinfo TIFF file information
tiffinfofrombuffer TIFF file information from memory
tiffinfopage TIFF information about a single page in a multipage TIFF file
tiffinfopagebyindex TIFF information about a single page in a multipage TIFF file
tiffinfopagebyindexfrombuffer TIFF info about a single page from memory
tiffinfopagebyindexex expanded TIFF info about a single page
tiffinfopagebyindexfrombufferex expanded TIFF info about a single page from memory
tiffgetdnstring get document name from TIFF file
tiffgetpageinfo TIFF file information about all pages
tiffgetpageinfofrombuffer TIFF file info about all pages in memory
tiffgetSOIofspagebyindex get offset of JPEG-compressed data
tiffgetSOIofspagebyindexfrombuffer get offset of JPEG-compressed data
tiffgetxyresolution get resolution data from a TIFF file
tiffgetxyresolutionpagebyindex get resolution data about a single page from a TIFF file
tiffsetdnstring set document name for saving TIFF file
tiffsetxyresolution set resolution data for saving a TIFF file
jpeggeterror report last JPEG error
pnggeterror report last PNG error
tiffgeterror report last TIFF error
unlockLZW enable LZW compression/decompression (requires license agreement with Unisys)
Image Processing
Image processing functions alter the brightness level values of 8- or 24-bit images. Functions marked with "+1" also operate on 1-bit images. Image processing functions can operate on the entire image or any rectangular area within the image.
addnoise add random noise addtext add text addtextex add text blur smoothing filter blurthresh smoothing filter with threshold brightenmidrange raise brightness of intermediate levels changebright increase or decrease brightness dilate darken by enlarging dark areas (+1) divide divide by factor dropbits remove noise by dropping less significant bits emboss emboss filter embossongray emboss filter onto a gray background erode brighten by enlarging bright areas (+1) exchangelevel change range of levels to new value expandcontrast increase contrast gammabrighten apply a gamma brightness correction gaussianblur normal distribution smoothing filter histobrighten histogram brightening histoequalize histogram equalization kodalith create high contrast image limitlevel set maximum brightness level matrixconv matrix convolution, 3 x 3 kernel matrixconvex matrix convolution, 63 x 63 kernel medianfilter remove noise by median filter, 3- to 11-pixel edge multiply multiply by factor multiplyex multiply by floating point factor negative negative image (+1) outline edge detection filter outlineongray edge detection filter onto a gray background pixellize pixellation removenoise remove noise by median filter sharpen sharpening filter sharpengentle gentle sharpening filter threshold set minimum brightness level tile fill with multiple copies of an image usetable set pixel values based on table zeroimage set all pixels to the same value (+1)
Multi-Image Processing
addimage add two images addtexture impose operator texture onto source andimage AND two images (+1) bleachimage multiply negatives of two images correlateimages fill result image with pixel data representing correlation coefficients cover overlay two images coverclear overlay two images, transparent color darker combine darker pixels of two images difference calculate difference onto gray background differenceab calculate absolute value of difference displace offset source based on operator divideimage divide source by operator isolate isolate source based on mask lighter combine lighter pixels of two images multnegimage negative of bleachimage multiplyimage multiply two images orimage OR two images (+1) screen high contrast using dither screen filter subimage subtract operator from source wtaverage weighted average of two images, uniform wt wtaveragemask weighted average of two images, wt based on mask xorimage XOR two images (+1)
Image Manipulation
These operations alter an image area's shape, dimensions, position, or orientation. Image data is read from a source image area, modified, and written to a result area.
copyimage copy image and palette (+1) copyimagebits copy image data only (+1) displace alter pixel positions extractcolorrange create mask based on color range extractplane copy R-, G-, B- or H-, S-, V-plane flipimage flip image top to bottom (+1) insertplane replace R-, G-, B- or H-, S-, V-plane mirrorimage reverse image left to right (+1) resize resize image (+1) resizeex resize image with interpolation rotate rotate image any angle (+1) rotateex rotate image any angle with pixel replication (+1) rotate90 rotate image 90 degrees (+1) tile fill with multiple copies of an image
Image Descriptor Modification
The image descriptor is a data structure that contains information that describes an image. These functions simplify the entry of data into an image descriptor.
copyimgdes copy all image descriptor elements imageareatorect set RECT coordinates from an image area recttoimagearea set an image area from a RECT data structure setimagearea set the image area of interest setupimgdes assign image descriptor fields based on the BITMAPINFOHEADER of a packed DIB zeroimgdes set all image descriptor elements to zero
Color Reduction and Image Conversion
Images and color palettes are converted between formats.
clienttoimage capture window client area to image cmykimagetorgbimage convert 32-bit CMYK image to 24-bit RGB colordither create dithered color image, 16- or 256-color palette colorscatter create scatter color image, 16- or 256-color palette colortogray color image to grayscale convert1bitto8bit 1-bit image to 8-bit image convert1bitto8bitsmooth 1-bit image to 8-bit image with smoothing convert8bitto1bit 8-bit image to 1-bit image with dither, scatter, or threshold options convert8bitto1bitex convert 8- to 1-bit with dither matrix convertgray8to16 8-bitgrayscale to 16-bit grayscale image convertgray16to8 16-bitgrayscale to 8-bit grayscale image convertgray16to8ex convert 16- to 8-bit with contrast expansion convertgray32to8 convert 32- to 8-bit grayscale convertgray32to16 convert 32- to 16-bit grayscale convertrgbpal 24-bit RGB image to 8-bit with optimum palette convertrgbpalex 24-bit RGB image to 8-bit with optimum palette with diffusion scatter and color matching options convertpalrgb 8-bit image to 24-bit RGB ddbtoimage device dependent bitmap to image dibtobitmap DIB to a device specific bitmap dibtoimage DIB to a Victor-compatible image dibsecttoimage DIB section to a Victor-compatible image hsvimagetorgbimage convert 24-bit HSV image to 24-bit RGB image imagetodib extract an image area and create a new DIB matchcolorimage match image to a specified palette matchcolorimageex match image to a specified palette with diffusion scatter and color matching options reduceimagecolors decrease the number of colors used in an image rgbimagetocmykimage convert 24-bit RGB image to 32-bit CMYK image rgbimagetohsvimage convert 24-bit RGB image to 24-bit HSV image windowtoimage capture window to imag
Color Palette Operations
copyimagepalette copy image palette data only defaultpalette establish a 16-color palette consisting of the default Windows colors makepalette create a color palette rainbowpalette create a 256-color rainbow palette standardpalette establish a 256-color palette consisting of the default Windows colors hsv2rgb convert hue, saturation, value table to red, green, blue palette rgb2hsv convert red, green, blue palette to hue, saturation, value table updatebitmapcolortable update internal color info (32-bit only) victowinpal convert image palette to Windows logical palette wintovicpal convert Windows logical palette to image palette
Display Functions
drawhisto display histogram on a device context viewimage display image on a device context viewimageex display image at specified position with automatic color reduction
Printer Functions
The printer functions print an image area at any size and position on a printer device context.
printimage print image printimagenoeject print image without ejecting the page printimageenddoc end print-document and eject page printimagestartdoc begin print-document
Image Analysis
calcavglevel calculate average brightness level calcavglevelfloat calculate average brightness level as a float calchisto calculate histogram calchistorgb calculate histogram treating palette color image as an RGB image calcminmax calculate minimum and maximum pixel values correlationcoef calculate correlation coefficient between two images correlationcoefRGB calculate correlation coefficient between two RGB images correlateimages fill result image with pixel data representing correlation coefficients getpixelcolor read pixel value at buffer (x,y) isgrayscaleimage determine if image is grayscale pixelcount count pixels within a brightness level range setpixelcolor set pixel at buffer (x,y) to value sortpixelsbyval sort pixel intensities into an array
System Information
Victorversion get Victor Library version number Victorversiondate get Victor Library version and date Victorversionex get Victor Library version information VicStaticLibStart initialize static library VicStaticLibTerm terminate static library
TWAIN Device Control Functions
Control a TWAIN-compliant scanner and Automatic Document Feeder (ADF), set parameters, get parameters, and capture images.
TWopen open TWAIN data source and data source manager
TWclose close TWAIN data source and data source manager
TWdetecttwain detect TWAIN source manager
TWgetbrightness set scanner brightness
Twgetcontrast set scanner contrast
TWgeterror get extended error information
TWgetfeeder get document feeder status
TWgetmeasureunit get valid measurement units
TWgetpixeltype restrict pixel type
TWgetphysicalsize get maximum image size
TWgetsourcenames get names of available data sources
TWgetxresolution set scanner horizontal resolution
TWgetyresolution set scanner vertical resolution
TWscancountimages acquire specified number of images
TWscanimage acquire image from TWAIN data source
TWscanimageex acquire image from TWAIN data source
without displaying Acquire dialog box
TWscanmultipleimages acquire multiple images
TWscanmultipleimagesex acquire multiple images without displaying
Acquire dialog box
TWselectsource select a new data source
TWselectsourcebyname select a data source by name
TWsetbrightness set scanner brightness
TWsetcontrast set scanner contrast
TWsetduplex set duplex operation
TWsetfeeder set document feeder
TWsetmeasureunit set measurement unit type
TWsetpagesize set maximum image size
TWsetpixeltype restrict pixel type
TWsetproductname inform data source of application name
TWsetxresolution set scanner horizontal resolution
TWsetyresolution set scanner vertical resolution
TWStaticLibStart initialize static library
TWStaticLibTerm terminate static library
TWvicversion return Victor Library TWAIN support module version number