Drawing device independent bitmaps

In this section:

When using %gr (Graphics Region) and its associated drawing surfaces (including internal and printer drawing surfaces) there are two sets of routines for processing device independent bitmaps (DIBs). The first set uses a CHARACTER array supplied by the programmer. The second uses a handle supplied by ClearWin+. (See also Using image resources.)

Using a 24 bit per pixel array

The following routines are used to handle device independent bitmaps:

GET_DIB_SIZE@

Gets parameters from a bitmap or JPEG file.

GET_DIB_BLOCK@

Extracts a rectangular block from a bitmap or JPEG file.

PUT_DIB_BLOCK@

Saves a rectangular block to a bitmap or JPEG file.

DISPLAY_DIB_BLOCK@

Displays a block on the current drawing surface.

RECOVER_DIB_BLOCK@

Recovers the block from the current drawing surface.


GET_DIB_SIZE@ obtains information about an existing .BMP file. The file name is an input argument that should have the .BMP suffix. The file name may be a full path name. If the routine succeeds, an error code is returned with the value zero whilst other arguments return the width and height (in pixels) of the image contained in the file. The number of bits per pixel is also returned as one of the following values:

1

Monochrome black and white image

4

16-colour image

8

256-colour image

24

Full colour image in which each pixel is represented by eight bits per red/green/blue value.


GET_DIB_BLOCK@ extracts a rectangular block (that could be the whole image) from a given file into an array. The first index of the array is the colour index in the order (red, green, blue). Displacements AX and AY into the array are typically zero but they can be set to other values if, for example, the array is to be composed of a montage of several blocks. Arguments W and H represent the width and height of the block to be transferred, whilst DX, DY represent the displacement (again typically zero) into the image in the file.

DISPLAY_DIB_BLOCK@ transfers a rectangular block of given size (W x H) from the array at a position (AX, AY) to a position (X, Y) on the current drawing surface (e.g. a %gr (Graphics Region) region or a printer). Two arguments named FUNCTION and MODE are normally set to zero. An argument for the error status is returned as zero if the process is successful.

PUT_DIB_BLOCK@ transfers a rectangular block from an array to given file, destroying any previous contents. Displacements AX and AY into the array are typically zero, whilst arguments W and H are the width and height of the image to be created. An argument for the number of bits per pixel is currently ignored and should set to 24. This routine always writes BMP files with 24 bits per pixel.

The use of these routines is best illustrated by a simple example. The following example reads a BMP file, alters the array to draw a red line through the image, displays the result, and writes a new BMP file with the modified image.

      WINAPP
      INCLUDE <windows.ins>
      CHARACTER*50 file
      CHARACTER a(3,1024,1024)
      INTEGER hres,vres,nb_colours,ier,i,k,control
c---  Note - you may need to alter this path
      file='c:\windows\setup.bmp'
      CALL get_dib_size@(file,hres,vres,nb_colours,ier)
      IF(ier.NE.0.OR.hres.GT.1024.OR.vres.GT.1024) STOP 'TROUBLE'
      CALL get_dib_block@(file,a,1024,1024,0,0,hres,vres,0,0,ier)
      IF(ier.NE.0) STOP 'TROUBLE'
c---  Draw a diagonal red stripe over the image
      k=MIN(hres,vres)
      DO i=1,k
       a(1,i,i)=char(255)
       a(2,i,i)=char(0)
       a(3,i,i)=char(0)
      ENDDO
c---  Display the image
      i=winio@('%gr%lw',hres,vres,control)
      CALL display_dib_block@(0,0,a,1024,1024,0,0,hres,vres,0,0,ier)
c---  Write the image away to another file      
      file='c:\temp\junk.bmp'
      CALL put_dib_block@(file,a,1024,1024,0,0,hres,vres,24,ier)
      END

The example is written in Fortran 77 with the array A declared to be 'sufficiently large'. With Fortran 90 you can use an allocatable array instead. Note that the resulting BMP file will typically be larger than the original because the colours will have been expanded to 24 bits per pixel.

Using a DIB handle

An alternative approach is to use routines that transmit a handle for a device independent bitmap.

The routines IMPORT_BMP@, IMPORT_PCX@, GET_SCREEN_DIB@ and CLIPBOARD_TO_SCREEN_BLOCK@ each return a handle to a DIB. This handle is then used in DIB_PAINT@, PRINT_DIB@ (now superceded by DIB_PRINT@), EXPORT_BMP@ and EXPORT_PCX@. When it is no longer needed the associated memory can be released using RELEASE_SCREEN_DIB@.

You can also use WRITE_GRAPHICS_TO_BMP@ and WRITE_GRAPHICS_TO_PCX@ in order to write the current drawing surface to a file.

Here is a simple program that uses some of these routines:

WINAPP
 INCLUDE <windows.ins>
 INTEGER hres,vres,nbbp,ercode,hdib,ctrl,i,width,height
 CHARACTER*50 file
 file='c:\windows\setup.bmp'
 CALL get_dib_size@(file,hres,vres,nbbp,ercode)
 IF(ercode.NE.0) STOP 'Size error' 
 hdib=import_bmp@(file,ercode)
 IF(ercode.NE.0) STOP 'Import error'
 i=winio@('%gr[rgb_colours]%lw',hres,vres,ctrl)
 ercode=dib_paint@(0,0,hdib,0,0)
 IF(ercode.EQ.0) STOP 'Paint error'
 call draw_line_between@(0,0,hres,vres,RGB@(255,0,0))
 IF(open_printer@(7).EQ.1)THEN
   CALL get_graphical_resolution@(width,height)
   ercode=print_dib@(7,0,0,width,height,hdib,0,0,hres,vres)
   IF(ercode.EQ.0) STOP 'Print error'
   ercode=close_printer@(7)
   IF(ercode.EQ.0) STOP 'Close printer error'
  ENDIF
  CALL release_screen_dib@(hdib)
 END

This program imports a bitmap and then creates a drawing surface on the screen using %gr (Graphics Region). The bitmap is drawn to the screen and a red line is draw across it. The standard printer dialog is then displayed via a call to OPEN_PRINTER@. If the user clicks on the OK button, the routine returns the value 1 and the current graphics device is now the printer with device handle 7. The bitmap is drawn to this device. Calling CLOSE_PRINTER@ sends the image to the printer.

 

 

Basket
Empty
 
Copyright © 1999-2024 Silverfrost Limited