int add2(HWND hWnd, imgdes *image1, imgdes *image2,
imgdes *image3)
{
int rcode;
setimagearea(image1, 0, 0, 255, 255);
setimagearea(image2, 0, 0, 255, 255);
if((rcode=blur(image1, image2)) == NO_ERROR) {
setimagearea(image3, 0, 0, 255, 255);
if((rcode=addimage(image1, image2, image3)) != NO_ERROR)
MessageBox(hWnd,"Error in adding images", 0, MB_OK);
}
else
MessageBox(hWnd,"Error in blurring images", 0, MB_OK);
return(rcode);
}
This example smooths image1, adds the original image to the smoothed image, and places the result in image3.
void CopyImageToClipboard(HWND hWnd, imgdes *image)
{
int rcode = NO_ERROR;
imgdes timage;
HGLOBAL hMem;
if(OpenClipboard(hWnd)) { // Open clipboard
EmptyClipboard();
// Create a new DIB to pass to the clipboard
rcode = allocDIB(&timage, (int)image->bmh->biWidth,
(int)image->bmh->biHeight, image->bmh->biBitCount);
if(rcode == NO_ERROR) {
rcode = copyimage(image, &timage);
if(rcode == NO_ERROR) {
// Get a handle to the new DIB
hMem = GlobalPtrHandle(timage.bmh);
// Unlock the handle to the DIB
GlobalUnlock(hMem);
// Pass the DIB to the clipboard
SetClipboardData(CF_DIB, hMem);
}
}
CloseClipboard();
}
if(rcode != NO_ERROR)
MessageBox(hWnd, "Error copying DIB to clipboard", 0, MB_OK);
}
This example creates a DIB from an image and passes the DIB to the Windows clipboard.
int loadTifImage(HWND hWnd, LPCSTR fname, imgdes *image)
char szBuff[80];
TiffData tdat;
int rcode;
// Get info on the file we're to load
rcode = tiffinfo(fname, &tdat); // Fill structure
if(rcode == NO_ERROR) {
// Allocate space for an image in global memory
rcode = allocimage(image, tdat.width, tdat.length,
tdat.vbitcount);
if(rcode == NO_ERROR)
rcode = loadtif(fname, image);
}
// If there is an error, free image and display message
if(rcode != NO_ERROR) {
freeimage(image);
wsprintf(szBuff, "Could not load %s", fname);
MessageBox(hWnd, szBuff, 0, MB_OK);
}
return(rcode);
}
This example reads a TIFF file header, allocates memory to hold the image, and then loads the TIFF file.
int AddRectToTifImage(HWND hWnd, LPCSTR fname, imgdes *image)
{
char szBuff[80];
TiffData tdat;
int rcode;
HDC hDC, hMemDC;
HBITMAP hOldBitmap;
// Get info on the file we're to load
rcode = tiffinfo(fname, &tdat); // Fill structure
if(rcode == NO_ERROR) {
// Allocate space for an image
rcode = allocimage(image, tdat.width, tdat.length,
tdat.vbitcount);
if(rcode == NO_ERROR)
rcode = loadtif(fname, image);
}
// If TIF file was successfully loaded, draw rectangle
if(rcode == NO_ERROR) {
// Create a memory DC
hDC = GetDC(hWnd);
hMemDC = CreateCompatibleDC(hDC);
if(hMemDC != 0) {
// Select the bitmap into the DC
hOldBitmap = SelectObject(hMemDC, image->hBitmap);
// Draw the rect into the DIB
Rectangle(hMemDC, 10, 10, 100, 100);
// Restore the original bitmap
SelectObject(hMemDC, hOldBitmap);
// Free the memory DC
DeleteDC(hMemDC);
ReleaseDC(hWnd, hDC);
}
}
else { // There was an error, free image and display message
freeimage(image);
wsprintf(szBuff, "Could not load %s", fname);
MessageBox(hWnd, szBuff, 0, MB_OK);
}
return(rcode);
}
This example allocates memory to hold an image, loads a TIFF file, and draws a rectangle on the image.
int andx(HWND hWnd, imgdes *image1, imgdes *image2,
imgdes *image3)
{
int rcode;
setimagearea(image1, 0, 0, 255, 255);
setimagearea(image2, 0, 0, 255, 255);
if((rcode=negative(image1, image2)) == NO_ERROR) {
setimagearea(image3, 0, 0, 255, 255);
if((rcode=andimage(image1, image2, image3)) != NO_ERROR)
MessageBox(hWnd,"Error in ANDing images", 0, MB_OK);
}
else
MessageBox(hWnd,"Error in creating negative image", 0,
MB_OK);
return(rcode);
}
This example creates the negative of image1, ANDs the original image with the negative, and places the result in image3.
void blurit(HWND hWnd, imgdes *image)
{
int rcode, stx=0, sty=0, endx=255, endy=243, thresh=128;
setimagearea(image, stx, sty, endx/2 - 1, endy);
if((rcode=blur(image, image)) == NO_ERROR) {
setimagearea(image, endx/2, sty, endx, endy);
if((rcode=blurthresh(thresh, image, image)) == NO_ERROR) {
setimagearea(image, stx, sty, endx, endy);
if((rcode=savebif("Blurred.bif", image)) != NO_ERROR)
MessageBox(hWnd,"Error in saving image", 0, MB_OK);
}
else
MessageBox(hWnd,"Error at blurthresh()", 0, MB_OK);
}
else
MessageBox(hWnd,"Error at blur", 0, MB_OK);
}
This example smooths the left half of the image, smooths the right half of the image using a threshold and saves the entire image.
int info_bmp(LPCSTR fname)
{
char szBuff[512];
BITMAPINFOHEADER bdat; // Reserve space for struct
int rcode;
// Make sure file exists and get info on it
if((rcode = bmpinfo(fname, &bdat)) == NO_ERROR) {
wsprintf((LPSTR)szBuff, (LPSTR)"File name: %s"
"\nImage width: %ld, Image length: %ld"
"\nPlanes: %d"
"\nBitCount: %d"
"\nHeader size: %ld"
"\nCompression: %ld, Image size: %ld"
"\nColors used: %ld, Colors Important: %ld",
(LPSTR)fname, bdat.biWidth, bdat.biHeight,
bdat.biPlanes, bdat.biBitCount, bdat.biSize,
bdat.biCompression, bdat.biSizeImage,
bdat.biClrUsed, bdat.biClrImportant);
MessageBox(0, szBuff, (LPSTR)"File information", MB_OK);
}
return(rcode);
}
This example displays information about a BMP file.
void raisebrightness4printing(HWND hWnd, imgdes *image)
{
HCURSOR hSaveCursor;
// Display hourglass cursor
hSaveCursor = SetCursor(LoadCursor(0, IDC_WAIT));
if(brightenmidrange(image, image) != NO_ERROR)
MessageBox(hWnd,"Error in raising brightness", 0, MB_OK);
SetCursor(hSaveCursor); // Restore cursor
}
This example brightens an image before printing.
int trace(HWND hWnd, imgdes *image1, imgdes *image2)
{
int rcode, redval, grnval, bluval;
rcode = calcavglevel(image1, &redval, &grnval, &bluval);
if(rcode == NO_ERROR) {
if((rcode=kodalith(redval, image1, image2)) == NO_ERROR) {
if((rcode=outline(image2, image2)) != NO_ERROR)
MessageBox(hWnd, "Error at outline()", 0, MB_OK);
}
else
MessageBox(hWnd, "Error at kodalith", 0, MB_OK);
}
else
MessageBox(hWnd,(LPSTR)"Error at calcavglevel()", 0, MB_OK);
return(rcode);
}
This example calculates an average brightness level to create a kodalith and then outlines the image.
void DrawHistogram(HWND hHistoWnd, imgdes *image)
{
PAINTSTRUCT ps; // Holds PAINT info
HDC hDC;
int rcode=NO_ERROR;
RECT rect;
long near *redtab, near *grntab, near *blutab;
// Allocate space for the 3 histo tables
if((redtab = (long near *)LocalAlloc(LPTR, 3 * 256 *
sizeof(long))) == NULL)
MessageBox(hHistoWnd,"Insufficient memory for histo tables",
0, MB_OK);
else {
// Assign histo table pointers
grntab = &redtab[256];
blutab = &redtab[512];
hDC = BeginPaint(hHistoWnd, &ps);
// Calculate the histogram
rcode = calchisto(image, redtab, grntab, blutab);
if(rcode == NO_ERROR) {
// Draw the histogram in the window
GetClientRect(hHistoWnd, &rect);
rcode = drawhisto(hDC, &rect, image->bmh->biBitCount,
redtab, grntab, blutab);
}
EndPaint(hHistoWnd, &ps);
LocalFree((HLOCAL)redtab);
if(rcode != NO_ERROR)
MessageBox(hHistoWnd, "Error in displaying histogram",
0, MB_OK);
}
}
This example calculates and displays the histogram of an image area.
void DrawHistogramRGB(HWND hHistoWnd, imgdes *image)
{
PAINTSTRUCT ps; // Holds PAINT info
HDC hDC;
int rcode = NO_ERROR;
RECT rect;
long near *redtab, near *grntab, near *blutab;
// Interpret 8-bit palette color image as RGB image
int histoMode = PALETTEIMAGEASRGB;
// Allocate space for the 3 histo tables
if((redtab = (long near *)LocalAlloc(LPTR, 3 * 256 *
sizeof(long))) == NULL)
MessageBox(hHistoWnd, "Insufficient memory for histo
tables",0, MB_OK);
else {
// Assign histo table pointers
grntab = &redtab[256];
blutab = &redtab[512];
hDC = BeginPaint(hHistoWnd, &ps);
// Calculate the histogram
rcode = calchistorgb(image, redtab, grntab, blutab,
histoMode);
if(rcode == NO_ERROR) {
int bitcount = image->bmh->biBitCount;
// Force 24-bit display if image is palette color and
// calchistorgb mode is "palette image as RGB"
if((image->imgtype & IMGTYPE_GRAYSCALE) == 0 &&
histoMode == PALETTEIMAGEASRGB)
bitcount = 24;
// Draw the histogram in the window
GetClientRect(hHistoWnd, &rect);
rcode = drawhisto(hDC, &rect, bitcount, redtab, grntab,
blutab);
}
EndPaint(hHistoWnd, &ps);
LocalFree((HLOCAL)redtab);
if(rcode != NO_ERROR)
MessageBox(hHistoWnd, "Error in displaying histogram", 0,
MB_OK);
}
}
This example calculates and displays the histogram of an image area.
void change_bright(HWND hWnd, imgdes *image)
{
HCURSOR hSaveCursor;
// Display hourglass cursor
hSaveCursor = SetCursor(LoadCursor(0, IDC_WAIT));
if(changebright(5, image, image) != NO_ERROR)
MessageBox(hWnd,"Error in changing brightness", 0, MB_OK);
SetCursor(hSaveCursor); // Restore cursor
}
This example brightens an image by 5 each time it is called.
int CaptureScreenClient(HWND hWnd)
{
int rcode;
imgdes timage;
LPCSTR fname = "client.tif";
// Capture window as Victor image
rcode = clienttoimage(hWnd, &timage);
if(rcode == NO_ERROR) {
// Save captured client area
rcode = savetif(fname, &timage, 0);
// Release memory allocated by clienttoimage()
freeimage(&timage);
}
return(rcode)
}
This example captures a window's client area and saves it as a TIFF file.
int CreateImage8(HWND hWnd, imgdes *srcimg, imgdes *desimg,
int *freeflag)
{
int DisplayBits, palmode, rcode = NO_ERROR;
HDC hdc;
imgdes timage;
// Assume an image buffer will not be allocated
*freeflag = 0;
// Determine display adapter capabilities
hdc = GetDC(hWnd);
DisplayBits = GetDeviceCaps(hdc, BITSPIXEL);
ReleaseDC(hWnd, hdc);
// To view the entire image, use a temporary image descriptor and set the image area to the entire image
copyimgdes(srcimg, &timage);
setimagearea(&timage, 0, 0,
(unsigned)timage.bmh->biWidth - 1,
(unsigned)timage.bmh->biHeight - 1);
// If we're displaying a 24-bit image on an 8-bit display adapter, create a temporary 8-bit image for
display
if(srcimg->bmh->biBitCount == 24 && DisplayBits <= 8) {
if((rcode=allocimage(desimg,
(int)timage.bmh->biWidth,
(int)timage.bmh->biHeight, 8)) == NO_ERROR) {
palmode = DisplayBits == 8 ? COLORDITHER256 :
COLORDITHER16;
// Quick dither representation of 24-bit image
// (Or use colorscatter)
rcode = colordither(&timage, desimg, palmode);
// If error, free allocated memory
if(rcode != NO_ERROR)
freeimage(desimg);
else // Set freeflag=1 to show new image buffer allocated
*freeflag = 1;
}
}
else
copyimgdes(&timage, desimg);
return(rcode);
}
This example creates a new 8-bit color dithered image if the source image is a 24-bit RGB image and the display adapter is limited to 256 or fewer colors.
void makegray4printing(HWND hWnd, imgdes *image)
{
HCURSOR hSaveCursor;
// Display hourglass cursor
hSaveCursor = SetCursor(LoadCursor(0, IDC_WAIT));
if(colortogray(image, image) != NO_ERROR)
MessageBox(hWnd,"Error in creating gray image", 0, MB_OK);
SetCursor(hSaveCursor); // Restore cursor
}
This example converts a palette color image to grayscale for printing.
int outline1bpp(HWND hWnd, LPCSTR fname,
imgdes *image) // Image is 1 bpp
{
int rcode, mode = 2; // Use threshold conversion mode
imgdes timage; // Temp 8-bit image
// Load a 1-bit TIFF image
rcode = loadtif(fname, image);
if(rcode != NO_ERROR)
MessageBox(hWnd, "Error in loading file", 0, MB_OK);
else {
// Allocate space for 8-bit temp image
rcode = allocimage(&timage, (int)image->bmh->biWidth,
(int) image->bmh->biHeight, 8);
if(rcode != NO_ERROR)
MessageBox(hWnd, "Not enough memory for temp image",
0, MB_OK);
else { // Convert 1-bit to 8-bit image
rcode = convert1bitto8bit(image, &timage);
if(rcode != NO_ERROR)
MessageBox(hWnd, "Error in converting image", 0,
MB_OK);
else { // Outline image
outline(&timage, &timage);
// Convert 8-bit to 1-bit image
convert8bitto1bit(mode, &timage, image);
// Save as a 1-bit TIFF file, no compression
rcode = savetif(fname, image, 0);
if(rcode != NO_ERROR)
MessageBox(hWnd, "Could not save image", 0, MB_OK);
}
freeimage(&timage);
}
}
return(rcode);
}
This example loads a 1-bit per pixel image, converts it to an 8-bit per pixel image, outlines it, converts it back to 1-bit, and finally saves it as a TIFF file with the same filename.
int scaletogray(HWND hWnd, LPCSTR fname,
imgdes *image) // Image is 1 bpp
{
int rcode; // Use threshold conversion mode
imgdes timage; // Temp 8-bit image
// Load a 1-bit TIFF image
rcode = loadtif(fname, image);
if(rcode != NO_ERROR)
MessageBox(hWnd, "Error in loading file", 0, MB_OK);
else {
// Allocate space for 8-bit temp image
rcode = allocimage(&timage, (int)image->bmh->biWidth,
(int) image->bmh->biHeight, 8);
if(rcode != NO_ERROR)
MessageBox(hWnd, "Not enough memory for temp image", 0, MB_OK);
else { // Convert 1-bit to 8-bit image with smoothing
rcode = convert1bitto8bitsmooth(image, &timage);
if(rcode != NO_ERROR)
MessageBox(hWnd, "Error in converting image", 0, MB_OK);
else { // Replace original with smoothed 8-bit version
freeimage(image); // free original image
// Replace original image data with that describing the smoothed 8-bit image
copyimgdes(&timage, image); // copy data structure info
}
}
}
return(rcode);
}
This example loads a 1-bit per pixel image and converts it to a smoothed 8-bit per pixel image.
int process16bitGrayTIFF(LPCSTR fname)
{
int rcode;
TiffData tdat;
imgdes timage;
rcode = tiffinfo(fname, &tdat); // Fill structure
if(rcode == NO_ERROR &&
// Make sure image to load is 16-bit grayscale
tdat.BitsPSample == 16 && tdat->SamplesPPixel == 1)
// Allocate memory for image storage
rcode = allocimage(&timage, tdat.width, tdat.length,
tdat.vbitcount);
if(rcode == NO_ERROR)
// Read in a 16-bit grayscale TIFF file
rcode = loadtif(fname, &timage);
if(rcode == NO_ERROR) {
imgdes nimage;
allocimage(&nimage, tdat.width, tdat.length, 8);
// Convert image to 8-bit
rcode = convertgray16to8(&timage, &nimage);
if(rcode == NO_ERROR) {
// Process image
histoequalize(&nimage, &nimage);
// Convert image back to 16-bits
convertgray8to16(&nimage, &timage);
// Save processed 16-bit image
rcode = savetif(fname, &timage, 0);
freeimage(&nimage); // Release memory allocated for 8-bit image
}
}
// Release memory allocated for 16-bit image
freeimage(&timage);
}
}
return(rcode)
}
This function loads a 16-bit grayscale image, converts it to 8-bits, performs image processing on it, converts it back to a 16-bit image, and saves it.
int saveasRGB(HWND hWnd, LPCSTR fname, imgdes *srcimg)
{
int rcode, rows, cols, compress=0;
char str[50];
imgdes resimg;
rows = srcimg->endy - srcimg->sty + 1;
cols = srcimg->endx - srcimg->stx + 1;
rcode = allocimage(&resimg, cols, rows, 24);
if(rcode != NO_ERROR)
MessageBox(hWnd, "Could not allocate memory", 0, MB_OK);
else {
rcode = convertpaltorgb(srcimg, &resimg);
if(rcode == NO_ERROR) {
wsprintf(str, "Saving %s as 24-bit TGA file",
(LPCSTR)fname);
MessageBox(hWnd, str, 0, MB_OK);
rcode = savetga(fname, &resimg, compress);
if(rcode != NO_ERROR)
MessageBox(hWnd, "Error in saving file", 0, MB_OK);
}
else MessageBox(hWnd, "Error converting palette "
"color image to RGB image", 0, MB_OK);
freeimage(&resimg);
}
return(rcode);
}
This example saves an 8-bit image as a 24-bit Targa file.
int qualityview(HWND hWnd, imgdes *srcimg)
{
int rcode, rows, cols;
HDC hDC;
HPALETTE hpal;
imgdes resimg;
PAINTSTRUCT ps;
rows = srcimg->endy - srcimg->sty + 1;
cols = srcimg->endx - srcimg->stx + 1;
rcode = allocimage(&resimg, cols, rows, 8);
if(rcode == NO_ERROR) {
rcode = convertrgbtopal(235, srcimg, &resimg);
if(rcode != NO_ERROR)
MessageBox(hWnd,
"Could not convert RGB to 8-bit image", 0, MB_OK);
else {
hDC = BeginPaint(hWnd, &ps);
// Display the image at (0,0)
rcode = viewimage(hWnd, hDC, &hpal, 0, 0, &resimg);
EndPaint(hWnd, &ps);
if(rcode != NO_ERROR)
MessageBox(hWnd, "Error in displaying image", 0,
MB_OK);
}
DeleteObject(hpal);
freeimage(&resimg);
}
return(rcode);
}
This example converts an RGB image to an 8-bit palette color image containing 235 colors and displays it.
int qualityviewex(HWND hWnd, imgdes *srcimg)
{
int rcode, rows, cols;
HDC hDC;
HPALETTE hpal;
imgdes resimg;
PAINTSTRUCT ps;
int colredmode = CR_TSDDIFF;
rows = srcimg->endy - srcimg->sty + 1;
cols = srcimg->endx - srcimg->stx + 1;
rcode = allocimage(&resimg, cols, rows, 8);
if(rcode == NO_ERROR) {
rcode = convertrgbtopalex(235, srcimg, &resimg,
colredmode);
if(rcode != NO_ERROR)
MessageBox(hWnd,
"Could not convert RGB to 8-bit image", 0, MB_OK);
else {
hDC = BeginPaint(hWnd, &ps);
// Display the image at (0,0)
rcode = viewimage(hWnd, hDC, &hpal, 0, 0, &resimg);
EndPaint(hWnd, &ps);
if(rcode != NO_ERROR)
MessageBox(hWnd, "Error in displaying image", 0,
MB_OK);
}
DeleteObject(hpal);
freeimage(&resimg);
}
return(rcode);
}
This example converts an RGB image to an 8-bit palette color image containing 235 colors and displays it.
int MakeBackUp(imgdes *image, imgdes *backup, RECT *backrect)
{
int rcode, rows, cols;
rows = image->endy - image->sty + 1;
cols = image->endx - image->stx + 1;
// If an old backup exists, delete it
if(backup->bmh != 0)
freeimage(backup);
// Allocate our backup DIB
if((rcode=allocimage(backup, cols, rows,
image->bmh->biBitCount)) == NO_ERROR) {
// Save the coords of where to place the image area
imageareatorect(image, backrect);
// Copy the image area into the backup buffer
rcode = copyimage(image, backup);
}
return(rcode);
}
This example makes a backup copy of an image area and palette.
int PasteBackUp(imgdes *backup, RECT *backrect, imgdes *image)
{
#define NO_BACKUP -3
int rcode;
// Make sure a backup image area exists
if(backup->bmh == 0)
return(NO_BACKUP);
// Restore the previous image area
recttoimagearea(backrect, image);
rcode = copyimagebits(backup, image);
return(rcode);
}
This example pastes a backup copy of an image area into an image buffer.
void dupimagepalette(int numcolors, imgdes *srcimg, imgdes *resimg)
{
int oldcolors;
oldcolors = srcimg->colors;
srcimg->colors = numcolors;
copyimagepalette(srcimg, resimg);
srcimg->colors = oldcolors;
}
This example copies a portion of a color palette from one image to another.
int coverneg(HWND hWnd, imgdes *image1, imgdes *image2,
imgdes *image3)
{
int rcode, threshold=68;
if((rcode=negative(image1, image2)) == NO_ERROR) {
if((rcode=cover(threshold,image1, image2, image3))
!= NO_ERROR)
MessageBox(hWnd,"Error in covering image", 0, MB_OK);
}
else
MessageBox(hWnd,"Error in creating negative image", 0,
MB_OK);
return(rcode);
}
This example creates the negative of image1, and covers the original image with the negative, and places the result in image3.
int addShadowWithCoverClear(imgdes *srcimg, imgdes *desimg)
{
imgdes tmpsrc;
// Drop shadow at horiz offset 10, vert offset 5
int hoffset = 10, voffset = 5;
int rcode, cols, rows;
long transcolor = 0xffffff; // White
cols = CALC_WIDTH(srcimg); // Macros in VICDEFS.H
rows = CALC_HEIGHT(srcimg);
// Create the shadow in a temp buffer
rcode = allocimage(&tmpsrc, cols, rows, srcimg->bmh->biBitCount);
if(rcode == NO_ERROR) {
zeroimage(255, &tmpsrc); // Set all pixels to white
tmpsrc.stx = hoffset;
tmpsrc.sty = voffset;
copyimage(srcimg, &tmpsrc); // Copy src image to offset pos
tmpsrc.stx = 0;
tmpsrc.sty = 0;
kodalith(255, &tmpsrc, &tmpsrc); // Turn all pixels not white
to black
changebright(64, &tmpsrc, &tmpsrc); // Black -> dark gray
for(j=0; j<25; j++) // Simulate gaussian blur
blur(&tmpsrc, &tmpsrc);
// Cover the shadow with the original image
rcode = coverclear(transcolor, &tmpsrc, srcimg, desimg);
freeimage(&tmpsrc); // Delete temp image
}
return(rcode);
}
This example creates a drop shadow of all non-white pixels in the image.
int SaveBitmapToTiffFile(HBITMAP hBitmap, HPALETTE hPal)
{
int rcode;
imgdes timage;
LPCSTR fname = "bitmap.tif";
rcode = ddbtoimage(hBitmap, hPal, &timage);
if(rcode == NO_ERROR) {
// Save captured image
rcode = savetif(fname, &timage, 0);
freeimage(&timage);
}
return(rcode);
}
This example saves a device dependent bitmap as a TIFF file.
int defaultpaletteview(HWND hWnd, imgdes *srcimg)
{
int rcode, rows, cols;
HDC hDC;
HPALETTE hpal;
imgdes resimg;
PAINTSTRUCT ps;
rows = srcimg->endy - srcimg->sty + 1;
cols = srcimg->endx - srcimg->stx + 1;
// Allocate temporary 8-bit image for viewing
rcode = allocimage(&resimg, cols, rows, 8);
if(rcode == NO_ERROR) {
// Create default palette in result image
defaultpalette(&resimg);
// Force 24-bit image to use default standard palette
rcode = matchcolorimage(srcimg, &resimg);
if(rcode != NO_ERROR)
MessageBox(hWnd,
"Could not convert RGB to 8-bit image", 0, MB_OK);
else {
hDC = BeginPaint(hWnd, &ps);
// Display the image at (0,0)
rcode = viewimageex(hWnd, hDC, &hpal, 0, 0, &resimg, 0,
0, VIEWDITHER);
EndPaint(hWnd, &ps);
if(rcode != NO_ERROR)
MessageBox(hWnd, "Error displaying image", 0, MB_OK);
}
DeleteObject(hpal);
// Release the temporary 8-bit image
freeimage(&resimg);
}
return(rcode);
}
This example converts an RGB image to an 8-bit palette color image with the default standard palette for display.
int SaveDIBSectToTiffFile(HBITMAP hBitmap)
{
int rcode;
imgdes timage;
LPCSTR fname = "bitmap.tif";
rcode = dibsecttoimage(hBitmap, &timage);
if(rcode == NO_ERROR) {
// Save captured image
rcode = savetif(fname, &timage, 0);
freeimage(&timage);
}
return(rcode);
}
This example saves a DIB section as a TIFF file.
int DrawBitmap(HDC hdc,
int xpos, int ypos, // Horiz, vert displacement to
imgdes *image) // first visible pixel
{
HDC hdcMem;
HBITMAP hBitmap, hBitOld; BITMAP bmap;
int rcode;
SetWindowOrgEx(hdc, xpos, ypos, NULL); // For scrolling
// Create memory DC
hdcMem = CreateCompatibleDC(hdc);
// Create a bitmap of the entire image
rcode = dibtobitmap(hdc, (unsigned char *)image->bmh,
&hBitmap);
if(rcode == NO_ERROR) {
// Select entire bitmap into the memory DC
hBitOld = SelectObject(hdcMem, hBitmap);
// Get bitmap's width and length
GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&bmap);
// Move memory DC to the screen
BitBlt(hdc, 0, 0, bmap.bmWidth, bmap.bmHeight,
hdcMem, 0, 0, SRCCOPY);
// Restore original bitmap to memory DC
SelectObject(hdcMem, hBitOld);
DeleteDC(hdcMem); // Delete memory DC
Delete Object(hBitmap); // Release bitmap
}
return(rcode);
}
This example creates a device dependent bitmap from a DIB and transfers it to a device context.
int GetClipping(HWND hwnd, imgdes *image)
{
#define NO_CLIPBRD_DIB -38
#define NO_CLIPBRD -39
unsigned char *dib;
int rcode=NO_ERROR, oclip;
HGLOBAL hMem;
// Open clipboard
if((oclip = OpenClipboard(hwnd)) != 0) {
// Get DIB from clipboard
if((hMem = GetClipboardData(CF_DIB)) != 0) {
// Get address of DIB
dib = (unsigned char *)GlobalLock(hMem);
// Create a new image from the DIB
rcode = dibtoimage(dib, image);
}
else
rcode = NO_CLIPBRD_DIB; // No DIB on clipboard
}
else
rcode = NO_CLIPBRD; // Could not open clipboard
if(hMem) // Unlock memory before closing the clipboard
GlobalUnlock(hMem);
if(oclip)
CloseClipboard(); // Close the clipboard
return(rcode);
}
This example creates an image from a DIB on the clipboard.
int darkenByDilation(HWND hWnd, imgdes *image)
{
int rcode, amount = 200;
rcode = dilate(amount, image, image);
if(rcode != NO_ERROR)
MessageBox(hWnd, "Error in darken by dilation", 0, MB_OK);
return(rcode);
}
This example darkens an image using dilation.
int posterize(HWND hWnd, imgdes *image1, imgdes *image2)
{
int rcode, factor=32;
if((rcode=divide(factor, image1, image2)) == NO_ERROR) {
if((rcode=multiply(factor, image2, image2)) != NO_ERROR)
MessageBox(hWnd,"Error at multiply", 0, MB_OK);
}
else
MessageBox(hWnd,"Error at divide", 0, MB_OK);
return(rcode);
}
This example divides an image by 32, multiplies it by 32, and places the result in image2 to create an 8-level posterization effect.
int brightenByErosion(HWND hWnd, imgdes *image)
{
int rcode, amount = 200;
rcode = erode(amount, image, image);
if(rcode != NO_ERROR)
MessageBox(hWnd, "Error in brighten by erosion", 0, MB_OK);
return(rcode);
}
This example brightens an image using erosion.
int hilite(HWND hWnd, imgdes *image)
{
int rcode, white=255, black=0;
if((rcode=exchangelevel(20, 25, white, image,
image)) == NO_ERROR) {
if((rcode=exchangelevel(26,30, black, image,
image)) != NO_ERROR)
MessageBox(hWnd,"Error at setting black", 0, MB_OK);
}
else
MessageBox(hWnd,"Error at setting white", 0, MB_OK);
return(rcode);
}
This example sets pixels between 20 - 25 to white, and pixels between 26 - 30 to black.
int contrast(HWND hWnd, imgdes *image)
{
int rcode, ravg, gavg, bavg, val, low, high;
rcode = calcavglevel(image, &ravg, &gavg, &bavg);
if(rcode == NO_ERROR) { // Make sure avg is valid
val = (ravg * 25 / 100);
low = ravg - val;
high = (val+ravg > 255) ? 255 : (ravg+val);
if((rcode=expandcontrast(low, high, image,
image)) != NO_ERROR)
MessageBox(hWnd,"Error in expanding contrast", 0, MB_OK);
}
else
MessageBox(hWnd,"Error at calcavglevel()", 0, MB_OK);
return(rcode);
}
This example increases the contrast based on the average brightness value.
int flip(HWND hWnd, imgdes *image1, imgdes *image2)
{
int rcode;
LPCSTR fname="tree.gif";
if((rcode=loadgif(fname, image1)) == NO_ERROR) {
if((rcode==flipimage(image1, image2)) != NO_ERROR)
MessageBox(hWnd,"Error in flipping image", 0, MB_OK);
}
else
MessageBox(hWnd,"Error in loading file", 0, MB_OK);
return(rcode);
}
This example loads an image and places a flipped copy in another buffer.
int MakeBackUp(imgdes *image, imgdes *backup, RECT *backrect)
{
int rcode, rows, cols;
rows = image->endy - image->sty + 1;
cols = image->endx - image->stx + 1;
// If an old backup exists, delete it
if(backup->bmh)
freeimage(backup);
// Allocate our backup DIB
if((rcode=allocimage(backup, cols, rows,
image->bmh->biBitCount)) == NO_ERROR) {
// Save original image area coordinates
imageareatorect(image, backrect);
// Copy the image area into the backup buffer
rcode = copyimage(image, backup);
}
return(rcode);
}
This example makes a backup copy of an image area and palette.
void gamma_correction(HWND hWnd, imgdes *image)
{
HCURSOR hSaveCursor;
double gamma = 0.5;
// Display hourglass cursor
hSaveCursor = SetCursor(LoadCursor(0, IDC_WAIT));
if(gammabrighten(gamma, image, image) != NO_ERROR)
MessageBox(hWnd,"Error in gamma correction", 0, MB_OK);
SetCursor(hSaveCursor); // Restore cursor
}
This example brightens an image by applying a gamma correction of 0.5 each time it is called.
void readgifcomment(HWND hWnd, char *fname)
{
int rcode, comlen;
char buff[80], near *combuff;
rcode = getgifcomment(fname, NULL, 0); // Get comment length
switch(rcode) {
case(BAD_OPN):
wsprintf(buff, "Cannot open %s", (LPSTR)fname); break;
case(BAD_GIF):
wsprintf(buff, "Bad GIF: %s", (LPSTR)fname); break;
case(0):
wsprintf(buff, "No comment in %s", (LPSTR)fname); break;
default: // Getgifcomment() returned length of comment
comlen = rcode; // Save length of comment
// Allocate space for comment string
combuff = (char near *)LocalAlloc(LPTR, comlen + 1);
if(combuff == NULL) {
wsprintf(buff, "Insufficient memory");
rcode = BAD_MEM;
}
else { // Get the comment
getgifcomment(fname, combuff, comlen + 1);
// Display comment in message box
MessageBox(hWnd, combuff, 0, MB_OK);
LocalFree((HLOCAL)combuff);
}
}
if(rcode <= 0) // If error, display error message
MessageBox(hWnd, buff, 0, MB_OK);
}
This example reads and displays a comment string in a GIF file.
void get_icolumn(HWND hWnd, imgdes *image, int xx, int yy)
{
#define GET_BLU(c) (int)(((c) >> 16) & 0xff)
#define GET_GRN(c) (int)(((c) >> 8) & 0xff)
#define GET_RED(c) (int)((c) & 0xff)
long color;
int red, grn, blu;
char szBuff[80];
char *str;
color = getpixelcolor(image, xx, yy);
if(color >= 0) { // Indicates no errors
if(image->bmh->biBitCount <= 8)
wsprintf(szBuff,
"Color value at (%d,%d) is %d, %d bpp", xx, yy,
(int)color, (int)image->bmh->biBitCount);
else { // 24-bit image
blu = GET_BLU(color);
grn = GET_GRN(color);
red = GET_RED(color);
wsprintf(szBuff, "Color value at (%d,%d) is red: %d, "
"green: %d, blue: %d, %d bpp", xx, yy, red, grn, blu,
(int)image->bmh->biBitCount);
}
MessageBox(hWnd, szBuff, 0, MB_OK);
}
else { // Error if color < 0
switch((int)color) { // Assign error message
case BAD_RANGE: str="Range error";
case BAD_BPP: str="Bits per pixel not 1, 8, or 24";
}
MessageBox(hWnd, str, 0, MB_OK);
}
}
This example displays the color of a pixel and the bits per pixel of the image.
void readAPNGComment(HWND hWnd, char *fname)
{
int rcode, comlen;
char buff[80], near *combuff;
// Get comment length
rcode = getpngcomment(fname, "Comment", 0, 0);
switch(rcode) {
case(BAD_OPN):
wsprintf(buff, "Cannot open %s", (LPSTR)fname); break;
case(BAD_PNG):
wsprintf(buff, "Bad PNG: %s", (LPSTR)fname); break;
case(0):
wsprintf(buff, "No comment in %s", (LPSTR)fname); break;
default: // Getpngcomment() returned length of comment
comlen = rcode; // Save length of comment
// Allocate space for comment string
combuff = (char near *)calloc(comlen + 1, sizeof(char));
if(combuff == NULL) {
wsprintf(buff, "Insufficient memory");
rcode = BAD_MEM;
}
else { // Get the comment
getgifcomment(fname, combuff, comlen + 1);
// Display comment in message box
MessageBox(hWnd, combuff, 0, MB_OK);
free(combuff);
}
}
if(rcode <= 0) // If error, display error message
MessageBox(hWnd, buff, 0, MB_OK);
}
This example reads and displays a comment string in a PNG file.
void gifsize(HWND hWnd, char *fname)
{
GifData gdat; // Reserve space for structure
int rcode;
char szBuff[80];
rcode = gifinfo(fname, &gdat);
if(rcode == BAD_OPN) {
wsprintf(szBuff, "Could not find %s", (LPSTR)fname);
MessageBox(hWnd, szBuff, 0, MB_OK);
}
else if(rcode == BAD_GIF) {
wsprintf(szBuff, "%s is not a GIF file", (LPSTR)fname);
MessageBox(hWnd, szBuff, 0, MB_OK);
}
else {
wsprintf(szBuff,
"%s image dimensions: Width=%d, Length=%d",
(LPSTR)fname, gdat.width, gdat.length);
MessageBox(hWnd, szBuff, 0, MB_OK);
}
}
This example reads a GIF file and prints the image size.
// Load a frame from a GIF file
int load_a_frame(LPTSTR fname, int framenumber, imgdes *image)
{
GifData gifdat;
int rcode;
imgdes tempimage;
int totalFrames;
GifGlobalData gdata;
GifFrameData fdata;
rcode = gifframecount(fname, &totalFrames); // Count the number of frames
if(framenumber < totalFrames);
rcode = gifinfoframe(fname, &gifdat, &gdata, &fdata, framenumber);
if(rcode == NO_ERROR) {
// Allocate an image buffer to hold the frame
if((rcode = allocimage(&tempimage, gifdat.width, gifdat.length, gifdat.vbitcount)) == NO_ERROR)
rcode = loadgifframe(fname, &tempimage, &gdata, &fdata]);
}
// Replace original image with this new image of a single gif frame
if(rcode == NO_ERROR || rcode == BAD_DATA) {
freeimage(image);
copyimgdes(&tempimage, image);
rcode = NO_ERROR; // Set rcode to NO_ERROR if file contained invalid data
}
return(rcode);
}
This example loads a single frame from a GIF file.
void brightenhisto(HWND hWnd, imgdes *image)
{
if(histobrighten(image, image) != NO_ERROR)
MessageBox(hWnd,"Error in brightening image", 0, MB_OK);
}
This example brightens an image and increases contrast.
void equalizehisto(HWND hWnd, imgdes *image)
{
if(histoequalize(image, image) != NO_ERROR)
MessageBox(hWnd,"Error in equalizing histogram", 0, MB_OK);
}
This example brightens an image through histogram equalization.
void hsv_to_rgb(int colors, // Number of HSVTRIPLEs to convert
HSVTRIPLE *hsvtab, imgdes *image)
{
hsv2rgb(hsvtab, image->palette, colors);
image->colors = colors;
}
This example converts an HSV table to a color palette associated with an image.
void CopyDIBToClipboard(HWND hWnd, imgdes *image)
{
int rcode=NO_ERROR;
HGLOBAL hMem;
UCHAR huge *dib;
if(OpenClipboard(hWnd)) { // Open clipboard
EmptyClipboard();
// 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 = GlobalPtrHandle(dib);
// Unlock the handle to the DIB
GlobalUnlock(hMem);
// Pass the DIB to the clipboard
SetClipboardData(CF_DIB, hMem);
}
CloseClipboard();
}
if(rcode != NO_ERROR)
MessageBox(hWnd, "Error copying DIB to clipboard", 0,
MB_OK);
}
This example creates a DIB from an image and passes the DIB to the clipboard.
int loadAJpegFile(HWND hWnd, char *fname, imgdes *image)
{
JpegData jdat;
int rcode;
// Get info on the file we're to load
rcode = jpeginfo(fname, &jdat);
if(rcode == NO_ERROR) { // Fill structure
// Allocate space for an image
rcode = allocimage(image, (int)jdat.width, (int)jdat.length, jdat.vbitcount);
if(rcode == NO_ERROR) {
// Load image
rcode = loadjpg(fname, image);
if(rcode == BAD_JPEG) {
char szBuff[128];
// Get extended error info
int extRcode = jpeggeterror();
wsprintf(szBuff, "Error in loading %s: extended error code %d", (LPSTR)fname, extRcode);
MessageBox(hWnd, szBuff, 0, MB_OK);
}
freeimage(image); // Free image on error
}
}
return(rcode);
}
This function reports extended error information when a JPEG file cannot be loaded.
void jpegInfo(HWND hWnd, char *fname)
{
JpegData jdat; // Reserve space for structure
int rcode;
char szBuff[80], *typstr;
rcode = jpeginfo(fname, &jdat);
if(rcode == BAD_OPN) {
wsprintf(szBuff, "Could not find %s", (LPSTR)fname);
MessageBox(hWnd, szBuff, 0, MB_OK);
}
else if(rcode == BAD_JPEG) {
wsprintf(szBuff, "%s is not a JPEG JFIF file",
(LPSTR)fname);
MessageBox(hWnd, szBuff, 0, MB_OK);
}
else {
typstr = (jdat.comps == 1) ? "grayscale" : "color";
wsprintf(szBuff, "%s is a %s JPEG image %d X %d pixels",
(LPSTR)fname, (LPSTR)typstr, jdat.width, jdat.length);
MessageBox(hWnd, szBuff, 0, MB_OK);
}
}
This example reads a JPEG file and displays the image size.
int trace(HWND hWnd, imgdes *image1, imgdes *image2)
{
int rcode, rval, gval, bval;
HCURSOR hSaveCursor;
// Display hourglass cursor
hSaveCursor = SetCursor(LoadCursor(0, IDC_WAIT));
rcode = calcavglevel(image1, &rval, &gval, &bval);
if(rcode == NO_ERROR) {
if((rcode=kodalith(rval, image1, image2)) == NO_ERROR) {
if((rcode=outline(image2, image2)) != NO_ERROR)
MessageBox(hWnd,"Error at outline()", 0, MB_OK);
}
else
MessageBox(hWnd,"Error at kodalith()", 0, MB_OK);
}
else
MessageBox(hWnd,"Error at calcavglevel()", 0, MB_OK);
SetCursor(hSaveCursor); // Restore cursor
return(rcode);
}
This example calculates a kodalith level then outlines the image.
int limit240(HWND hWnd, imgdes *image)
{
int rcode, max=240;
HCURSOR hSaveCursor;
// Display hourglass cursor
hSaveCursor = SetCursor(LoadCursor(0, IDC_WAIT));
rcode = limitlevel(max, image, image);
if(rcode != NO_ERROR)
MessageBox(hWnd,"Error at limitlevel()", 0, MB_OK);
SetCursor(hSaveCursor); // Restore cursor
return(rcode);
}
This example limits the maximum intensity level in the image to 240.
int load_bif(HWND hWnd, char *fname, imgdes *image)
{
// BIF files must have predefined width and length
int width=512, length=480;
OFSTRUCT of;
int rcode=BAD_OPN; // Assume file does not exist
// Make sure file exists
if(OpenFile(fname, &of, OF_READ | OF_EXIST) == -1) {
MessageBox(hWnd,"Error in opening file", 0, MB_OK);
return(rcode);
}
// Allocate space for an 8-bit image
rcode = allocimage(image, width, length, 8);
if(rcode != NO_ERROR) {
MessageBox(hWnd,"Not enough memory to load file", 0, MB_OK);
return(rcode);
}
// Load image
rcode = loadbif(fname, image);
if(rcode != NO_ERROR) // Free image on error
freeimage(image);
return(rcode);
}
This example allocates space for and loads a BIF image.
int load_bmp(HWND hWnd, char *fname, imgdes *image)
{
BITMAPINFOHEADER bminfo;
int rcode, bppixel;
// Get info on the file we're to load
rcode = bmpinfo(fname, &bminfo);
if(rcode != NO_ERROR) { // Fill structure
MessageBox(hWnd,"Error in reading file", 0, MB_OK);
return(rcode);
}
bppixel = bminfo.biBitCount;
// Allocate space for an image
rcode = allocimage(image, (int)bminfo.biWidth,
(int)bminfo.biHeight, bppixel);
if(rcode != NO_ERROR) {
MessageBox(hWnd,"Not enough memory to load file",
0, MB_OK);
return(rcode);
} // Load image
rcode = loadbmp(fname, image);
if(rcode != NO_ERROR) // Free image on error
freeimage(image);
return(rcode);
}
This example allocates space for and loads a BMP image.
int getBMPpal(HWND hWnd, char *fname,
// paltable must be sizeof(RGBQUAD) * (1 << biBitCount)
RGBQUAD *paltable)
{
int colors;
char szBuff[80];
colors = loadbmppalette(fname, paltable); // Load palette data
if(colors >= 0) // Check range for error
wsprintf(szBuff, "%s contains %d colors", (LPSTR)fname,
colors);
else
wsprintf(szBuff, "Error on loading palette of %s",
(LPSTR)fname);
MessageBox(hWnd, szBuff, 0, MB_OK); return(colors);
}
This example loads a BMP color palette into an array and if there are no errors, displays the number of palette colors loaded.
int load_gif(HWND hWnd, char *fname, imgdes *image)
{
GifData gdat;
int rcode;
// Get info on the file we're to load
rcode = gifinfo(fname, &gdat);
if(rcode != NO_ERROR) { // Fill structure
MessageBox(hWnd,"Error in reading file", 0, MB_OK);
return(rcode);
} // Allocate space for an 8-bit image
rcode = allocimage(image, gdat.width, gdat.length,
gdat.vbitcount);
if(rcode != NO_ERROR) {
MessageBox(hWnd,"Not enough memory to load file", 0, MB_OK);
return(rcode);
}
// Load image
rcode = loadgif(fname, image);
if(rcode != NO_ERROR) {
freeimage(image); // Free image on error
MessageBox(hWnd, "Could not load file", 0, MB_OK);
}
return(rcode);
}
This example allocates space for and loads a GIF image.
// Load a GIF file
int load_animated_gif(LPTSTR fname, imgdes *image)
{
GifData gifdat; // Reserve space for struct
int rcode;
int totalFrames;
GifGlobalData gdata;
GifFrameData *fdatarray; // Array of GifFrameData structures
HANDLE hmem;
int size;
int tempimage;
// Loading all frames from a gif into a single vertical image
rcode = gifframecount(fname, &totalFrames); // Count the number of frames
size = sizeof(GifFrameData);
fdatarray = (GifFrameData *)calloc(totalFrames, size);
rcode = gifinfoallframes(fname, &gdata, fdatarray, totalFrames); // Get all the frame info
if(rcode == NO_ERROR) {
int j;
// Allocate an image buffer to hold all the frames
if((rcode = allocimage(&tempimage, gdata.saveData.scrwidth, gdata.saveData.scrlength * totalFrames, fdatarray[0].vbitcount)) == NO_ERROR)
zeroimage(gdata.saveData.bckColor, &tempimage); // Set the background color
// Load all frames
for(j=0; j < totalFrames; j++) {
tempimage.stx = fdatarray[j].saveData.startx ;
tempimage.sty = j * gdata.saveData.scrlength + fdatarray[j].saveData.starty ;
rcode = loadgifframe(fname, &tempimage, &gdata, &fdatarray[j]);
}
tempimage.stx = 0;
tempimage.sty = 0;
}
// Replace original image with this new image of gif frames
if(rcode == NO_ERROR || rcode == BAD_DATA) {
freeimage(image);
copyimgdes(&tempimage, image);
rcode = NO_ERROR; // Set rcode to NO_ERROR if file contained invalid data
}
return(rcode);
}
This example loads all the frames from a multiframe GIF into a single image.
int getGIFpal(HWND hWnd, char *fname,
RGBQUAD *paltable) //paltable must be sizeof(RGBQUAD) * 256
{
int colors;
char szBuff[80];
// Load palette data
colors = loadgifpalette(fname, paltable);
if(colors >= 0) // Check range for error
wsprintf(szBuff, "%s contains %d colors", (LPSTR)fname,
colors);
else
wsprintf(szBuff, "Error on loading palette of %s",
(LPSTR)fname);
MessageBox(hWnd, szBuff, 0, MB_OK);
return(colors);
}
This example loads a GIF color palette into an array and if there are no errors, displays the number of palette colors loaded.
int getGIFframepal(HWND hWnd, char *fname,
RGBQUAD *paltable) //paltable must be sizeof(RGBQUAD) * 256
{
int colors;
char szBuff[80];
int framenumber;
framenumber = 0;
// Load palette data
colors = loadgifframepalette(fname, paltable, framenumber);
if(colors >= 0) // Check range for error
wsprintf(szBuff, "%s contains %d colors", (LPSTR)fname,
colors);
else
wsprintf(szBuff, "Error on loading palette of %s",
(LPSTR)fname);
MessageBox(hWnd, szBuff, 0, MB_OK);
return(colors);
}
This example loads the palette associated with the specified frame number.
int getGIFglobalpal(HWND hWnd, char *fname,
RGBQUAD *paltable) //paltable must be sizeof(RGBQUAD) * 256
{
int colors;
char szBuff[80];
// Load palette data
colors = loadgifglobalpalette(fname, paltable);
if(colors >= 0) // Check range for error
wsprintf(szBuff, "%s contains %d colors", (LPSTR)fname,
colors);
else
wsprintf(szBuff, "Error on loading palette of %s",
(LPSTR)fname);
MessageBox(hWnd, szBuff, 0, MB_OK);
return(colors);
}
This example loads a GIF global palette into an array and if there are no errors, displays the number of palette colors loaded.
int load_jpg(HWND hWnd, char *fname, imgdes *image)
{
JpegData jdat;
int rcode;
// Get info on the file we're to load
rcode = jpeginfo(fname, &jdat);
if(rcode != NO_ERROR) { // Fill structure
MessageBox(hWnd, "Error in reading file", 0, MB_OK);
return(rcode);
}
// Allocate space for an image
rcode = allocimage(image, (int)jdat.width, (int)jdat.length,
jdat.vbitcount);
if(rcode != NO_ERROR) {
MessageBox(hWnd,"Not enough memory to load file", 0, MB_OK);
return(rcode);
}
// Load image
rcode = loadjpg(fname, image);
if(rcode != NO_ERROR) {
freeimage(image); // Free image on error
MessageBox(hWnd, "Could not load file", 0, MB_OK);
}
return(rcode);
}
This example allocates space for and loads a JPEG image.
int loadJpgfilesfrombuffer(HWND hWnd, char *fname, imgdes *image)
{
#include <io.h>
#define FILES_TO_LOAD dim(fileInfo)
#define BAD_READ -87
typedef struct { char *name; DWORD size; } FILE_INFO;
JpegData jdat; // Reserve space for struct
int j, bytesRead, rcode = NO_ERROR;
OFSTRUCT of_st;
UCHAR huge *jpegbuff, huge *des;
HFILE fhandle;
DWORD memTotal;
FILE_INFO fileInfo[] = {
{ "d:pic1.jpg", 0L },
{ "d:pic2.jpg", 0L },
{ "d:pic3.jpg", 0L },
{ "d:pic4.jpg", 0L },
};
// Load JPEG files into buffer
memTotal = 0;
for(j=0; j<FILES_TO_LOAD; j++) {
if((fhandle = OpenFile(fileInfo[j].name, &of_st,
OF_READ)) < 0)
return(BAD_OPN);
// Get filesize
#if defined WIN32 || defined _WIN32
fileInfo[j].size = GetFileSize((HANDLE)fhandle, NULL);
#else
fileInfo[j].size = _filelength(fhandle);
#endif
memTotal += fileInfo[j].size;
_lclose(fhandle); // Close the file
}
// Allocate memory to hold files
jpegbuff = (UCHAR huge *)GlobalAllocPtr(GMEM_MOVEABLE,
memTotal);
if(jpegbuff == 0)
return(BAD_MEM); // Allocation failed!
// Load JPEG files into memory
des = jpegbuff;
for(j=0; j<FILES_TO_LOAD; j++) {
if((fhandle = OpenFile(fileInfo[j].name, &of_st,
OF_READ)) < 0)
return(BAD_OPN);
// For 16-bit Windows JPEG files must be less than 64Kb
bytesRead = _lread(fhandle, des,
(unsigned)fileInfo[j].size);
if(bytesRead <= 0)
rcode = BAD_READ;
_lclose(fhandle); // Close the file
des += fileInfo[j].size;
}
// Load the JPEG files from the buffer
des = jpegbuff;
for(j=0; j<FILES_TO_LOAD; j++) {
char szBuff[80];
// Make sure file exists and get its dimensions
rcode = jpeginfofrombuffer(des, &jdat);
if(rcode == NO_ERROR) {
// Release the current image buffer
freeimage(image);
// Try to allocate the new image buffer to the file
// dimensions
rcode = allocimage(image, jdat.width, jdat.length,
jdat.vbitcount);
if(rcode == NO_ERROR) {
// Load the image
rcode = loadjpgfrombuffer(des, image);
if(rcode == NO_ERROR) {
// Display pic
ShowWindow(hWnd, SW_SHOWNORMAL);
UpdateWindow(hWnd);
wsprintf((LPSTR)szBuff, (LPSTR)"File %s
loaded",(LPSTR)fileInfo[j].name);
MessageBox(hWnd, szBuff, "Load JPEG from
Buffer", MB_OK);
}
}
}
des += fileInfo[j].size;
}
if(jpegbuff)
GlobalFreePtr(jpegbuff); // Free any allocated memory
return(rcode);
}
This example loads four JPEG files from a buffer.
int load_thumbnail(HWND hwnd, char *fname, imgdes *image)
{
JpegDataEx jdatex; // Reserve space for struct
int rcode, width, length, bitcount;
// Use embedded thumbnail if present
BOOL createThumbNail = FALSE;
int thumbSize = 64; // Max width or length
// Make sure file exists and get its dimensions
if((rcode = jpeginfoex(fname, &jdatex)) == NO_ERROR) {
// Load embedded thumbnail if thumbnail exists and
// createThumbNail flag is FALSE
if(jdatex.thumbNail.hasThumbNail == TRUE &&
createThumbNail == FALSE)
bitcount = jdatex.thumbNail.bitcount;
else
bitcount = jdatex.vbitcount;
// Alloc a square image buffer
width = length = thumbSize;
rcode = allocimage(image, width, length, bitcount);
if(rcode == NO_ERROR) {
zeroimage(0xff, image); // Set background to white
// Load the image
rcode = loadjpgthumbnail(fname, image, createThumbNail);
}
}
if(rcode != NO_ERROR) {
freeimage(image); // Free image on error
MessageBox(hWnd, "Could not load thumbnail", 0, MB_OK);
}
return(rcode);
}
This example allocates space for and loads a JPEG thumbnail image.
int load_pcx(HWND hWnd, char *fname, imgdes *image)
{
PcxData pdat;
int rcode;
// Get info on the file we're to load
rcode = pcxinfo(fname, &pdat);
if(rcode != NO_ERROR) { // Fill structure
MessageBox(hWnd,"Error in reading file", 0, MB_OK);
return(rcode);
}
// Allocate space for an image
rcode = allocimage(image, pdat.width, pdat.length,
pdat.vbitcount);
if(rcode != NO_ERROR) {
MessageBox(hWnd,"Not enough memory to load file", 0, MB_OK);
return(rcode);
}
// Load image
rcode = loadpcx(fname, image);
if(rcode != NO_ERROR) // Free image on error
freeimage(image);
return(rcode);
}
This example allocates space for and loads a PCX image.
int getPCXpal(HWND hWnd, char *fname,
RGBQUAD *paltable) // paltable size -- see table above
{
int colors;
char szBuff[80];
// Load palette data
colors = loadpcxpalette(fname, paltable);
if(colors >= 0) // Check range for error
wsprintf(szBuff, "%s contains %d colors", (LPSTR)fname,
colors);
else
wsprintf(szBuff, "Error on loading palette of %s",
(LPSTR)fname);
MessageBox(hWnd, szBuff, 0, MB_OK);
return(colors);
}
This example loads a PCX color palette into an array and if there are no errors, displays the number of palette colors loaded.
int loadAPng(HWND hWnd, char *fname, imgdes *image)
{
PngData pdat;
int rcode;
// Get info on the file we're to load
rcode = pnginfo(fname, &pdat);
if(rcode != NO_ERROR) { // Fill structure
MessageBox(hWnd,"Error in reading file", 0, MB_OK);
return(rcode);
}
// Allocate space for the image
rcode = allocimage(image, pdat.width, pdat.length, pdat.vbitcount);
if(rcode != NO_ERROR) {
MessageBox(hWnd,"Not enough memory to load file", 0, MB_OK);
return(rcode);
}
// Load image
rcode = loadpng(fname, image);
if(rcode != NO_ERROR) {
char szBuff[80];
wsprintf(szBuff, "Could not load %s", fname);
MessageBox(hWnd, szBuff, 0, MB_OK);
}
freeimage(image); // Free image on error
return(rcode);
}
This example loads an image from a PNG file.
int getPNGpal(HWND hWnd, char *fname,
RGBQUAD *paltab) // paltab must be sizeof(RGBQUAD) * 256
{
int colors;
char szBuff[80];
// Load palette data
colors = loadpngpalette(fname, paltab);
if(colors >= 0) // Check range for error
wsprintf(szBuff, "%s contains %d colors", (LPSTR)fname, colors);
else
wsprintf(szBuff, "Error on loading palette of %s", (LPSTR)fname);
MessageBox(hWnd, szBuff, 0, MB_OK);
return(colors);
}
This example loads a PNG color palette into an array and if there are no errors, displays the number of palette colors loaded.
int load_tga(HWND hWnd, char *fname, imgdes *image)
{
TgaData tgdat;
int rcode;
// Get info on the file we're to load
rcode = tgainfo(fname, &tgdat);
if(rcode != NO_ERROR) { // Fill structure
MessageBox(hWnd,"Error in reading file", 0, MB_OK);
return(rcode);
}
// Allocate space for an image
rcode = allocimage(image, tgdat.width, tgdat.length,
tgdat.vbitcount);
if(rcode != NO_ERROR) {
MessageBox(hWnd,"Not enough memory to load file", 0, MB_OK);
return(rcode);
}
rcode = loadtga(fname, image);
if(rcode != NO_ERROR) // Free image on error
freeimage(image);
return(rcode);
}
This example allocates space for and loads a Targa true color file.
int getTGApal(HWND hWnd, char *fname,
RGBQUAD *paltable) //paltable must be sizeof(RGBQUAD) * 256
{
int colors;
char szBuff[80];
// Load palette data
colors = loadtgapalette(fname, paltable);
if(colors >= 0) // Check range for error
wsprintf(szBuff, "%s contains %d colors", (LPSTR)fname,
colors);
else
wsprintf(szBuff, "Error on loading palette of %s",
(LPSTR)fname);
MessageBox(hWnd, szBuff, 0, MB_OK);
return(colors);
}
This example loads a Targa color palette into an array and if there are no errors, displays the number of palette colors loaded.
int load_tif(HWND hWnd, char *fname, imgdes *image)
{
TiffData tdat;
int rcode;
// Get info on the file we're to load
rcode = tiffinfo(fname, &tdat);
if(rcode != NO_ERROR) { // Fill structure
MessageBox(hWnd,"Error in reading file", 0, MB_OK);
return(rcode);
}
// Allocate space for an image
rcode = allocimage(image, tdat.width, tdat.length,
tdat.vbitcount);
if(rcode != NO_ERROR) {
MessageBox(hWnd,"Not enough memory to load file", 0, MB_OK);
return(rcode);
}
rcode = loadtif(fname, image);
if(rcode != NO_ERROR) // Free image on error
freeimage(image);
return(rcode);
}
This example allocates space for and loads a TIFF image.
int loadMultiTiff(HWND hWnd, char *filename, imgdes *image,
int pageToLoad)
{
// Returns no. of elements
#define dim(x) (sizeof(x) / sizeof(x[0]))
TiffData tdat; // Reserve space for struct
int indx, rcode;
int pageArray[16]; // Allow room for 16 pages
int totalPages;
BOOL pageFound;
// Fill the page array
rcode = tiffgetpageinfo(filename, &totalPages, pageArray,
dim(pageArray));
if(rcode == NO_ERROR) {
pageFound = FALSE; // Assume page to load is NOT in the file
// Make sure page to load is in the file
for(j=0; j<totalPages; j++) {
if(pageToLoad == pageArray[j]) {
pageFound = TRUE;
break;
}
}
// Handle "page not found" error
if(pageFound == FALSE) {
char szBuff[80];
wsprintf(szBuff, "Page %d not found in %s", pageToLoad,
(LPSTR)fname);
MessageBox(hWnd, szBuff, "Error!", MB_OK);
}
else { // Found page to load in TIFF file, load it
// Get the dimensions of the page to load
if((rcode = tiffinfopage(filename, &tdat, pageToLoad)) ==
NO_ERROR) {
// Allocate an image buffer based on the file dimensions
if((rcode = allocimage(image, tdat.width, tdat.length,
tdat.vbitcount)) == NO_ERROR)
// Load the image
rcode = loadtifpage(fname, image, pageToLoad);
}
}
return(rcode);
}
This example loads a specific page (image) from a single or multipage TIFF file.
int getTIFpal(HWND hWnd, char *fname,
RGBQUAD *paltable) //paltable must be sizeof(RGBQUAD) * 256
{
int colors;
char szBuff[80];
// Load palette data
colors = loadtifpalette(fname, paltable);
if(colors >= 0) // Check range for error
wsprintf(szBuff, "%s contains %d colors", (LPSTR)fname,
colors);
else
wsprintf(szBuff, "Error on loading palette of %s",
(LPSTR)fname);
MessageBox(hWnd, szBuff, 0, MB_OK);
return(colors);
}
This example loads a TIFF color palette into an array and if there are no errors, displays the number of palette colors loaded.
int getTIFpalpage(HWND hWnd, char *fname,
RGBQUAD *paltable) //paltable must be sizeof(RGBQUAD) * 256
{
int colors, pageno=2;
char szBuff[80];
int pageno;
// Load palette data
colors = loadtifpalettepage(fname, paltable, pageno);
if(colors >= 0) // Check range for error
wsprintf(szBuff, "%s contains %d colors", (LPSTR)fname,
colors);
else
wsprintf(szBuff, "Error on loading palette from page 2 of %s",
(LPSTR)fname);
MessageBox(hWnd, szBuff, 0, MB_OK);
return(colors);
}
This example loads a TIFF color palette into an array and if there are no errors, displays the number of palette colors loaded.
// Force three images to use same palette. Images must be 8-bit!
int matchupEx(imgdes *farm, imgdes *city, imgdes *lake)
{
int rcode;
imgdes timage;
int colmatchmode = CR_TDSNODIFF;
// Force city and lake to use farm palette
// Match city and lake to farm
copyimgdes(city, &timage);
timage.palette = farm->palette;
timage.colors = farm->colors;
// Force city to use farm's palette
rcode = matchcolorimageex(city, &timage, colmatchmode);
if(rcode == NO_ERROR) {
copyimagepalette(farm, city); // Replace city's palette
city->colors = farm->colors;
copyimgdes(lake, &timage);
timage.palette = farm->palette;
timage.colors = farm->colors;
// Force city to use farm's palette
rcode = matchcolorimageex(lake, &timage, colmatchmode);
copyimagepalette(farm, lake); // Replace lake's palette
lake->colors = farm->colors;
}
return(rcode);
}
This example forces two images to use the palette of a third image.
int combineImagesEx(HWND hWnd, imgdes *simage1, imgdes *simage2)
{
int imgnum, rcode;
imgdes timage, *image;
int colmatchmode= CR_OCTREEDIFF;
image = simage1; // Setup for first image
for(imgnum=0; imgnum<2; imgnum++) {
// Allocate 8-bit buffer for the converted image
rcode = allocimage(&timage, (int)image->bmh->biWidth,
(int)image->bmh->biHeight, 8);
if(rcode == NO_ERROR) {
rainbowpalette(&timage); // Use a standard palette
// Match the image to the palette
rcode = matchcolorimageex(image, &timage, colmatchmode);
if(rcode == NO_ERROR) {
// Replace image with timage, free source image
freeimage(image);
copyimgdes(&timage, image);
}
else { // matchcolorimageex() failed, release timage
freeimage(&timage);
MessageBox(hWnd, "Error in matching color palette",
0,MB_OK);
break;
}
}
image = simage2; // Setup for second image
}
return(rcode);
}
This example matches two 24- or 8-bit images to a single rainbow palette and replaces the original images.
int detect_horiz(HWND hWnd, imgdes *image)
{
static char dethoriz[] = {1, 1, 1, 0, 0, 0, -1, -1, -1, 1 };
int rcode;
if((rcode=matrixconv(dethoriz, image, image)) != NO_ERROR)
MessageBox(hWnd,"Error at matrixconv()", 0, MB_OK);
return(rcode);
}
This example emphasizes the horizontal lines in an image.
int detect_horiz2(HWND hWnd, imgdes *image)
{
static char dethoriz[] = {1, 1, 1, 0, 0, 0, -1, -1, -1};
int divsr = 1;
int rcode;
rcode = matrixconvex(3, dethoriz, divsr, image, image);
if(rcode != NO_ERROR)
MessageBox(hWnd,"Error at matrixconvex()", 0, MB_OK);
return(rcode);
}
This example emphasizes the horizontal lines in an image.
int watercolor(HWND hWnd, imgdes *image)
{
int rcode;
rcode = medianfilter(3, image, image);
if(rcode != NO_ERROR)
MessageBox(hWnd,"Error at matrixconvex()", 0, MB_OK);
else {
medianfilter(5, image, image);
medianfilter(7, image, image);
sharpen(image, image);
}
return(rcode);
}
This example creates a watercolor painting effect in an image.
int mirror(HWND hWnd, char *fname, imgdes *image)
{
int rcode;
char szBuff[80];
if((rcode=loadtif(fname, image)) == NO_ERROR) {
if((rcode=mirrorimage(image, image)) == NO_ERROR) {
if((rcode=savetif(fname, image, 0)) != NO_ERROR) {
wsprintf(szBuff, "Error in saving %s", (LPSTR)fname);
MessageBox(hWnd, szBuff, 0, MB_OK);
}
}
else
MessageBox(hWnd,"Error at mirrorimage()", 0, MB_OK);
}
else {
wsprintf(szBuff, "Error in loading %s", (LPSTR)fname);
MessageBox(hWnd, szBuff, 0, MB_OK);
}
return(rcode);
}
This example loads an image, mirrors it for creating an iron-on transfer, and saves it.
int negtrace(HWND hWnd, imgdes *image1, imgdes *image2)
{
int rcode;
HCURSOR hSaveCursor;
// Display hourglass cursor
hSaveCursor = SetCursor(LoadCursor(0, IDC_WAIT));
if((rcode=kodalith(128, image1, image2)) == NO_ERROR) {
if((rcode=outline(image2, image2)) == NO_ERROR) {
rcode = negative(image2, image2);
if(rcode != NO_ERROR)
MessageBox(hWnd,"Error at negative()", 0, MB_OK);
}
else
MessageBox(hWnd,"Error at outline()", 0, MB_OK);
}
else
MessageBox(hWnd,"Error at kodalith()", 0, MB_OK);
SetCursor(hSaveCursor); // Restore cursor
return(rcode);
}
This example makes a new image that appears to be the photographic negative of the original image.
int or2(HWND hWnd, imgdes *image1, imgdes *image2, imgdes
*image3)
{
int rcode;
if((rcode=blur(image1, image2)) == NO_ERROR) {
if((rcode=orimage(image1, image2, image3)) != NO_ERROR)
MessageBox(hWnd,"Error in ORing images", 0, MB_OK);
}
else
MessageBox(hWnd,"Error in blurring image", 0, MB_OK);
return(rcode);
}
This example smooths image1, ORs the original image with the smoothed image, and places the result in image3.
int trace(HWND hWnd, imgdes *image1, imgdes *image2)
{
int rcode, rval, gval, bval;
HCURSOR hSaveCursor;
// Display hourglass cursor
hSaveCursor = SetCursor(LoadCursor(0, IDC_WAIT));
rcode = calcavglevel(image1, &rval, &gval, &bval);
if(rcode == NO_ERROR) {
if((rcode=kodalith(rval, image1, image2)) == NO_ERROR) {
if((rcode=outline(image2, image2)) != NO_ERROR)
MessageBox(hWnd,"Error at outline()", 0, MB_OK);
}
else
MessageBox(hWnd,"Error at kodalith()", 0, MB_OK);
}
else
MessageBox(hWnd,"Error at calcavglevel()", 0, MB_OK);
SetCursor(hSaveCursor); // Restore cursor
return(rcode);
}
This example calculates a level for a kodalith then outlines the image.
int pincrease(HWND hWnd, imgdes *image)
{
int rcode, area_wide, area_long, min=230, max=255;
long pels, redcnt, grncnt, blucnt, sum;
// Calculate pixels in image area of interest
area_wide = image->endx - image->stx + 1;
area_long = image->endy - image->sty + 1;
pels = area_wide * (long)area_long;
for(;;) {
if((rcode=pixelcount(min, max, &redcnt, &grncnt, &blucnt,
image)) != NO_ERROR) {
MessageBox(hWnd,"Error in counting pixels", 0, MB_OK);
break;
}
sum = redcnt;
if(image->bmh->biBitCount == 24)
// Adjust pixelcount for 3 planes
sum = (redcnt + grncnt + blucnt) / 3;
// If pixels between min and max < 10% pels, brighten
if(sum >= pels / 10)
break; // We are done!
if((rcode=changebright(10, image, image)) != NO_ERROR) {
MessageBox(hWnd,"Error in changing brightness", 0,
MB_OK);
break;
}
}
return(rcode);
}
This example increases the brightness until the range 230 to 255 contains at least 10 percent of the total pixels in the image area.
int pix8(HWND hWnd, imgdes *image)
{
int rcode, pixfactor=8;
rcode = pixellize(pixfactor, image, image);
if(rcode == NO_ERROR)
MessageBox(hWnd,"Error at pixellize()", 0, MB_OK);
return(rcode);
}
This example pixellizes an image area using a pixellation factor of 8.
int loadAPngFile(HWND hWnd, char *fname, imgdes *image)
{
PngData pdat;
int rcode;
// Get info on the file we're to load
rcode = pnginfo(fname, &pdat);
if(rcode == NO_ERROR) { // Fill structure
// Allocate space for an image
rcode = allocimage(image, (int)pdat.width, (int)pdat.length, pdat.vbitcount);
if(rcode == NO_ERROR) {
// Load image
rcode = loadpng(fname, image);
if(rcode == BAD_PNG) {
char szBuff[128];
// Get extended error info
int extRcode = pnggeterror();
wsprintf(szBuff, "Error in loading %s: extended error code %d", (LPSTR)fname, extRcode);
MessageBox(hWnd, szBuff, 0, MB_OK);
}
freeimage(image); // Free image on error
}
}
return(rcode);
}
This function reports extended error information when a PNG file cannot be loaded.
void pngsize(HWND hWnd, char *fname)
{
PngData pdat; // Reserve space for structure
int rcode;
char szBuff[80];
rcode = pnginfo(fname, &pdat);
if(rcode == BAD_OPN) {
wsprintf(szBuff, "Could not find %s", (LPSTR)fname);
MessageBox(hWnd, szBuff, 0, MB_OK);
}
else if(rcode == BAD_PNG) {
wsprintf(szBuff, "%s is not a PNG file", (LPSTR)fname);
MessageBox(hWnd, szBuff, 0, MB_OK);
}
else {
wsprintf(szBuff,
"%s image dimensions: Width=%d, Length=%d",
(LPSTR)fname, pdat.width, pdat.length);
MessageBox(hWnd, szBuff, 0, MB_OK);
}
}
This example reads a PNG file and prints the image size.
#define PRTDEFAULT 0// in VICDEFS.H
#define PRTHALFTONE 1
#define PRTSCATTER 2
// Global variables
int CancelPrt; // Cancel printing flag
HWND hDlgPrt; // "Cancel printing" dialog box handle
imgdes Image; // Image to print
// Display current band number in "cancel printing" dialog box.
Returns state of cancel printing flag (Cancel if TRUE).
int _export FAR PASCAL DisplayProgress(int bandno)
{
#define IDC_TEXT 0x200
MSG msg;
char szBuff[64];
// Display progress in cancel printing dialog box
if(hDlgPrt) { // If dialog exists...
wsprintf(szBuff, "Imaging band number %d", bandno);
SetDlgItemText(hDlgPrt, IDC_TEXT, szBuff);
}
// Allow other apps and cancel print dialog to process messages
while(PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) {
if(!hDlgPrt || !IsDialogMessage(hDlgPrt, &msg)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return(CancelPrt); // Return state of "cancel printing" flag
}
// Dialog proc for "cancel printing" dialog box
int _export FAR PASCAL CancelPrtProc(HWND hDlg, WORD message, WORD
wParam, LONG lParam)
{
if(message == WM_COMMAND && wParam == IDCANCEL) {
CancelPrt = TRUE; // Cancel printing
return(TRUE);
}
return(FALSE);
}
// "Print an image area" command selected from menu
LONG DoPrint(HWND hWnd, WORD msg, WORD wParam, LONG lParam)
{
#define IDD_PRTCANCEL 0x210
int xpos, ypos, rcode, frame = 1;
DLGPROC lpfnDispProg; // Function to display current band
DLGPROC lpfnPrtProc; // Dialog to cancel printing
HINSTANCE hInst = GetWindowInstance(hWnd);
HDC hPrn; // Printer Device Context
int prtmode = PRTHALFTONE; // Use halftone print mode
RECT prtrc;
// Get printer DC
if((hPrn = GetPrinterDC()) == NULL)
rcode = PRT_ERR;
else {
// Disable main window to prevent closing
EnableWindow(hWnd, FALSE);
CancelPrt = 0; // Clear cancel printing flag
// Create a "cancel printing" dialog box
lpfnPrtProc = (DLGPROC)MakeProcInstance(
(FARPROC)CancelPrtProc,hInst);
hDlgPrt = CreateDialog(hInst,MAKEINTRESOURCE(IDD_PRTCANCEL),
hWnd, (DLGPROC)lpfnPrtProc);
// Create procedure-instance pointer to DisplayProgress()
// printimage calls that function to display current band
lpfnDispProg = (DLGPROC)MakeProcInstance(
(FARPROC)DisplayProgress, hInst);
// Area to print: 3 inches x 5 inches, 2.5" down and in
xpos = 2500; ypos = 2500;
SetRect(&prtrc, xpos, ypos, xpos + 2999, ypos + 4999);
// Print the image
rcode = printimage(hWnd, hPrn, prtmode, &Image, &prtrc,
frame, lpfnDispProg);
FreeProcInstance(lpfnDispProg);
EnableWindow(hWnd, TRUE); // Re-enable main window
DestroyWindow(hDlgPrt); // Delete "cancel printing" dialog
hDlgPrt = 0;
FreeProcInstance(lpfnPrtProc);
DeleteDC(hPrn); // Delete printer DC
}
if(rcode != NO_ERROR)
MessageBox(hWnd, "Error in printing image", 0, MB_OK);
return(0L);
}
// Read WIN.INI for default printer and create a DC.
// Returns a handle to the DC or 0 if unsuccessful.
HDC GetPrinterDC(void)
{
char szPrinter[80];
char *szDevice, *szDriver, *szOutput;
GetProfileString("windows", "device", "", szPrinter,
sizeof(szPrinter));
if((szDevice = strtok(szPrinter, ",")) &&
(szDriver = strtok(0, ", ")) &&
(szOutput = strtok(0, ", ")))
return(CreateDC(szDriver, szDevice, szOutput, 0));
return(0);
}
This example prints a 3 x 5 inch image in the center of the pageand displays a dialog box that reports printing progress andallows the user to cancel printing.
// Functions GetPrinterDC(), CancelPrtProc(), and
// DisplayProgress() are defined in printimage() example
void DoPrintTwoImages(HWND hWnd)
{
#define IDD_PRTCANCEL 0x210
int xpos, ypos, rcode, frame = 1;
HINSTANCE hInst = GetWindowInstance(hWnd);
HDC hPrn; // Printer Device Context
int prtmode = PRTHALFTONE; // Use halftone print mode
RECT prtrc;
char szBuff[256];
BOOL ejectPage; // Eject the page if TRUE
// Get printer DC
if((hPrn = GetPrinterDC()) == NULL)
rcode = PRT_ERR;
else {
// Disable main window to prevent closing
EnableWindow(hWnd, FALSE);
CancelPrt = FALSE; // Clear cancel printing flag
// Create a "cancel printing" dialog box
hDlgPrt = CreateDialog(hInst,
MAKEINTRESOURCE(IDD_PRTCANCEL),hWnd,
(DLGPROC)CancelPrtProc);
// Print 3 x 5 inch image 0.5 inch from left, xpos = 500;
// ypos = 2500; 2.5 inches from top
SetRect(&prtrc, xpos, ypos, xpos + 2999, ypos + 4999);
// Set doc name for print manager
GetWindowText(hWnd, szBuff, sizeof(szBuff));
// Initialize for multi-image printing
rcode = printimagestartdoc(hPrn, szBuff);
if(rcode == NO_ERROR) {
// Print the first image
rcode = printimagenoeject(hWnd, hPrn, prtmode, &Image,
&prtrc, frame, (DLGPROC)DisplayProgress);
if(CancelPrt == FALSE && rcode == NO_ERROR) {
// Add some text to the page
SetTextAlign(hPrn, TA_UPDATECP);
MoveTo(hPrn, 1 * 300, 2 * 300);
TextOut(hPrn, 0, 0, "This is a test", 14);
// Print 3 x 5 inch image 4.0 inches from left,
xpos = 4000; ypos = 2500; // 2.5 inches from top
SetRect(&prtrc, xpos, ypos, xpos + 2999, ypos + 4999);
// Print the second image
rcode = printimagenoeject(hWnd, hPrn, prtmode,
&Image,&prtrc, frame, (DLGPROC)DisplayPrtProg);
}
// Eject the page if the user didn't abort & no errors
ejectPage = CancelPrt == FALSE && rcode == NO_ERROR;
printimageenddoc(hPrn, ejectPage);
}
EnableWindow(hWnd, TRUE); // Re-enable main window
DestroyWindow(hDlgPrt); // Delete "cancel printing" dialog
hDlgPrt = 0;
DeleteDC(hPrn); // Delete printer DC
}
if(rcode != NO_ERROR)
MessageBox(hWnd, "Error in printing image", 0, MB_OK);
}
This example prints two 3 x 5 inch images and some text in the center of the page and displays a dialog box that reports printing progress and allows the user to cancel printing.
int rainbowview(HWND hWnd, imgdes *srcimg)
{
int rcode, rows, cols;
HDC hDC;
HPALETTE hpal;
imgdes resimg;
PAINTSTRUCT ps;
rows = srcimg->endy - srcimg->sty + 1;
cols = srcimg->endx - srcimg->stx + 1;
// Allocate temporary 8-bit image for viewing
rcode = allocimage(&resimg, cols, rows, 8);
if(rcode == NO_ERROR) {
// Create rainbow palette in result image
rainbowpalette(&resimg);
// Force 24-bit image to use rainbow palette
rcode = matchcolorimage(srcimg, &resimg);
if(rcode != NO_ERROR)
MessageBox(hWnd,
"Could not convert RGB to 8-bit image", 0, MB_OK);
else {
hDC = BeginPaint(hWnd, &ps);
// Display the image at (0,0)
rcode = viewimageex(hWnd, hDC, &hpal, 0, 0, &resimg, 0,
0, VIEWDITHER);
EndPaint(hWnd, &ps);
if(rcode != NO_ERROR)
MessageBox(hWnd, "Error displaying image", 0, MB_OK);
}
DeleteObject(hpal);
// Release the temporary 8-bit image
freeimage(&resimg);
}
return(rcode);
}
This example converts an RGB image to an 8-bit palette color image with a rainbow palette for display.
int makea16colorimage(HWND hWnd, imgdes *srcimg, imgdes *resimg)
{
int rcode, rows, cols;
cols = srcimg->endx - srcimg->stx + 1;
rows = srcimg->endy - srcimg->sty + 1;
// Allocate space for the 16-color image
rcode = allocimage(resimg, cols, rows, 8);
if(rcode != NO_ERROR) {
MessageBox(hWnd,
"Not enough memory to create 16-color image", 0, MB_OK);
return(rcode);
}
resimg->colors = 16; // Reduce palette colors to 16
rcode = reduceimagecolors(srcimg, resimg);
if(rcode != NO_ERROR) {
freeimage(resimg);
MessageBox(hWnd,"Error in creating 16-color image", 0,
MB_OK);
}
return(rcode);
}
This example creates a 16-color image for display on 16-color display adapters.
int RemoveRandomNoise(HWND hWnd, imgdes *image)
{
int rcode;
if((rcode=removenoise(image, image)) != NO_ERROR)
MessageBox(hWnd,"Error at removenoise", 0, MB_OK);
return(rcode);
}
This example removes random noise from the image area.
void ResizeImage(HWND hWnd, imgdes *image)
{
imgdes timage;
int dx, dy, rcode, pct = 50; // 50% reduction
// Allocate space for the new DIB
dx = (int)(((long)(image->endx - image->stx + 1)) * pct / 100);
dy = (int)(((long)(image->endy - image->sty + 1)) * pct / 100);
if((rcode = allocimage(&timage, dx, dy,
image->bmh->biBitCount)) == NO_ERROR) {
// Resize Image into timage
if((rcode = resize(image, &timage)) == NO_ERROR) {
// Success, free source image
freeimage(image);
// Assign timage to image
copyimgdes(&timage, image);
}
else // Error in resizing image, release timage memory
freeimage(&timage);
}
if(rcode != NO_ERROR)
MessageBox(hWnd, "Error in resizing image", 0, MB_OK);
}
This example resizes an image area and replaces the original image with the new image.
void ResizeImageByInterp(HWND hWnd, imgdes *image)
{
imgdes timage;
int dx, dy, rcode, pct = 50; // 50% reduction
int mode = RESIZEBILINEAR; // Bilinear interpolation
// Allocate space for the new DIB
dx = (int)(((long)(image->endx - image->stx + 1)) * pct / 100);
dy = (int)(((long)(image->endy - image->sty + 1)) * pct / 100);
if((rcode = allocimage(&timage, dx, dy,
image->bmh->biBitCount)) == NO_ERROR) {
// Resize Image into timage
if((rcode = resizeex(image, &timage, mode)) == NO_ERROR) {
// Success, free source image
freeimage(image);
// Assign timage to image
copyimgdes(&timage, image);
}
else // Error in resizing image, release timage memory
freeimage(&timage);
}
if(rcode != NO_ERROR)
MessageBox(hWnd, "Error at resizeex()", 0, MB_OK);
}
This example resizes an image area using interpolation and replaces the original image with the new image.
void rgb_to_hsv(int colors, // Number of RGBQUADs to convert
imgdes *image, HSVTRIPLE *hsvtab)
{
rgb2hsv(image->palette, hsvtab, colors);
}
This example converts an RGB palette associated with an image to an HSV table.
#include math.h // for sin and cos functions
int rotate_any_angle(imgdes *image)
{
imgdes timage;
int rcode, rotwidth, rotlength;
double angle = 37.21;
double cols, rows, costheta, sintheta;
cols = (double)CALC_WIDTH(image); // VICDEFS.H macros
rows = (double)CALC_HEIGHT(image);
costheta = fabs(cos(angle)); sintheta = fabs(sin(angle));
rotwidth = (int)(costheta * cols + sintheta * rows);
rotlength = (int)(sintheta * cols + costheta * rows);
// Allocate buffer large enough to hold entire rotated image area
rcode = allocimage(&timage, rotwidth, rotlength,
image->bmh->biBitCount);
if(rcode == NO_ERROR) {
// Rotate image area
rcode = rotate(angle, image, &timage);
if(rcode == NO_ERROR) {
// Copy palette data into rotated image
copyimgpalette(image, &timage);
freeimage(image);
// Replace original image with rotated image
copyimgdes(&timage, image);
}
else
freeimage(&timage); // Release memory if error
}
return(rcode);
}
This example rotates an image 37.21 degrees and modifies the image descriptor to describe the new rotated image.
int rotate_90(imgdes *image)
{
#define CW 0
#define CCW 1
imgdes timage;
int rcode, rotwidth, rotlength, rotflag=CW;
rotlength = image->endx - image->stx + 1;
rotwidth = image->endy - image->sty + 1;
copyimgdes(image, &timage);
rcode = allocimage(&timage, rotwidth, rotlength,
image->bmh->biBitCount);
if(rcode == NO_ERROR) {
rcode = rotate90(rotflag, image, &timage);
if(rcode == NO_ERROR) {
// Copy palette data into rotated image
copyimgpalette(image, &timage);
freeimage(image);
// Replace original image with rotated image
copyimgdes(&timage, image);
}
else
freeimage(&timage); // Release memory if error
}
return(rcode);
}
This example rotates an image 90 degrees clockwise and modifies the image descriptor to describe the new rotated image.
int save_bif(HWND hWnd, char *fname, imgdes *image)
{
int rcode;
char szBuff[80];
rcode = savebif(fname, image);
if(rcode == BAD_DSK)
wsprintf(szBuff, "Could not save %s, disk full",
(LPSTR)fname);
else if(rcode == BAD_CRT)
wsprintf(szBuff, "Could not create %s", (LPSTR)fname);
else if(rcode == NO_ERROR)
wsprintf(szBuff, "%s saved as %d x %d BIF file",
(LPSTR)fname,
(int)image->bmh->biWidth, (int)image->bmh->biHeight);
MessageBox(hWnd, szBuff, 0, MB_OK);
return(rcode);
}
This example saves an image area as a binary image file.
int save_bmp(HWND hWnd, char *fname, imgdes *image)
{
int rcode, comp=0; // Save as uncompressed
char szBuff[80];
rcode = savebmp(fname, image, comp);
if(rcode != NO_ERROR) {
wsprintf(szBuff, "Could not save %s", (LPSTR)fname);
MessageBox(hWnd, szBuff, 0, MB_OK);
}
return(rcode);
}
This example saves an image as an uncompressed BMP file.
int save_eps(HWND hWnd, char *fname, imgdes *image)
{
int rcode;
char szBuff[80];
rcode = saveeps(fname, image);
if(rcode == BAD_DSK)
wsprintf(szBuff, "Could not save %s, disk full",
(LPSTR)fname);
else if(rcode == BAD_CRT)
wsprintf(szBuff, "Could not create %s", (LPSTR)fname);
else if(rcode == NO_ERROR)
wsprintf(szBuff, "%s saved as %d x %d EPS file",
(LPSTR)fname, (int)image->bmh->biWidth,
(int)image->bmh->biHeight);
MessageBox(hWnd, szBuff, 0, MB_OK);
return(rcode);
}
This example saves an image area as an Encapsulated Postscript file.
int save_gif(HWND hWnd, char *fname, imgdes *image)
{
int rcode;
char szBuff[80];
rcode = histoequalize(image, image);
if(rcode != NO_ERROR)
wsprintf(szBuff, "Error in brightening image");
else {
rcode = savegif(fname, image);
if(rcode != NO_ERROR)
wsprintf(szBuff, "Could not save %s", (LPSTR)fname);
}
if(rcode != NO_ERROR)
MessageBox(hWnd, szBuff, 0, MB_OK);
return(rcode);
}
This example brightens an image and saves it as a GIF file.
int saveGifEx(HWND hWnd, char *fname, imgdes *image)
{
#define VINTERLACE 1 // Defined in VICDEFS.H
#define VTRANSPARENT 2
#define VWRITE4BIT 4
int rcode;
// Write a transparent, interlaced GIF
int saveMode = VINTERLACE | VTRANSPARENT;
int transColor = 10; // Transparent color is 10
// Write a 4-bit GIF if palette colors are 16 or less
if(image->colors <= 16)
saveMode |= VWRITE4BIT;
rcode = savegifex(fname, imgptr, saveMode, trasnColor);
if(rcode != NO_ERROR) {
char szBuff[80];
wsprintf(szBuff, "Could not save %s", (LPSTR)fname);
MessageBox(hWnd, szBuff, 0, MB_OK);
}
return(rcode);
}
This example saves an image area as a transparent, interlaced, 4- or 8-bit GIF file.
int findwhite(imgdes *srcimg) // Helper function to find white palette entry
{
int j;
int r, g, b;
int maxwhite = 0;
int maxwhiteindex = -1;
for(j = 0; j <= srcimg->colors; j++) {
r = srcimg->palette[j].rgbRed;
g = srcimg->palette[j].rgbGreen;
b = srcimg->palette[j].rgbBlue;
if(r == g && r == b)
if (r > maxwhite) {
maxwhiteindex = j;
maxwhite = r;
}
}
return maxwhiteindex;
}
// Make an animated gif of a growing image
int makegrowingGIF(int frames, imgdes *srcimg)
{
int rcode = NO_ERROR;
int cols, rows;
int j;
int wd, ht;
imgdes desimg;
int foundwhite;
GifGlobalSaveData gdata;
GifFrameSaveData fdata;
if(srcimg->bmh->biBitCount != 8)
return(BAD_BPP);
cols = CALC_WIDTH(srcimg);
rows = CALC_HEIGHT(srcimg);
foundwhite = findwhite(srcimg);
// GIF global data used by savegifframe(), etc.
gdata.scrwidth = cols;
gdata.scrlength = rows;
gdata.hasColorMap = TRUE; // Global color table is present!
gdata.bckColor = foundwhite; // Color index of screen backgnd
gdata.loop = 1000; // Number of iterations
fdata.startx = 0;
fdata.starty = 0; // X,Y pixel position with respect to scrwidth, scrlength
fdata.hasColorMap = FALSE; // Local color table present?
fdata.delay = 1; // 100ths of a second to display frame
fdata.transColor = -1; // Transparent color index, -1 => none
fdata.removeBy = 0; // How graphic is to be treated after display
fdata.waitForUserInput = FALSE; // If true, expect user input
wd = cols/frames/2;
ht = rows/frames/2;
rcode = allocimage(&desimg, cols, rows, 8);
copyimagepalette(srcimg, &desimg);
zeroimage(foundwhite, &desimg);
// First frame, plain white
rcode = savegifframe("growing.gif", &desimg, &gdata, &fdata, GIFLZWCOMP ); // or GIFNOCOMP
for(j = frames-1; j >= 0; j--) {
// GIF frame data used by savegifframe(), etc.
fdata.startx = wd*j;
fdata.starty = ht*j; // X,Y pixel position with respect to scrwidth, scrlength
fdata.removeBy = 2; // How graphic is to be treated after display
//NOTHING 0 – The image is left unremoved
//ASIS 1 – The image is left unremoved
//BACKGROUND 2 – The image is replaced by the background
//PREVIOUS 3 – The image is replaced by the previous image
// Create a growing image
setimagearea(&desimg, fdata.startx, fdata.starty, cols-fdata.startx-1, rows-fdata.starty-1);
resizeex(srcimg, &desimg, RESIZEFAST); // 1 = RESAMPLEBILINEAR
rcode = savegifframe("growing.gif", &desimg, &gdata, &fdata, GIFLZWCOMP ); // or GIFNOCOMP
}
freeimage(&desimg);
return (rcode);
}
This example creates an animated GIF that displays the image growing on a white background.
typedef struct { char *qualstr; int qval; } QUALVAL;
int save_jpeg(HWND hWnd, char *fname, imgdes *image, char
*qstring)
{
int j, rcode, quality;
static QUALVAL quallist[] = {
{"best", 100}, {"excellent", 75}, {"good", 50},
{"fair", 35}, {"poor", 10}};
char szBuff[80];
quality = 75;
for(j=0; j<5; j++) {
if(lstrcmpi(quallist[j].qualstr, qstring) == 0)
quality = quallist[j].qval;
}
rcode = savejpg(fname, image, quality);
if(rcode != NO_ERROR) {
wsprintf(szBuff, "Could not save %s", (LPSTR)fname);
MessageBox(hWnd, szBuff, 0, MB_OK);
}
return(rcode);
}
This example saves an image as a compressed JPEG file, where the image quality factor is determined by a string argument.
int saveProgressiveJpeg(HWND hWnd, char *fname, imgdes *image)
{
int j, rcode, quality = 75;
int savemode = JPGPROG;
char szBuff[80];
rcode = savejpgex(fname, image, quality, savemode);
if(rcode != NO_ERROR) {
wsprintf(szBuff, "Could not save %s", (LPSTR)fname);
MessageBox(hWnd, szBuff, 0, MB_OK);
}
return(rcode);
}
This example saves an image as a progressive JPEG file.
// Save an image buffer as a JPG file.
int jpegWithThumb(const char *filnam, imgdes *image, int ftype)
{
int quality = (ftype == JPGTYP) ? 75 : 50;
int saveMode = JPGSEQOPTTN; // JPGSEQTN, JPGPROGTN;
int longEdge = 100; // Maximum width or length 100 pixels
jpegsetthumbnailsize(longEdge);
return(savejpgex(filnam, image, quality, saveMode));
}
This examples saves an image with a thumbnail.
int saveAndLoadJpgFromBuffer(HWND hWnd, char *fname,
imgdes *image)
{
TiffData tdat;
JpegData jdat; // Reserve space for struct
imgdes timage;
UCHAR huge *buffaddr;
char szBuff[80];
int rcode, qual = 75;
// Load a TIFF file into temp image
if((rcode = tiffinfo(fname, &tdat)) == NO_ERROR &&
(rcode = allocimage(&timage, tdat.width, tdat.length,
tdat.vbitcount)) == NO_ERROR &&
(rcode = loadtif(fname, &timage)) == NO_ERROR) {
// Save temp image as compressed JPEG data in buffer
rcode = savejpgtobuffer(&buffaddr, &timage, qual);
if(rcode == NO_ERROR) {
// Done with temp image, release it
freeimage(&timage);
// Load the JPEG image from the buffer
// Get the JPEG image dimensions
rcode = jpeginfofrombuffer(buffaddr, &jdat);
if(rcode == NO_ERROR) {
// Allocate a new image buffer
rcode = allocimage(image, jdat.width,
jdat.length, jdat.vbitcount);
if(rcode == NO_ERROR) {
// Load the compressed JPEG image
rcode = loadjpgfrombuffer(buffaddr, image);
GlobalFreePtr(buffaddr); // Done with JPEG data
if(rcode == NO_ERROR) {
// Display pic
ShowWindow(hWnd, SW_SHOWNORMAL);
UpdateWindow(hWnd);
wsprintf((LPSTR)szBuff, (LPSTR)
"File %s loaded",(LPSTR)fname);
MessageBox(hWnd, szBuff,
"Load JPEG from Buffer", MB_OK);
}
}
}
}
}
return(rcode);
}
The example loads a TIFF file, stores the image as compressed JPEG data in memory, and expands the JPEG data into an image buffer.
int save_pcx(HWND hWnd, char *fname, imgdes *image)
{
int rcode;
char szBuff[80];
rcode = savepcx(fname, image);
if(rcode == BAD_DSK)
wsprintf(szBuff, "Could not save %s, disk full",
(LPSTR)fname);
else if(rcode == BAD_CRT)
wsprintf(szBuff, "Could not create %s", (LPSTR)fname);
else if(rcode == NO_ERROR)
wsprintf(szBuff, "%s saved as %d x %d PCX file",
(LPSTR)fname, (int)image->bmh->biWidth,
(int)image->bmh->biHeight);
MessageBox(hWnd, szBuff, 0, MB_OK);
return(rcode);
}
This example saves an image area as a PCX file.
int saveAPng(HWND hWnd, char *fname, imgdes *image)
{
int rcode;
int comp = PNGALLFILTERS | PNGINTERLACE;
char szBuff[80];
histoequalize(image, image);
rcode = savepng(fname, image, comp);
if(rcode != NO_ERROR) {
wsprintf(szBuff, "Could not save %s", (LPSTR)fname);
MessageBox(hWnd, szBuff, 0, MB_OK);
}
return(rcode);
}
This example brightens an image and saves it with maximum compression as an interlaced PNG file.
int save_tga(HWND hWnd, char *fname, imgdes *image)
{
int rcode;
char szBuff[80];
rcode = sharpen(image, image);
if(rcode != NO_ERROR)
wsprintf(szBuff, "Error in sharpening image");
else {
rcode = savetga(fname, image, 0);
if(rcode != NO_ERROR)
wsprintf(szBuff, "Could not save %s", (LPSTR)fname);
}
if(rcode != NO_ERROR)
MessageBox(hWnd, szBuff, 0, MB_OK);
return(rcode);
}
This example sharpens an image and saves it as an uncompressed TGA file.
int save_tif(HWND hWnd, char *fname, imgdes *image)
{
#define NONE 0
#define LZW 1
#define PB 2
#define G3 3
#define G4 4
int rcode, comp;
char szBuff[80];
// Use PackBits comp for 1- or 8-bit image
comp = (image->bmh->biBitCount <= 8) ? PB : NONE;
rcode = savetif(fname, image, comp);
if(rcode != NO_ERROR)
wsprintf(szBuff, "Could not save %s", (LPSTR)fname);
MessageBox(hWnd, szBuff, 0, MB_OK);
return(rcode);
}
This example saves a 1- or 8-bit image as a compressed TIFF file and a 24-bit image as an uncompressed TIFF file.
void replacePageInMultiTIF(LPSTR fname,
imgdes far *rimage, // Image to substitute
int newPage) // Page to replace
{
// Assume TIF file contains PAGE_MAX or less pages
#define PAGE_MAX 25
int pageArray[PAGE_MAX];
int j, k, min, tmp, rcode, totalPages, curPage;
char *fname = "multiTIF.tif";
char *tempName = "TempFile.TMP";
TiffData tinfo;
imgdes timage, far *simage;
int cmprsn = 0; // Save as uncompressed TIF
// Call tiffgetpageinfo to fill totalPages and pageArray
rcode = tiffgetpageinfo(fname, (int far *)&totalPages,
(int far *)pageArray, sizeof(pageArray));
if(rcode == NO_ERROR) {
// Write the new file
for(j=0; j<totalPages; j++) {
curPage = pageArray[j];
if(curPage == newPage) // Write current page
simage = rimage;
else { // Don't write current page
// Make sure page exists and get its dimensions
rcode = tiffinfopage(fname, &tinfo, curPage);
// Allocate space for the page
rcode = allocimage(&timage, tinfo.width,tinfo.length,
tinfo.vbitcount);
// Load the page
rcode = loadtifpage(fname, &timage, curPage);
simage = &timage;
}
// Write the page to a new file
rcode = savetifpage(tempName, simage, cmprsn, curPage);
if(curPage != newPage)
freeimage(&timage); // Release page memory
}
// Replace fname with tempName and delete tempName
if(rcode == NO_ERROR) {
CopyFile(tempName, fname, FALSE); // 32-bit API function
remove(tempName);
}
}
return(rcode);
}
This example replaces page number newPage with a new image.
int save_gifcom(HWND hWnd, char *fname, imgdes *image)
{
int rcode, gifvers = 89; // Create a GIF89a file
char szBuff[80], *gifcomment = "File created on 4-9-94";
// Set GIF version and add a comment to the GIF file
// (cannot add a comment to an GIF87a file)
setgifcomment(gifvers, gifcomment);
rcode = savegif(fname, image);
if(rcode != NO_ERROR) {
wsprintf(szBuff, "Could not save %s", (LPSTR)fname);
MessageBox(hWnd, szBuff, 0, MB_OK);
}
return(rcode);
}
This example saves an image as a GIF89a file and includes a comment string indicating when the image was created.
void ResetArea(HWND hWnd, imgdes *image)
{
// Reset image area to the entire image
setimagearea(image, 0, 0, (int)image->bmh->biWidth - 1,
(int)image->bmh->biHeight - 1);
}
This example resets the image area to the entire image.
void set_icolumn(HWND hWnd, imgdes *image, int xx, int yy,
int pels2write, unsigned char *lnbuff) // Source of pixels
{
unsigned long color;
int j, rcode=NO_ERROR;
unsigned char red, grn, blu, mask=0x80;
for(j=0; j<pels2write && rcode==NO_ERROR; j++) {
if(image->bmh->biBitCount == 1) { // 1-bit image
color = *lnbuff & mask;
mask >>= 1;
if(mask == 0) {
mask = 0x80;
lnbuff++;
}
}
else if(image->bmh->biBitCount == 8) // 8-bit image
color = *lnbuff++;
else { // 24-bit image
blu = *lnbuff++;
grn = *lnbuff++;
red = *lnbuff++;
color = RGB(red, grn, blu); // Windows macro
}
rcode = setpixelcolor(image, xx, yy++, color);
}
if(rcode != NO_ERROR)
MessageBox(hWnd, "Failure in setting pixel color", 0,
MB_OK);
}
This example copies a row of pixels in a line buffer to a column.
int GetAClipping(HWND hwnd, char *fname)
{
unsigned char huge *dib;
int rcode=NO_ERROR, oclip;
HGLOBAL hMem;
imgdes image;
if((oclip = OpenClipboard(hwnd)) != 0) {
// Get DIB from clipboard
if((hMem = GetClipboardData(CF_DIB)) != 0) {
// Get address of DIB
dib = (unsigned char huge *)GlobalLock(hMem);
// Describe the DIB with an image descriptor
rcode = setupimgdes(dib, &image);
if(rcode == NO_ERROR)
rcode = savebmp(fname, &image, 0);
}
else
rcode = NO_CLIPBRD_DIB; // No DIB on clipboard
}
else
rcode = NO_CLIPBRD; // Could not open clipboard
if(hMem) // Unlock memory before closing the clipboard
GlobalUnlock(hMem);
if(oclip)
CloseClipboard(); // Close the clipboard
return(rcode);
}
This example saves a DIB from the clipboard as a BMP file.
int save_sharp(HWND hWnd, char *fname, imgdes *image)
{
int rcode;
char szBuff[80];
rcode = sharpen(image, image);
if(rcode != NO_ERROR)
wsprintf(szBuff, "Error in sharpening image");
else {
rcode = savebmp(fname, image, 0);
if(rcode != NO_ERROR)
wsprintf(szBuff, "Could not save %s", (LPSTR)fname);
}
if(rcode != NO_ERROR)
MessageBox(hWnd, szBuff, 0, MB_OK);
return(rcode);
}
This example sharpens an image and saves it as a BMP file.
int save_gentle(HWND hWnd, char *fname, imgdes *image)
{
int rcode;
char szBuff[80];
rcode = sharpengentle(image, image);
if(rcode != NO_ERROR)
wsprintf(szBuff, "Error in sharpening image");
else {
rcode = savetif(fname, image, 0);
if(rcode != NO_ERROR)
wsprintf(szBuff, "Could not save %s", (LPSTR)fname);
}
if(rcode != NO_ERROR)
MessageBox(hWnd, szBuff, 0, MB_OK);
return(rcode);
}
This example gently sharpens an image and saves it as a TIFF file.
int sub2(HWND hWnd, imgdes *image1, imgdes *image2,
imgdes *image3)
{
int rcode;
if((rcode=blur(image1, image2)) == NO_ERROR) {
if((rcode=subimage(image1, image2, image3)) != NO_ERROR)
MessageBox(hWnd, "Error in subtracting images", 0,
MB_OK);
}
else
MessageBox(hWnd, "Error in blurring images", 0, MB_OK);
return(rcode);
}
This example smooths image1, subtracts the smoothed image from the original,
and places the difference in image3.
int thresh15(HWND hWnd, imgdes *image)
{
int rcode, max_black=15;
setimagearea(image, 0, 0, (unsigned)image->bmp->biWidth-1,
(unsigned)image->bmh->biHeight-1);
rcode = threshold(max_black, image, image);
if(rcode != NO_ERROR)
MessageBox(hWnd, "Error at threshold", 0, MB_OK);
return(rcode);
}
This example resets the image area to the entire image, and sets all brightness levels less than or equal to 15 to black.
int loadATiffFile(HWND hWnd, char *fname, imgdes *image)
{
TiffData tdat;
int rcode;
// Get info on the file we're to load
rcode = tiffinfo(fname, &tdat);
if(rcode == NO_ERROR) { // Fill structure
// Allocate space for an image
rcode = allocimage(image, (int)tdat.width, (int)tdat.length, tdat.vbitcount);
if(rcode == NO_ERROR) {
// Load image
rcode = loadtif(fname, image);
if(rcode == BAD_TIFF) {
char szBuff[128];
// Get extended error info
int extRcode = tiffgeterror();
wsprintf(szBuff, "Error in loading %s: extended error code %d", (LPSTR)fname, extRcode);
MessageBox(hWnd, szBuff, 0, MB_OK);
}
freeimage(image); // Free image on error
}
}
return(rcode);
}
This function reports extended error information when a TIFF file cannot be loaded.
void tiffidentity(HWND hWnd, char *fname)
{
TiffData tdat; // Reserve space for structure
int rcode;
char szBuff[80];
if((rcode=tiffinfo(fname, &tdat)) == BAD_OPN)
wsprintf(szBuff, "Could not find %s", (LPSTR)fname);
else if(rcode == BAD_TIFF)
wsprintf(szBuff, "%s is not a TIFF file", (LPSTR)fname);
else { // Is it an RGB TIFF?
if(tdat.SamplesPPixel == 3 && tdat.PhotoInt == 2 &&
tdat.BitsPSample == 8)
wsprintf(szBuff, "%s is a RGB TIFF file", (LPSTR)fname);
// Is it a palette color TIFF?
else if(tdat.SamplesPPixel == 1 && tdat.PhotoInt == 3)
wsprintf(szBuff, "%s is a palette color TIFF file",
(LPSTR)fname);
// Is it a grayscale TIFF?
else if(tdat.SamplesPPixel == 1 && tdat.PhotoInt <= 1)
wsprintf(szBuff, "%s is a grayscale TIFF file",
(LPSTR)fname);
// Is it a bilevel TIFF?
else if(tdat.SamplesPPixel == 1 && tdat.BitsPSample == 1
&& tdat.PhotoInt <= 1)
wsprintf(szBuff, "%s is a bilevel TIFF file",
(LPSTR)fname);
else wsprintf(szBuff, "%s is a TIFF file of unknown type",
(LPSTR)fname);
}
MessageBox(hWnd, szBuff, 0, MB_OK);
}
This example identifies a file as a grayscale, bilevel, palette color, or RGB TIFF file.
void EnableTwainScanMenuItems(HWND hWnd, HMENU hMenu)
{
static BOOL scanDriverReady = FALSE;
int mstate;
// Enable/disable scan menu items
if(scanDriverReady == FALSE) {
// Enable/disable scan menu items
mstate = MF_GRAYED;
// If Twain source manager (TWAIN.DLL or TWAIN_32.DLL)
// is present, enable the scan menu items
if(TWdetecttwain(hWnd) == NO_ERROR) {
scanDriverReady = TRUE;
mstate = MF_ENABLED;
}
EnableMenuItem(hMenu, IDM_F_SELECTSOURCE, mstate);
EnableMenuItem(hMenu, IDM_F_ACQUIRE, mstate);
}
}
This example enables or disables the TWAIN scan menu items.
int AcquireAnImageDup(HWND hWnd, imgdes far *desimg)
{
int rcode;
int width, height;
BOOL enableduplex = TRUE;
unsigned pagesize = 0; // TWSS_NONE, for largest page size
TWgetphysicalsize(hWnd, &width, &height);
// Enable (or disable) duplex operation
TWsetduplex(hWnd, enableduplex);
// Set maximum page size
TWsetpagesize(hWnd, pagesize);
// Acquire image from selected/default source
rcode = TWscanimage(hWnd, desimg);
if(rcode != NO_ERROR){ // Handle any errors
char szBuff[80];
wsprintf(szBuff, "Error in acquiring image: %d, %d",
rcode, TWgeterror());
MessageBox(hWnd, szBuff, "TWAIN Error", MB_OK);
}
return(rcode);
}
This example gets the physical scan limits, enables duplex operation, sets the maximum page size, and acquires an image.
int SelectDataSourceByName(HWND hWnd)
int j, rcode;
char far *targetDS="DeskScan II"; // HP ScanJet data source
TW_STR32 far *nameList; // List of Twain data sources
int nameCount; // Number of sources in nameList
// Store App name to display in Source dialog box
TWsetproductname("My App");
nameList = NULL;
// Get number of data sources available
rcode = TWgetsourcenames(hWnd, nameList, &nameCount);
// Allocate space for names of data sources
nameList = (TW_STR32 far *)calloc(nameCount, sizeof(TW_STR32));
// Get data source names
rcode = TWgetsourcenames(hWnd, nameList, &nameCount);
if(rcode == NO_ERROR) {
// Compare data source names found to our target
for(j=0; j<nameCount; j++) {
if(lstrcmpi(targetDS, (char far *)&nameList[j]) == 0)
break; // Found a match
}
if(j == nameCount)
rcode = TWAIN_NODS; // Target data source not found
else // Select the data source for image acquisition
rcode = TWselectsourcebyname(hWnd, (char far *)&nameList[j]);
}
if(nameList)
free(nameList);
return(rcode);
}
This example retrieves a list of TWAIN data sources and then selects the data source for the HP ScanJet scanner.
int AcquireAnImage2(HWND hWnd, imgdes far *desimg)
{
int rcode; // Set App name to display in source dialog
TWsetproductname("OurApp");
rcode = TWopen(hWnd); // Open Data Source and source mgr
if(rcode == NO_ERROR)
// Acquire image from selected/default source
rcode = TWscanimage(hWnd, desimg);
return(rcode);
}
This example acquires an image from a TWAIN source using the TWopen function.
int _export WINAPI saveImage(imgdes far *simage)
{
static int imgCtr = 0; // Count scanned images
int rcode;
TCHAR filnam[256];
// Create a filename to save the scanned image
wsprintf(filnam, (LPSTR)_T"test%d.tif", imgCtr);
// Expand image contrast
expandcontrast(20, 240, simage, simage);
// Save the image
rcode = savetif(filnam, simage, 0);
if(rcode == NO_ERROR)
imgCtr++; // Update image counter
else
rcode = TWAIN_STOP_SCAN; // Quit if error
// Free image buffer after it's saved
freeimage(simage);
return(rcode);
}
// Acquire command selected
int AcquireCountImages(HWND hWnd)
{
int rcode;
imgdes simage;
int maxPages = 20; // Acquire up to 20 images
BOOL showUI = FALSE; // Hide user interface
BOOL feederEnabled; // If TRUE, ADF enabled
BOOL feederLoaded; // If TRUE, ADF has paper
TWAIN_CAP_DATA newXRes; // For setting scan resolution
TWAIN_CAP_DATA newPixType; // For setting scan bits per pixel
// Specify scan area in mils
static RECT scanRc = { 0, 0, 8500, 11000 }; // lf,tp,rt,bt
TWsetfeeder(hWnd, TRUE); // Enable ADF
TWgetfeeder(hWnd, &feederEnabled, &feederLoaded);
// Set scanning mode (this is optional)
newPixType.conType = TWON_ONEVALUE; // Container type
// TWPT_BW=0, TWPT_GRAY, TWPT_RGB, TWPT_PALETTE,
newPixType.oneValue.val = TWPT_GRAY; // Acquire grayscale image
rcode = TWsetpixeltype(hWnd, &newPixType);
// Set scanning resolution (this is optional)
newXRes.conType = TWON_ONEVALUE; // Container type
newXRes.oneValue.val = 200; // resolution = 200 dpi
rcode = TWsetxresolution(hWnd, &newXRes);
rcode = TWsetyresolution(hWnd, &newXRes);
// Acquire maxPages images, save to disk via saveImage()
rcode = TWscancountimages(hWnd, &simage, NULL, showUI,
maxPages, saveImage);
if(rcode != NO_ERROR){ // Handle any errors
TCHAR szBuff[80];
wsprintf(szBuff, _T("Error in acquiring image: %d, %d"),
rcode, TWgeterror());
MessageBox(hWnd, szBuff, _T("TWAIN Error"), MB_OK);
}
return(rcode);
}
This example acquires up to 20 images from a TWAIN source and stores them as individual TIFF files.
int AcquireAnImage(HWND hWnd, imgdes far *desimg)
{
int rcode;
// Store App name to display in Source dialog box.
// String may contain up to 32 chars.
TWsetproductname("OurApp");
// Acquire image from selected/default source
rcode = TWscanimage(hWnd, desimg);
if(rcode != NO_ERROR){ // Handle any errors
char szBuff[80];
wsprintf(szBuff, "Error in acquiring image: %d, %d",
rcode, TWgeterror());
MessageBox(hWnd, szBuff, "TWAIN Error", MB_OK);
}
return(rcode);
}
This example acquires an image from a TWAIN source and stores it in an image buffer.
int AcquireSmallImage(HWND hWnd, imgdes *desimg)
{
int rcode;
// Area to scan: 1.25 inches from left, 0.0 inches from
// top, end at 3.0 inches from left and 3.5 inches from top
static RECT scanRc = { 1250, 0, 3000, 3500 }; // lf,tp,rt,bt
BOOL showUI = FALSE; // Don't display acquire dialog
TWAIN_CAP_DATA newXRes;
TWAIN_CAP_DATA newBrt;
TWAIN_CAP_DATA newPixType;
// Store App name to display in Source dialog box.
// String may contain up to 32 chars.
TWsetproductname("OurApp");
newPixType.conType = TWON_ONEVALUE; // Container type
// TWPT_BW=0, TWPT_GRAY, TWPT_RGB, TWPT_PALETTE,
// Acquire RGB image
newPixType.oneValue.val = TWPT_RGB;
rcode = TWsetpixeltype(hWnd, &newPixType);
newBrt.conType = TWON_ONEVALUE; // Container type
newBrt.oneValue.val = 200;
rcode = TWsetbrightness(hWnd, &newBrt);
newXRes.conType = TWON_ONEVALUE; // Container type
newXRes.oneValue.val = 150; // 150 dpi
rcode = TWsetxresolution(hWnd, &newXRes);
// Acquire image from selected/default source
// without acquire dialog
rcode = TWscanimageex(hWnd, desimg, &scanRc, showUI);
if(rcode != NO_ERROR){ // Handle any errors
char szBuff[80];
wsprintf(szBuff, "Error in acquiring image: %d, %d",
rcode, TWgeterror());
MessageBox(hWnd, szBuff, "TWAIN Error", MB_OK);
}
return(rcode);
}
This example sets the pixel type, brightness, and horizontal resolution, and acquires an image from a TWAIN source without displaying the acquire dialog box.
static int imgCtr = 0; // Counts scanned images
int _export WINAPI saveScannedImage(imgdes far *simage)
{
int rcode;
char filnam[64];
// Create a filename to save the scanned image
wsprintf((LPSTR)filnam, (LPSTR)"test%d.tif", imgCtr);
// Save the image
rcode = savetif(filnam, simage, 0);
if(++imgCtr >= 10)
rcode = TWAIN_STOP_SCAN; // Quit after 10 images
// Free image buffer after it's saved
freeimage(simage);
return(rcode);
}
// Acquire command selected
int AcquireMultipleImages(HWND hWnd)
{
int rcode;
imgdes simage;
imgCtr = 0; // Initialize image counter
// Store App name to display in Source dialog box.
// String may contain up to 32 chars.
TWsetproductname("MyApp");
// Acquire images and save to disk via saveScannedImage()
rcode = TWscanmultipleimages(hWnd, &simage, saveScannedImage);
if(rcode != NO_ERROR){ // Handle any errors
char szBuff[80];
wsprintf(szBuff, "Error in acquiring image: %d, %d",
rcode, TWgeterror());
MessageBox(hWnd, szBuff, "TWAIN Error", MB_OK);
}
return(rcode);
}
This example acquires up to 10 images from a TWAIN source and stores them as TIFF files.
int SelectDefaultSource(HWND hWnd)
{
// Call the TWAIN source manager to select a data source
// for image acquisition
return(TWselectsource(hWnd));
}
The example allows the user to select a new TWAIN data source.
int SelectSourceByName(HWND hWnd)
{
LPCSTR dsname = "Logitech ScanMan";
// Select the ScanMan data source for image acquisition
return(TWselectsourcebyname(hWnd, dsname));
}
The example selects a TWAIN data source for use with the Logitech ScanMan scanner.
int setTWbright(HWND hWnd, int newbright) // newbright is 0 - 255
{
int slope, rcode;
TWAIN_CAP_DATA curBrt, newBrt;
rcode = TWgetbrightness(hWnd, &curBrt);
// If brightness is returned in a range container
if(curBrt.conType == TWON_RANGE) {
slope = (curBrt.range.max - curBrt.range.min) / 255;
newBrt.oneValue.val = slope * newbright + curBrt.range.min;
newBrt.conType = TWON_ONEVALUE; // Container type
rcode = TWsetbrightness(hWnd, &newBrt);
}
return(rcode);
}
This example sets the brightness of a TWAIN device given a brightness value between 0 and 255.
int setTWpixeltype(HWND hWnd)
{
int rcode, j, k;
TWAIN_CAP_DATA curPT, newPT;
// Pixel types, listed in preferred order
int preferred_types[3] = {TWPT_RGB, TWPT_GRAY, TWPT_BW};
rcode = TWgetpixeltype(hWnd, &curPT);
// If pixel type is returned in a range container
if(curPT.conType == TWON_ENUMERATION) {
newBrt.oneValue.val = curPT.enumType.array[0];
for(k = 0; k < 3; k++) {
for(j = 0; j < curPT.enumType.nelems; j++) {
if(preferred_types[k] == curPT.enumType.array[j]) {
newPT.oneValue.val = preferred_types[k];
goto setPT;
}
}
}
setPT:
newPT.conType = TWON_ONEVALUE; // Container type
rcode = TWsetpixeltype(hWnd, &newPT);
}
return(rcode);
}
The example sets the pixel type of a TWAIN device to one of the preferred types given.
int InitInstance(LPCSTR lpCmdLine, int nCmdShow)
{
HWND hWndMain = CreateWindow("AppName",
"AppName", WS_CAPTION | WS_SYSMENU,
0, 0, 640, 480, 0, 0, hInstance, 0);
if(hWndMain) {
// Initialize static Victor Library
VicLibStart();
// Initialize static Victor Library TWAIN Support Module
TWStaticLibStart(hInstance);
. . .
// Init application
if(InitLoadNSho(hWndMain) != NO_ERROR)
PostMessage(hWndMain, WM_DESTROY, 0, 0);
ShowWindow(hWndMain, nCmdShow); // Display main window
UpdateWindow(hWndMain);
return(TRUE);
}
return(FALSE);
}
This example function includes code that initializes the static linkable Victor Library.
void DoDestroy(HWND hWnd)
{
TWclose(); // If opened close TWAIN data source and data source manager
TWStaticLibTerm(); // Termination routine for static Vic Twain module
VicLibTerm();
. . .
PostQuitMessage(0); // Quit the application
}
The example function includes code that terminates the Victor Twain support module.
void showVicTWVersion(HWND hWnd, char *fname, imgdes *image)
{
WORD version;
char szBuff[80];
version = TWvicversion();
wsprintf(szBuff, "Victor Library TWAIN Support Module\n"
"Version %d.%02d", HIBYTE(version), LOBYTE(version));
MessageBox(hWnd, szBuff, 0, MB_OK);
}
This example displays the Victor Library TWAIN support module version number in a message box.
#define LZWKEY 1234 // Not a valid key - example only . . . unlockLZW(LZWKEY); // Enable LZW functionality . . .
This code fragment enables loading and saving GIF and TIFF-LZW files.
int updateTifBitmap(HWND hWnd, char *fname, imgdes *image)
{
char szBuff[80];
TiffData tdat;
int rcode;
// Get info on the file we're to load
rcode = tiffinfo(fname, &tdat); // Fill structure
if(rcode == NO_ERROR) {
// Allocate space for an image in global memory
rcode = allocimage(image, tdat.width, tdat.length, tdat.vbitcount);
if(rcode == NO_ERROR) {
rcode = loadtif(fname, image);
if(rcode == NO_ERROR)
// Update color table associated with image->hBitmap
updatebitmapcolortable(image);
}
}
// If there is an error, free image and display message
if(rcode != NO_ERROR) {
freeimage(image);
wsprintf(szBuff, "Could not load %s", fname);
MessageBox(hWnd, szBuff, 0, MB_OK);
}
return(rcode);
}
#include <math.h>
void gogamma(HWND hWnd, imgdes *image, double gamma)
{
double newvalue;
int j;-
unsigned char newtab[256];
char szBuff[80];
// Gamma correction: newvalue = (value/255) ** gamma * 255
for(j=0; j<256; j++) { // Create a lookup table
// newvalue = 0 to 1
newvalue = pow((double)j / 255.0, gamma);
newtab[j] = (unsigned char)(newvalue * 255.0);
}
if(usetable(newtab, newtab, newtab, image, image) !=
NO_ERROR) {
wsprintf(szBuff,"Error at usetable(), gamma: %f", gamma);
MessageBox(hWnd, szBuff, 0, MB_OK);
}
}
int InitInstance(LPCSTR lpCmdLine, int nCmdShow)
{
HWND hWndMain = CreateWindow("AppName",
"AppName", WS_CAPTION | WS_SYSMENU,
0, 0, 640, 480, 0, 0, hInstance, 0);
if(hWndMain) {
// Initialize static Victor Library
VicLibStart();
. . .
// Init application
if(InitLoadNSho(hWndMain) != NO_ERROR)
PostMessage(hWndMain, WM_DESTROY, 0, 0);
ShowWindow(hWndMain, nCmdShow); // Display main window
UpdateWindow(hWndMain);
return(TRUE);
}
return(FALSE);
}
This example function includes code that initializes the static linkable Victor Library.
void DoDestroy(HWND hWnd)
{
. . .
VicLibTerm(); // Termination routine for static Victor Library
PostQuitMessage(0); // Quit the application
}
The example function includes code that terminates the static Victor Library.
void showVicVersion(HWND hWnd, char *fname, imgdes *image)
{
WORD version;
char szBuff[80];
version = Victorversion();
wsprintf(szBuff, "Victor Library version %d.%02d",
HIBYTE(version), LOBYTE(version));
MessageBox(hWnd, szBuff, 0, MB_OK);
}
This example displays the Victor Library version number in a message box.
// Processes messages for "About" dialog box
int _export WINAPI About(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
TCHAR buff[128];
WORD version;
(void)lParam;
switch(msg) {
case WM_INITDIALOG:
{
VIC_VERSION_INFO vicVSInfo;
TCHAR versionDate[64];
CenterDlgBox(hDlg); // Center the dialog box
// Display VicDemo version
version = appVersion();
wsprintf(buff, (LPTSTR)_T("Victor Demo Program version %d.%02d"),
HIBYTE(version), LOBYTE(version));
SetDlgItemText(hDlg, IDC_VAL1, buff);
// Display Victor Library version
Victorversionex(&vicVSInfo);
wsprintf(buff, (LPTSTR)_T("Victor Library version %d.%02d,%02d"),
HIBYTE(vicVSInfo.version), LOBYTE(vicVSInfo.version),
vicVSInfo.flags);
SetDlgItemText(hDlg, IDC_VAL2, buff);
// Display Victor Library creation date
Victorversiondate(versionDate, sizeof(versionDate)/sizeof(TCHAR));
wsprintf(buff, (LPTSTR)_T("Lib created: %s"), versionDate);
SetDlgItemText(hDlg, IDC_VAL3, buff);
return(TRUE);
}
case WM_COMMAND:
if(LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) {
EndDialog(hDlg, TRUE);
return(TRUE);
}
break;
}
return(FALSE);
}
void showVicVersionex(HWND hWnd, char *fname, imgdes *image)
{
char szBuff[80];
VIC_VERSION_INFO verinfo;
Victorversionex(&verinfo);
wsprintf(szBuff, "Victor Library version %d.%02d,%02d",
HIBYTE(verfino.version), LOBYTE(verinfo.version),
verinfo.flags);
MessageBox(hWnd, szBuff, 0, MB_OK);
}
This example displays the Victor Library version information in a message box.
HPALETTE HPalette;
void setpalette(HWND hWnd, imgdes *image)
{
HDC hdc;
int DisplayBits;
hdc = GetDC(hWnd);
DisplayBits = GetDeviceCaps(hdc, BITSPIXEL);
if(DisplayBits <= 8) {
// Delete palette object previously created by victowinpal()
if(HPalette)
DeleteObject(HPalette);
// Create and realize a logical palette
victowinpal(image, &HPalette);
HPalette = SelectPalette(hdc, HPalette, 0);
RealizePalette(hdc);
// Remove logical palette before releasing DC
HPalette = SelectPalette(hdc, HPalette, 0);
}
ReleaseDC(hWnd, hdc);
}
This example creates, selects, and realizes a logical palette for image display.
// Function UpdateScrollRange is defined in viewimageex() example
imgdes Image;
HPALETTE hPalette;
HDC hdc;
PAINTSTRUCT ps;
HCURSOR hSaveCursor;
int xpos, ypos;
.
.
.
case WM_SIZE: // Size of window has changed!
UpdateScrollRanges(hWnd, &Image);
break;
case WM_PAINT: // Repaint a portion of the window!
hdc = BeginPaint(hWnd, &ps);
// Display hourglass cursor
hSaveCursor = SetCursor(LoadCursor(0, IDC_WAIT));
// Delete palette allocated by previous viewimage()
if(hPalette)
DeleteObject(hPalette);
xpos = GetScrollPos(hWnd, SB_HORZ);
ypos = GetScrollPos(hWnd, SB_VERT);
rcode = viewimage(hWnd, hdc, &hPalette, xpos, ypos, &Image);
SetCursor(hSaveCursor); // Restore cursor
EndPaint(hWnd, &ps);
break;
.
.
.
This code displays an image in a window upon receiving a WM_PAINT message.
imgdes Image;
HPALETTE hPalette;
POINT ptScrn={10, 10}; // Display image at window offset (10,10)
// Repaint a portion or all of the window
void DoPaint(HWND hWnd)
{
PAINTSTRUCT ps; // Holds PAINT info
HDC hdc;
int rcode, xpos, ypos;
hdc = BeginPaint(hWnd, &ps);
// Get the position of the upper left corner in the image
xpos = GetScrollPos(hWnd, SB_HORZ);
ypos = GetScrollPos(hWnd, SB_VERT);
if(hPalette) // Delete palette object allocated by viewimageex()
DeletePalette(hPalette);
rcode = viewimageex(hWnd, hdc, &hPalette, xpos, ypos, &Image,
ptScrn.x, ptScrn.y, VIEWDITHER);
EndPaint(hWnd, &ps);
// Handle any errors here
}
// Size of window has changed!
void DoSize(HWND hWnd, UINT state, int cx, int cy)
{
UpdateScrollRanges(hWnd, &Image);
}
// Set scroll ranges to allow using scroll box position in
// viewimageex function
void UpdateScrollRanges(HWND hwnd, imgdes *image)
{
RECT rc;
int vert_range, horiz_range, j, xpos, ypos;
static int flag;
if(flag == 0) { // Enter ftn only if we're not already here
flag++;
for(j=0; j<2; j++) {
GetClientRect(hwnd, &rc);
// Calc horizontal scroll range
horiz_range = (unsigned)image->bmh->biWidth -
rc.right + ptScrn.x;
if(horiz_range < 0)
horiz_range = 0;
SetScrollRange(hwnd, SB_HORZ, 0, horiz_range, TRUE);
// Calc vertical scroll range
vert_range = (unsigned)image->bmh->biHeight -
rc.bottom + ptScrn.y;
if(vert_range < 0)
vert_range = 0;
SetScrollRange(hwnd, SB_VERT, 0, vert_range, TRUE);
// Redraw window if a scroll position is out of range
xpos = GetScrollPos(hwnd, SB_HORZ);
ypos = GetScrollPos(hwnd, SB_VERT);
if(ypos > vert_range || xpos > horiz_range)
InvalidateRect(hwnd, 0, TRUE);
}
flag--;
}
}
This code displays an image in a window upon receiving a WM_PAINT message.
int CaptureScreenWindow(HWND hWnd)
{
int rcode;
imgdes timage;
char *fname = "window.tif";
// Capture window as Victor image
rcode = windowtoimage(hWnd, &timage);
if(rcode == NO_ERROR) {
// Save captured window
rcode = savetif(fname, &timage, 0);
// Release memory allocated by windowtoimage()
freeimage(&timage);
}
return(rcode)
}
This example captures a window's area and saves it as a TIFF file.
int pastepal(HWND hWnd, imgdes *image)
{
int rcode;
HPALETTE hPal;
if(OpenClipboard(hWnd)) {
if(hPal = GetClipboardData(CF_PALETTE)) {
// Copy the palette data into image->palette
rcode = wintovicpal(hPal, image);
}
CloseClipboard();
}
else
rcode = NO_CLIPBRD;
return(rcode);
}
This example retrieves a logical palette from the clipboard and uses it to create an image palette.
void brighten_shadows(HWND hWnd, imgdes *image1, imgdes *image2)
{
int rcode, weight=50;
// Make very dark portions of the picture visible
rcode = expandcontrast(0, 60, image1, image2);
if(rcode == NO_ERROR) {
// Combine with original image to create balanced image
rcode=wtaverage(weight, image1, image2, image2);
if(rcode != NO_ERROR)
MessageBox(hWnd, "Error at wtaverage()", 0, MB_OK);
}
else
MessageBox(hWnd, "Error at expandcontrast()", 0, MB_OK);
}
This example improves the visibility of the dark areas of an image without destroying the visibility of the bright regions.
int zero_imagearea(HWND hWnd, imgdes far *image1)
{
int rcode;
if((rcode=xorimage(image1, image1, image1)) != NO_ERROR)
MessageBox(hWnd, "Error in XORing images", 0, MB_OK);
return(rcode);
}
This example zero's the image buffer by XORing each pixel with itself.
int clear_imagebuffer(HWND hWnd, imgdes *image)
{
int rcode, newvalue=128;
setimagearea(image, 0, 0, (UINT)image->bmh->biWidth-1,
(UINT)image->bmh->biHeight-1);
if((rcode=zeroimage(newvalue, image)) != NO_ERROR)
MessageBox(hWnd, "Error in clearing buffer", 0, MB_OK);
return(rcode);
}
This example sets the image area to the size of the entire buffer, and sets all pixels to 128.
void free_image(imgdes *image)
{
HGLOBAL hMem;
hMem = GlobalPtrHandle(image->bmh); // Macro in WINDOWSX.H
if(hMem) {
GlobalUnlock(hMem);
GlobalFree(hMem);
zeroimgdes(image); // Zero the image descriptor
}
}
This example frees the memory assigned to a packed DIB and zeros the image descriptor.