Overblog
Editer l'article Suivre ce blog Administration + Créer mon blog
1 octobre 2006 7 01 /10 /octobre /2006 11:15

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,'SETCONN','the_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',1,'SETUSER','username');


Set the password

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


Set the
database image table information

Set_Custom_Property('BLOCK.ITEM',1,'SETTABLEINFO','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',1,'READIMGFILE','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).
Partager cet article
Repost0

commentaires

J
Hi FrancoisI've studied your code for this PJC, because I need to create something similar myself. There is one aspect, that makes your approach unusable to me though, and that's the fact, that your PJC requires the client to actually be able to access the database directly. In a web deployment, where the only access to the database is through the Application Server, it's impossible to do it like this. What I'm wondering is - wouldn't it be a better idea to use WebUtil to physically transfer the file to the application server, and as soon as the transfer has completed, invoke a server-side class made with the Java Importer to store the image in a specific BLOB? Have you ever tried doing it this way?Thanks,Jacob
Répondre
O
My goal was to not use the Webutil library. In fact, what I am really targeting is to pass the binary content from the Bean to Forms, then use the current connexion to store the image into the database. At this moment, I am not able to manage this ; for an unknown reason, 5 characters are misinterpreted then poison the whole image.Francois
P
I read image from local mashine in item bean but I would like to off border.<br /> help me please
Répondre
O
Hello,In the public void init(IHandler handler) method, replace the following code:<br />         border = BorderFactory.createTitledBorder(loweredetched) ;        mp.setBorder(border);<br /> by:<br />         border = BorderFactory.createEmptyBorder() ;        mp.setBorder(border);
J
Hi, I've been tried your pjc, and I've 2 questions:<br /> 1.- Why the only image file types i can read from file are JPEG files and not TIFF or BMP types?<br /> 2.- When I try to read a blob column from the database, the ii.getIconWidth() and ii.getIconHeight() methods returns -1 (both methods) ? In fact I cant read/write any image file types from / to database, what could be wrong?<br /> Thanks so much for this site, It's very useful
Répondre
O
1. Yes, the default images format read by the component are the web ones.If you want to load other types, you have to use the Java Advanced Imaginghttp://java.sun.com/products/java-media/jai/iio.html.2. When I try to read a blob column from the database...use the Set_Custom_Property( 'YOUR_BLOCK.YOUR_BEAN', 1, 'SETLOG' , 'true' ) ; to output messages to the Java console when using this bean. You'd probably get an error message.Francois
M
I googled Distrib but could not find it.<br />  <br /> Can you give a pointer?<br />  <br /> Also, is it suitable for a web based deployment to anonymous users?
Répondre
O
Sorry, The product that I talked about is an internal made soft.It appears that teledistribution softwares are pretty expansive. More simpler is to use .bat files or VBS (Visual Basic Script) in conjonction with a logon.bat file.If you cannot find anything about this, I will send you an example in a few days.
M
Any solution that requires manually editing files on the client doesn't seem very practical.<br /> Do you have any thoughts on how to manage deployment?
Répondre
O
Some products are made to accomplish this task. At startup, they load onto your machine all the programes you need, and are able to copy anything, like a particular tnsnames.ora file for instance. My company uses : Distrib, but you could probably find something else.Francois