Victor Image Processing Library How-to Tips

Display a Sticky Note on an Image

A sticky note is a little reminder that gets displayed on top of an image. The paper version was invented by 3M and quickly made it's way onto all of our desks and papers. With this code example you can create sticky notes for display on your images.

Image displayed in a Window with a sticky note reminder


The image and the sticky note are displayed together within the same window. This is a simple approach where the application keeps track of the message as a text string and screen position in which to display it. The image is not altered by the note.

To display the image with the note the steps are:

Display a Sticky Note on an Image - the Source Code

Requires Victor Image Processing Library for Windows v 4.1x or higher.
int viewstickynote(int scrx, int scry, char far *thetext)
{
#define FONT_FOR_STICKYNOTE_SIZE 18
   static LOGFONT lf = { // Use font described by LOGFONT struct
      0, 0, 0, 0, FW_NORMAL, 0, 0, 0,
      ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
      DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, "MYSTICAL"
      };
   HFONT hFont, hOldFont;
   HPEN hpen, hpenshado, hpenOld;
   HBRUSH hbrush, hbrushshado, hbrushOld;
   HWND hWnd;
   HDC hDC;
   RECT rc, wndrc;
   int rcode = NO_ERROR, captionHt, captionWd, wndextent, maxnotewid = 250, margin=5;
   int noteWd, noteHt, offsetshado=3;
   hDC = GetDC(hWnd= GetActiveWindow());
            // Set the font point size
   lf.lfHeight= - MulDiv(FONT_FOR_STICKYNOTE_SIZE, GetDeviceCaps(hDC,
      LOGPIXELSY), 72);
   hFont = CreateFontIndirect(&lf); // Create our font
   SetBkMode(hDC, TRANSPARENT);  // Set background to transparent (or opaque)
   hOldFont = SelectObject(hDC, hFont); // Select font into DC
            // Don't write any text, just fill rc with text dimensions
   DrawText(hDC, thetext, -1, &rc, DT_CALCRECT ); 
   GetWindowRect(hWnd, &wndrc);
            // Calculate the text size 
   captionHt = rc.bottom - rc.top + 1;
   captionWd = rc.right - rc.left + 1;
            // Keep text in window
   wndextent = wndrc.right - wndrc.left + 1;
   if(wndextent - scrx < maxnotewid)
      maxnotewid = wndextent - scrx;
   if(captionWd > maxnotewid || captionWd < 0) {
      rc.left = 0;
      rc.right = maxnotewid - 2 * margin;
      DrawText(hDC, thetext, -1, &rc, DT_CALCRECT | DT_WORDBREAK); 
      captionHt = rc.bottom - rc.top + 1;
      captionWd = rc.right - rc.left + 1;
      }
   noteWd = captionWd + 2 * margin;
   noteHt = captionHt;
   
            // Draw a yellow sheet with shadow
            // Create a pale yellow pen and brush
   hpen = CreatePen(PS_SOLID, 1, RGB(255, 255, 102));
   hbrush = CreateSolidBrush(RGB(255, 255, 102));
            // Select the new pen and brush, draw the note paper
   hpenOld = SelectObject(hDC, hpen);
   hbrushOld = SelectObject(hDC, hbrush);
   Rectangle(hDC, scrx, scry, scrx+noteWd, scry+noteHt);
   
            // Give it a gray shadow
   hbrushshado = CreateSolidBrush(RGB(128, 128, 128));
   hpenshado = CreatePen(PS_SOLID, 1, RGB(128, 128, 128));
   SelectObject(hDC, hbrushshado);
   SelectObject(hDC, hpenshado);
   Rectangle(hDC, scrx+noteWd, scry+offsetshado, scrx+noteWd+offsetshado, scry+noteHt);
   Rectangle(hDC, scrx+offsetshado, scry+noteHt, scrx+noteWd+offsetshado, scry+noteHt+offsetshado);
            // Clean up
   SelectObject(hDC, hpenOld);
   DeleteObject(hpen);
   SelectObject(hDC, hbrushOld);
   DeleteObject(hbrush);
   DeleteObject(hbrushshado);
   DeleteObject(hpenshado);
            // Write the text for the note
   SetRect(&rc, scrx+margin, scry, scrx+margin+captionWd, scry+captionHt);
   DrawText(hDC, thetext, -1, &rc, DT_LEFT|DT_NOCLIP|DT_WORDBREAK);
   ReleaseDC(hWnd, hDC);
   return(rcode);
}
And call viewstickynote from your application's WM_PAINT message handler.
void DoPaint(HWND hWnd)
{
   PAINTSTRUCT ps;   // Holds PAINT info
   HDC hdc;
   int rcode, xpos, ypos;
   StartWait(); // Display the hourglass cursor
   hdc = BeginPaint(hWnd, &ps);
            // Get the position of the upper left corner in the image buffer
   xpos = GetScrollPos(hWnd, SB_HORZ);
   ypos = GetScrollPos(hWnd, SB_VERT);
   if(HPalette)   // Delete palette object allocated by viewimageex()
      DeletePalette(HPalette);
   // Display the image
   rcode = viewimageex(hWnd, hdc, &HPalette, xpos, ypos, &Image, 0, 0, ColorRednMode);
            // Display a sticky note message on the image, the starting position was
   // set by the mouse and is stored in the image descriptor elements stx and sty
   rcode = viewstickynote(Image.stx, Image.sty, "Save as JPEG, then upload to website -- J.");
   EndPaint(hWnd, &ps);
   EndWait();      // Restore the cursor
            // Handle any errors
   if(rcode != NO_ERROR)
      error_handler(hWnd, rcode);
}

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


Victor Image Processing Library homepage | Victor Sample Code