Purpose

Here is a Java Bean that allows to read, display and write images.

(See the last evolution of this solution here


When you load an image within Forms with the Read_Image_File() built-in, you can notice a certain lack of quality, both in the Forms Image item display quality and in the real information stored in the blob column.
The image seems to be compressed before it is stored in the database. This compression rate is between 25 and 50% !
This Java Bean allows to load images from a file, then store them in the database.

The Forms sample dialog provided with the article uses two image rooms:

 - The first one is a standard Forms Image item that is populated with the Client_Image.Read_Image_File() Webutil function that populates the PHOTO blob column.


 - The second one is the Java Bean itself that populates the PHOTO_JAVA blob column.


As you see as follows, the Read_Image_File() function can drastically compress the initial image:

1 select
2 identifiant,
3 length(photo),
4 length(photo_java),
5 round((length(photo)/length(photo_java)*100),1) || '%' "photo reduction"
6 from photos
7* where photo is not null
SQL> /

IDENTIFIANT LENGTH(PHOTO) LENGTH(PHOTO_JAVA) photo reduction
----------- ------------- ------------------ ---------------
2           23536         100952             23.3%
1            6763          13548             49.9%
 

This JavaBean connect to the database through the JDBC driver to read and write the images.
Of course, some of you can complain that this solution needs a second connection, the loading of the classes12.jar file on the client machine, so it is "deconnected" from the Forms transaction.
For this very moment, my answer is : everything has its price, and if you need to keep and display the real quality of the images in your Forms application, this bean is the one you need.

Let's see the screenshot to decide !

handleimage small format

Click here to get the full format image


The Java code

     HandleImage.java     LectureBlob.java    myPanel.java



The implementation class of the Bean Item

     oracle.forms.fd.HandleImage



The methods you can call

Set the connection string

Set_Custom_Property('BLOCK.ITEM',1,'SETCONNthe_connection_string');

e.g. :
Set_Custom_Property( 'BL.BEAN', 1, '
SETCONN', 'jdbc:oracle:thin:@my-machine:1521:XE' ) ;   
(Provide the complete jdbc:oracle:thin:... syntax)


Set the username


Set_Custom_Property('BLOCK.ITEM',1SETUSER','username');


Set the password

Set_Custom_Property('BLOCK.ITEM',1SETPWD','password');


Set the database image table information


Set_Custom_Property('BLOCK.ITEM',1SETTABLEINFO','p1,p2,p3');

p1 is the table name that hold the image blob column
p2 is the column name that hold the image
p3 is the column name that identifies the unique row in the table (for the UPDATE statment)

e.g.:
Set_Custom_Property( 'BLZ.BEAN', 1, 'SETTABLEINFO', 'PHOTOS,PHOTO_JAVA,IDENTIFIANT' ) ;  

The instruction above indicates that the PHOTOS table handle images in the PHOTO_JAVA blob column, and the key column that identifies the unique row is IDENTIFIANT.


Read an image from a local file


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

e.g.:
Set_Custom_Property( 'BLZ.BEAN', 1, 'READIMGFILE', 'D:/image.jpg' ) ; 


Read an image from the database table

Set_Custom_Property('BLOCK.ITEM',1,'READIMGBASE,'unique_ID');

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

unique_ID is the value to identify a unique row to update in the table. The above instruction will be interpreted as :

   Select PHOTO_JAVA From PHOTOS Where IDENTIFIANT = 1


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


Write an image to the database table


Set_Custom_Property('BLOCK.ITEM',1,'WRITEIMGFILE','unique_ID');

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

unique_ID is the value to identify a unique row to update in the table.
The above instruction will be interpreted as :

   Update PHOTOS Set PHOTO_JAVA = ? Where IDENTIFIANT = 1


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
   Set_Custom_Property( 'BLZ.BEAN', 1, 'READIMGBASE', :PHOTOS.IDENTIFIANT ) ;
Else
   Set_Custom_Property( 'BLZ.BEAN', 1, 'CLEAR', '' ) ;
End if ;
:BLZ.IMG_SIZE := Get_Custom_Property( 'BLZ.BEAN', 1, 'GETSIZE' ) ;


Set the log mode to output the Bean messages

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



Set mode to allow the display of the scrollbars if needed

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


In the sample dialog, 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 JDBC connection information --
  Set_Custom_Property( 'BLZ.BEAN', 1, 'SETCONN', 'jdbc:oracle:thin:@my-machine:1521:XE' ) ;
  Set_Custom_Property( 'BLZ.BEAN', 1, 'SETUSER', 'tutoforms' ) ;
  Set_Custom_Property( 'BLZ.BEAN', 1, 'SETPWD',  'tuto' ) ;
  -- set the image table and column name --
  Set_Custom_Property( 'BLZ.BEAN', 1, 'SETTABLEINFO',  'PHOTOS,PHOTO_JAVA,IDENTIFIANT' ) ;
  -- allow the bean to display scrollbars --
  Set_Custom_Property( 'BLZ.BEAN', 1, 'SETSCROLL',  'true' ) ; 
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


Accessing to a remote database

Because the JavaBean is executed within an applet, it is not possible to connect to a remote database without a little adaptation:

   - first, the jar file must be signed.
   - second : you have to update the java.policy file stored in the Jinitiator directory

For example, to access to the database located on the machine-name server on the port 1524, add the following lines to the java.policy file:

C:/Program Files/Oracle/JInitiator 1.3.1.xx/lib/security/java.policy file

 

 permission java.net.SocketPermission "machine-name:1524-", "accept,connect,listen,resolve"; 
permission java.security.AllPermission;



The sample dialog



     . Download the handleimage.zip file
     . Unzip the file
     . run the create_table.sql under the Oracle user you want to test (It creates the sample image table).
     . copy the handleimages.jar file in the <ORACLE_HOME>/forms/java directory
     . Edit your /forms/server/formsweb.cfg file to add both handleimages.jar and classes12.jar (the classes12.jar is located in the <DEV_HOME>/jdbc/lib directory. add a copy of this file in the <DEV_HOME>/forms/java directory).
     . Open the HANDLEIMAGE.fmb module (Oracle Forms 10.1.2)
     . Compile all and run the module

     . Enter a valid file name in the Image File name item then press the Read image file button

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