Purpose

Here is a Java Bean that allows reading, displaying with scaling and writing images.

It allows scaling images to fit the target item size, and includes a FileChooser with image preview dialog.

In its third version, it does not need any JDBC connexion to handle images from/to the database
.

It uses the JRE 1.4 javax.imageio.ImageIO package, so it needs, at least the Sun Java plugin 1.4.
It won't run against JInitiator.



handleimage3



The Java code

     HandleImage.java      GetImageFileName.java



The implementation class of the Bean Item

     oracle.forms.fd.HandleImage



The methods you can call




Read an image from a file


Set_Custom_Property('BLOCK.ITEM',1READIMGFILE','the_complete_filename');

e.g.:
-- read image from the file system --
Set_Custom_Property( 'BLZ.BEAN', 1, 'READIMGFILE', 'D:/image.jpg' ) ;
 

-- read image from the JAR file --
Set_Custom_Property( 'BLZ.BEAN', 1, 'READIMGFILE', '/image.jpg' ) ;

-- read image from the Internet --
Set_Custom_Property( 'BLZ.BEAN', 1, 'READIMGFILE', 'http://the_url/image.jpg' ) ;




Read an image from the database table

The reading process is composed by three steps:

1. Select the Blob table's column
2. Read the image chunks and send them to the Java Bean
3. End the sending process


1. Select the Blob table's column:

Pkg_Read_Blob_Image.Select_Blob(LC$Clause); (*)

LC$Clause is a string that must contain the Select order to fetch the corresponding single row:

 LC$Clause := 'Select PHOTO_JAVA From PHOTOS Where IDENTIFIANT = 10'  ;
 -- Select the Blob column --
 If Pkg_Read_Blob_Image.Select_Blob(LC$Clause) Then
    ...


2. Read the image chunks from the database then send them to the Java Bean:

Pkg_Read_Blob_Image.Get_B64_Chunk() (*)

     -- Get the image chunks from the database --
     LC$Image := Pkg_Read_Blob_Image.Get_B64_Chunk ;
     If LC$Image Is Not Null Then
       -- Send the chunks to the Java Bean --
       Set_Custom_Property( 'BLZ.BEAN', 1, 'READIMGBASE', LC$Image ) ;

3. End the sending process:

     Else
       -- End the sending process --
       Set_Custom_Property( 'BLZ.BEAN', 1, 'READIMGBASE', '[END_IMAGE]' )
;


(*) the PKG_READ_BLOB_IMAGE database's package is provided with the zip file.


e.g.:

PROCEDURE Read_Image IS
  LB$Ok      boolean ;
  LC$Image   Varchar2(32767) ;
  LC$Clause  Varchar2(4000) ;
BEGIN
 
 --
 -- Read an image from the database
 --
 LC$Clause := 'Select PHOTO_JAVA From PHOTOS Where IDENTIFIANT = ' || :PHOTOS.IDENTIFIANT ;
 -- Select the Blob column --
 If Pkg_Read_Blob_Image.Select_Blob(LC$Clause) Then
   Loop
     -- Get the image chunks from the database --
     LC$Image := Pkg_Read_Blob_Image.Get_B64_Chunk ;
     If LC$Image Is Not Null Then
       -- Send the chunks to the Java Bean --
       Set_Custom_Property( 'BLZ.BEAN', 1, 'READIMGBASE', LC$Image ) ;
     Else
       -- End the sending process --
       Set_Custom_Property( 'BLZ.BEAN', 1, 'READIMGBASE', '[END_IMAGE]' ) ;
       Exit ;
     End if ; 
   End loop ;
 End if ; 
  
END;



Put this method into the When-New-Record-Instance block-level trigger


Write an image to the database table


The writing process is also composed by three steps:

1. Initialize the transfer
2. Read the image chunks from the Java Bean and send them to the database
3. Update the Blob column with the new content


1. Initialize the transfer:

Pkg_Read_Blob_Image.Init_Transfer() (*)

This will empty the current Blob column:

 Pkg_Read_Blob_Image.Init_Transfer ;

2. Read the image chunks from the Java Bean and send them to the database
:

Get_Custom_Property('BLZ.BEAN',1,'GETIMAGE

Pkg_Read_Blob_Image.Set_B64_Chunk(LC$Req) (*)

    Loop
      -- Get the image chunk from the Java Bean --
      LC$Req := Get_Custom_Property('BLZ.BEAN',1,'GETIMAGE
      Exit When LC$Req is null ;
      ...   
      -- Send the image chunks to the Database --
      Pkg_Read_Blob_Image.Set_B64_Chunk(LC$Req);
    End loop;

3. Update the Blob column with the new content:

     LC$Res := Pkg_Read_Blob_Image.Save_Blob('PHOTOS','PHOTO_JAVA','IDENTIFIANT=' || :PHOTOS.IDENTIFIANT );

The Save_Blob() function takes the table name, the blob column name and the Where clause arguments.


(*) the PKG_READ_BLOB_IMAGE database's package is provided with the zip file.

Put this method into the Post-Insert and Post-Update block-level trigger

e.g.:

PROCEDURE Save_Image IS
    LC$Req  Varchar2(32000);
    LN$Cpt  Pls_integer := 0 ;
    LC$Res  Varchar2(2000) ;
BEGIN
    --
    -- Save the image to the database
    --
    Loop
      -- Get the image chunk from the Java Bean --
      LC$Req := Get_Custom_Property('BLZ.BEAN',1,'GETIMAGE
      Exit When LC$Req is null ;
      LN$Cpt := LN$Cpt + 1 ;
      If Ln$Cpt = 1 Then
         Pkg_Read_Blob_Image.Init_Transfer ;
      End if ;  
      -- Send the image chunks to the Database --
      Pkg_Read_Blob_Image.Set_B64_Chunk(LC$Req);
    End loop;
    If LN$Cpt > 0 Then
      -- Update the Blob column with the new content --
      LC$Res := Pkg_Read_Blob_Image.Save_Blob('PHOTOS','PHOTO_JAVA','IDENTIFIANT=' || :PHOTOS.IDENTIFIANT );
    End if ;
    Clear_Message ;
    Message('Result:'|| LC$Res, no_acknowledge);
END;


Put this method into the Post-Insert and Post-Update block-level triggers


Clear the image

Set_Custom_Property( 'BL.BEAN', 1, '
CLEAR' , '' ) ;

This function has to be called in a When-New-Record-Instance trigger if the record does not exist:

When-New-Record-Instance trigger:
If :PHOTOS.IDENTIFIANT is not null Then
   Read_Image ;
Else
   Set_Custom_Property( 'BLZ.BEAN', 1, 'CLEAR', '' ) ;
End if ;
:BLZ.IMG_SIZE := Get_Custom_Property( 'BLZ.BEAN', 1, 'GETSIZE' ) ;


Set the display image scalling

This function concerns only the image displayed. The image stored with the WRITEIMGBASE method will be the initial image.

Set_Custom_Property( 'BL.BEAN', 1, '
SCALE_IMAGE
','Width=x,Height= y' ) ;

Both Width and Height parameters must be transmitted

x and y can take the following values:


Any value greater then 0 that express an absolute size in pixels
the special value: FIT that extends the image to fit the exact size of the image panel' size
-1 that to keep the corresponding aspect ratio
0 that indicates no scale at all



Examples:

-- Scale the image to fit horizontally and vertically the image item --

Set_Custom_Property('BLZ.BEAN',1,'SCALE_IMAGEh=FIT,Height=FIT' ) ;

-- Scale the image to 200x100 pixels --
Set_Custom_Property('BLZ.BEAN',1,'SCALE_IMAGEh=200,Height=100' ) ;
-- Scale the image to 200 horizontal pixels and keep vertical aspect ratio --
Set_Custom_Property('BLZ.BEAN',1,'SCALE_IMAGEh=200,Height=-1' ) ;





Display/hide the image panel' scrollbars

Set_Custom_Property('BLOCK.ITEM',1SETSCROLL','true|false');


e.g.:
Set_Custom_Property( 'BLZ.BEAN', 1, 'SETSCROLL', 'true' ) ; 





Set the item border

Set_Custom_Property('BLOCK.ITEM',1,'SETBORDER','thick[,color]');


e.g.:

-- set a null border --
Set_Custom_Property( 'BLZ.BEAN', 1, 'SETBORDER', '0' ) ; 

-- set a 4 pixel red border --
Set_Custom_Property( 'BLZ.BEAN', 1, 'SETBORDER', '4,r255g0b0' ) ; 



Set the JFileChooser title and starting directory

Set_Custom_Property('BLOCK.ITEM',1SET_FILECHOOSER_TITLE','title[,directory]');

e.g.:
Set_Custom_Property( 'BLZ.BEAN', 1, 'SET_FILECHOOSER_TITLE', 'Select a file,D:/' ) ; 

the directory argument is not mandatory



Set the JFileChooser Look and Feel


Set_Custom_Property('BLOCK.ITEM',1SET_FILECHOOSER_LAF','SYSTEM|other_value');


e.g.:
-- use the current O.S. L&F --
Set_Custom_Property( 'BLZ.BEAN', 1, 'SET_FILECHOOSER_LAF ', 'SYSTEM' ) ;
 

-- use the Metal L&F --
Set_Custom_Property( 'BLZ.BEAN', 1, 'SET_FILECHOOSER_LAF ', 'JAVA' ) ;
 


Set the log mode to output the Bean messages

Set_Custom_Property( 'BL
.BEAN', 1, 'SETLOG' , 'true|false' ) ;



In the sample dialog provided, here is the code used in the When-New-Form-Instance trigger:

PROCEDURE InitForm IS
BEGIN
  -- switch the log to true --
  Set_Custom_Property( 'BLZ.BEAN', 1, 'SETLOG', 'true' ) ;
  -- set the baen image bckground color --
  Set_Custom_Property( 'BLZ.BEAN', 1, 'SETBG', '255,255,255' ) ;
  -- Set the JFileChooser title --
  Set_Custom_Property( 'BLZ.BEAN', 1, 'SET_FILECHOOSER_TITLE',  'Select an image file' ) ;
  -- Set the JFileChooser L&F --
  Set_Custom_Property( 'BLZ.BEAN', 1, 'SET_FILECHOOSER_LAF', 'SYSTEM' ) ;
  -- scalling properties --

  Set_Custom_Property('BLZ.BEAN',1,'SCALE_IMAGE','Width=FIT,Height=FIT
  -- display scrollbars policy --
  Set_Custom_Property( 'BLZ.BEAN', 1, 'SETSCROLL',  'false' ) ;
 
END;

Here is the description of the database table used:

CREATE TABLE PHOTOS
   (   
      "IDENTIFIANT" NUMBER(5,0) NOT NULL ENABLE,
      "NOM" VARCHAR2(50 BYTE),
      "PHOTO" BLOB,
      "PHOTO_JAVA" BLOB,
      CONSTRAINT "PHOTO_PK" PRIMARY KEY ("IDENTIFIANT") ENABLE
   )
/



The properties you can get from the JavaBean


Get the image size

Varchar2 :=
Get_Custom_Property( 'BL.BEAN', 1, 'GETSIZE'
) ;

The format returned (width,height) is like the following : 50,120



Get the
selected filename (JFileChooser)

Varchar2 :=
Get_Custom_Property( 'BL.BEAN', 1, 'GET_FILE_NAME' ) ;

this method both displays the JFileChooser and returns the selected file.



Get the current image chunks

Varchar2 :=
Get_Custom_Property( 'BL.BEAN', 1, 'GETIMAGE' ) ;

This method returns the last image read by the READIMGFILE() method..
It returns null when the image is completly read.

 


The events raised to Forms


Two events are raised by the Java Bean to Forms:

 

MOUSE_CLICKED and MOUSE_DOUBLECLICKED that you can trap through the When-Custom-Item-Event trigger:

 

DECLARE
    eventName varchar2(30) := :system.custom_item_event;
    eventValues ParamList;
    eventValueType number;
BEGIN
   IF (eventName='MOUSE_DOUBLECLICKED') THEN
      Message('Mouse double-click',no_acknowledge);
   ElsIF (eventName='MOUSE_CLICKED') THEN
      Message('Mouse click',no_acknowledge);
   END IF;
END;


 

The sample dialog


     . Download the handleimage3.zip file
     . Unzip the file
     . run the create_table.sql script under the Oracle user you want to test (It creates the sample image table).
     . run the PKG_READ_BLOB_IMAGE.sql script under the Oracle user you want to test (It creates the database package).
     . copy the handleimage3.jar file in the <ORACLE_HOME>/forms/java directory
     . Edit your /forms/server/formsweb.cfg file to add the handleimage3.jar .
     . Open the HANDLEIMAGE3.fmb module (Oracle Forms 9.0.2)
     . Compile all and run the module



Note : If you rebuild the jar file, it has to be signed. (the handleimage3.jar file provided in this article is already signed).