Quantcast
Channel: SCN : Document List - ABAP Development
Viewing all articles
Browse latest Browse all 935

Employee Photo - Bitmap Automation (for Dynamic Employee Photos in Smartforms)

$
0
0

EMPLOYEE PHOTO - BITMAP AUTOMATION

( TO BE DISPLAYED ON SMARTFORMS )

 

Recently we needed the functionality to print Employee Photos on smartforms. As smartforms only show BMP files uploaded via SE78 and employee photos are mostly JPG files with different stories we had to make some sort of automation that gets the employee photo, converts it to bitmap file and upload this BMP file to SE78 via background processing.

 

1. Displaying Pictures Dynamically in Smartforms

 

First we create a dummy smartform and an input parameter for SE78 file name (IPERNR in our case).

 

1.jpg

 

Then we put a graphic component in our smartform  parameters as below.

 

2.jpg

 

Here; &IPERNR& variable should have the name of an SE78 GRAPHICS file with ID = BMAP and type = BCOL (for Colored Images).

 

3.jpg

 

Below screenshots are smartform test screen and SE78 display screen, IPERNR parameter has the same name as image name in SE78.

 

21.jpg

5.jpg

 

We can see and print the image succesfully.

 

6.jpg

 

2. Converting External Image Formats (JPG/GIF/TIFF/PNG) to Bitmap

 

SAP has a class CL_IGS_IMAGE_CONVERTOR for these purposes.

 

7.jpg

 

This class has below public methods that all together used to set and convert image files with extensions JPG, GIF, TIFF and PNG.

 

8.jpg

 

There is a prerequisite to use this class properly and that is IGS (Internet Graphics Server) must be up and running. If IGS is not installed and configured, you should receive RFC Destination error. IGS is explained below.

 

 

 

3. IGS (Internet Graphics Server)


"Execute" method of class CL_IGS_IMAGE_CONVERTER uses below RFC destination as default to send file to IGS for conversion so if IGS is not up and running you should get an RFC error and conversion process will not work.

 

9.jpg10.jpg

11.jpg

 

If Connection Test is succesful than we can say the IGS is up and running.

12.jpg

 

4. Note 454042 - IGS: Installing and Configuring the IGS

 

If IGS is not running than BASIS should apply this note which explains the steps clearly.

 

454042 - IGS: Installing and Configuring the IGS

 

5. Programming Step

 

Some number of approaches can be used to develop this kind of program. As SE78 and similar tcodes work on frontend services like GUI_UPLOAD, I used DATASET logic to handle data uploading and data storing. (Complete source code added at the end of the document.)

I used PNP logical database as I want to fetch Employee Photo. The logic of the program goes like this.

 

13.jpg

 

fetch_and_convert_emp_photo subroutine starts with employee photo check.

 

14.jpg

then we get the binary data for the file

 

15.jpg

then we write the binary file to /usr/sap/trans/ directory

 

16.jpg

 

then we read this file into an xstring typed variable and delete the JPG file from directory. Here I used FM - ZBMP_CREATE_FROM_EXT_FORMAT which gets the xstring file and converts to bitmap.

 

17.jpg

 

Thomas Jung has a nice article about ABAP Bitmap Image Processing Class which tells us about ZCL_ABAP_BITMAP class. This class has a method CREATE_FROM_EXT_FORMAT which this function is derived from.

 

18.jpg

19.jpg

 

The method uses standard components so you may directly create this simple FM instead of Implementing whole ZCL_ABAP_BITMAP and call this FM instead of using ZCL_ABAP_BITMAP class methods.

 

 

Source Code is as follows;

 

FUNCTION ZBMP_CREATE_FROM_EXT_FORMAT.

*"----------------------------------------------------------------------

*"*"Local Interface:

*"  IMPORTING

*"     REFERENCE(XSTREAM) TYPE  XSTRING

*"     REFERENCE(FORMAT) TYPE  STRING DEFAULT 'JPG'

*"  EXPORTING

*"     REFERENCE(BITMAP) TYPE  W3MIMETABTYPE

*"----------------------------------------------------------------------

 

  DATA: l_igs_imgconv TYPE REF TO cl_igs_image_converter,

         l_img_blob    TYPE w3mimetabtype,

         l_img_size    TYPE w3param-cont_len,

         l_bmp_xstream TYPE xstring.

 

   CREATE OBJECT l_igs_imgconv.

 

   l_img_size = XSTRLEN( xstream ).

 

   CALL FUNCTION 'SCMS_XSTRING_TO_BINARY'

     EXPORTING

       buffer     = xstream

     TABLES

       binary_tab = l_img_blob.

 

   CALL METHOD l_igs_imgconv->set_image

     EXPORTING

       blob      = l_img_blob

       blob_size = l_img_size.

 

   DATA l_format TYPE string.

 

   l_format = format.

 

   CASE l_format.

     WHEN 'TIF'.

       l_igs_imgconv->input  = 'image/tiff'.

     WHEN 'JPG'.

       l_igs_imgconv->input  = 'image/jpeg'.

     WHEN 'PNG'.

       l_igs_imgconv->input  = 'image/png'.

     WHEN 'GIF'.

       l_igs_imgconv->input  = 'image/gif'.

     WHEN OTHERS.

       EXIT.

   ENDCASE.

 

   l_igs_imgconv->output = 'image/x-ms-bmp'.

 

   CALL METHOD l_igs_imgconv->execute

     EXCEPTIONS

       OTHERS = 1.

 

   IF sy-subrc IS INITIAL.

 

     CALL METHOD l_igs_imgconv->get_image

       IMPORTING

         blob      = l_img_blob

         blob_size = l_img_size.

 

     CALL FUNCTION 'SCMS_BINARY_TO_XSTRING'

       EXPORTING

         input_length = l_img_size

       IMPORTING

         buffer       = l_bmp_xstream

       TABLES

         binary_tab   = l_img_blob

       EXCEPTIONS

         failed       = 1

         OTHERS       = 2.

 

     bitmap = l_img_blob.

 

   ENDIF.

 

ENDFUNCTION.


then we write this converted bitmap file to the same directory like this

 

20.jpg

 

at this point we have the bmp formatted employee photo and can upload this to Document Server. there is the subroutine "import_bitmap_bds " in standard report "saplstxbitmaps" which asks for the user for the file to be uploaded. I converted the subroutine to work with file in usr/sap/trans directory.

 

Here is the modified subroutine;

 

 

FORM import_bitmap_bds_local.

MOVE list_filename TO imagefile.
MOVE pernr-pernr   TO imagename.
MOVE pernr-pernr   TO imagedesc.

DATA: l_resolution  TYPE stxbitmaps-resolution.
DATA: l_docid     TYPE stxbitmaps-docid.

DATA: l_object_key TYPE sbdst_object_key.
DATA: l_tab        TYPE ddobjname.
DATA: BEGIN OF l_bitmap OCCURS 0,
l
(64) TYPE x,
END OF l_bitmap.
DATA: l_filename        TYPE string,
l_bytecount      
TYPE i,
l_bds_bytecount  
TYPE i.
DATA: l_color(1)        TYPE c,
l_width_tw       
TYPE stxbitmaps-widthtw,
l_height_tw      
TYPE stxbitmaps-heighttw,
l_width_pix      
TYPE stxbitmaps-widthpix,
l_height_pix     
TYPE stxbitmaps-heightpix.
DATA: l_bds_object      TYPE REF TO cl_bds_document_set,
l_bds_content    
TYPE sbdst_content,
l_bds_components 
TYPE sbdst_components,
wa_bds_components
TYPE LINE OF sbdst_components,
l_bds_signature  
TYPE sbdst_signature,
wa_bds_signature 
TYPE LINE OF sbdst_signature,
l_bds_properties 
TYPE sbdst_properties,
wa_bds_properties
TYPE LINE OF sbdst_properties.
DATA  wa_stxbitmaps TYPE stxbitmaps.


* Enqueue
PERFORM enqueue_graphic USING 'GRAPHICS'
imagename
'BMAP'
'BCOL'.

*** Read BMP File
CLEAR list_filename.
MOVE imagefile TO list_filename.
OPEN DATASET list_filename IN BINARY MODE FOR INPUT.
IF sy-subrc EQ 0.
CLEAR xstr1.
*** Read BMP File
READ DATASET list_filename INTO xstr1.

**** Delete BMP File
DELETE DATASET list_filename.

CLEAR l_bitmap.
CALL FUNCTION 'SCMS_XSTRING_TO_BINARY'
EXPORTING
buffer        = xstr1
IMPORTING
output_length
= l_bytecount
TABLES
binary_tab   
= l_bitmap.

CASE sy-subrc.
WHEN 0.
WHEN 2.
PERFORM dequeue_graphic USING 'GRAPHICS'
imagename
'BMAP'
'BCOL'.
MESSAGE e811(td) WITH imagefile.

WHEN 3.
PERFORM dequeue_graphic USING 'GRAPHICS'
imagename
'BMAP'
'BCOL'.
MESSAGE e812(td) WITH imagefile.

WHEN OTHERS.
PERFORM dequeue_graphic USING 'GRAPHICS'
imagename
'BMAP'
'BCOL'.

MESSAGE e813(td) WITH imagefile.

ENDCASE.

l_color
= c_true.

* Bitmap conversion
CALL FUNCTION 'SAPSCRIPT_CONVERT_BITMAP_BDS'
EXPORTING
color                    = l_color
format                   = 'BMP'
resident                
= space
bitmap_bytecount        
= l_bytecount
compress_bitmap         
= space
IMPORTING
width_tw                
= l_width_tw
height_tw               
= l_height_tw
width_pix               
= l_width_pix
height_pix              
= l_height_pix
dpi                     
= l_resolution
bds_bytecount           
= l_bds_bytecount
TABLES
bitmap_file             
= l_bitmap
bitmap_file_bds         
= l_bds_content
EXCEPTIONS
format_not_supported    
= 1
no_bmp_file             
= 2
bmperr_invalid_format   
= 3
bmperr_no_colortable    
= 4
bmperr_unsup_compression
= 5
bmperr_corrupt_rle_data 
= 6
OTHERS                   = 7.
IF sy-subrc <> 0.
PERFORM dequeue_graphic USING 'GRAPHICS'
imagename
'BMAP'
'BCOL'.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4
RAISING conversion_failed.
ENDIF.

* Save bitmap in BDS
CREATE OBJECT l_bds_object.

wa_bds_components
-doc_count  = '1'.
wa_bds_components
-comp_count = '1'.
wa_bds_components
-mimetype   = c_bds_mimetype.
wa_bds_components
-comp_size  = l_bds_bytecount.
APPEND wa_bds_components TO l_bds_components.

IF l_docid IS INITIAL.          " graphic is new

wa_bds_signature
-doc_count = '1'.
APPEND wa_bds_signature TO l_bds_signature.

CALL METHOD l_bds_object->create_with_table
EXPORTING
classname 
= c_bds_classname
classtype 
= c_bds_classtype
components
= l_bds_components
content   
= l_bds_content
CHANGING
signature 
= l_bds_signature
object_key
= l_object_key
EXCEPTIONS
OTHERS     = 1.
IF sy-subrc <> 0.
PERFORM dequeue_graphic USING 'GRAPHICS'
imagename
'BMAP'
'BCOL'.

MESSAGE e285(td) WITH imagename  'BDS'.

ENDIF.
READ TABLE l_bds_signature INDEX 1 INTO wa_bds_signature
TRANSPORTING doc_id.
IF sy-subrc = 0.
l_docid
= wa_bds_signature-doc_id.
ELSE.
PERFORM dequeue_graphic USING 'GRAPHICS'
imagename
'BMAP'
'BCOL'.

MESSAGE e285(td) WITH imagename 'BDS'.

ENDIF.

ELSE.                " graphic already exists
********* read object_key for faster access *****
CLEAR l_object_key.
SELECT SINGLE * FROM stxbitmaps INTO wa_stxbitmaps
WHERE tdobject = 'GRAPHICS'
ANDtdid     = 'BMAP'
ANDtdname   = imagename
ANDtdbtype  = 'BCOL'.
SELECT SINGLE tabname FROM bds_locl INTO l_tab
WHERE classname = c_bds_classname
ANDclasstype = c_bds_classtype.
IF sy-subrc = 0.
SELECT SINGLE object_key FROM (l_tab) INTO l_object_key
WHERE loio_id = wa_stxbitmaps-docid+10(32)
ANDclassname = c_bds_classname
ANDclasstype = c_bds_classtype.
ENDIF.
******** read object_key end ********************

CALL METHOD l_bds_object->update_with_table
EXPORTING
classname    
= c_bds_classname
classtype    
= c_bds_classtype
object_key   
= l_object_key
doc_id       
= l_docid
doc_ver_no   
= '1'
doc_var_id   
= '1'
CHANGING
components   
= l_bds_components
content      
= l_bds_content
EXCEPTIONS
nothing_found
= 1
OTHERS        = 2.
IF sy-subrc = 1.   " inconsistency STXBITMAPS - BDS; repeat check in
wa_bds_signature
-doc_count = '1'.
APPEND wa_bds_signature TO l_bds_signature.

CALL METHOD l_bds_object->create_with_table
EXPORTING
classname 
= c_bds_classname
classtype 
= c_bds_classtype
components
= l_bds_components
content   
= l_bds_content
CHANGING
signature 
= l_bds_signature
object_key
= l_object_key
EXCEPTIONS
OTHERS     = 1.
IF sy-subrc <> 0.
PERFORM dequeue_graphic USING 'GRAPHICS'
imagename
'BMAP'
'BCOL'.

MESSAGE e285(td) WITH imagename 'BDS'.
ENDIF.
READ TABLE l_bds_signature INDEX 1 INTO wa_bds_signature
TRANSPORTING doc_id.
IF sy-subrc = 0.
l_docid
= wa_bds_signature-doc_id.
ELSE.
PERFORM dequeue_graphic USING 'GRAPHICS'
imagename
'BMAP'
'BCOL'.
MESSAGE e285(td) WITH imagename 'BDS'.
ENDIF.

ELSEIF sy-subrc = 2.
PERFORM dequeue_graphic USING 'GRAPHICS'
imagename
'BMAP'
'BCOL'.
MESSAGE e285(td) WITH imagename 'BDS'.
ENDIF.

ENDIF.

* Save bitmap header in STXBITPMAPS
wa_stxbitmaps
-tdname     = imagename.
wa_stxbitmaps
-tdobject   = 'GRAPHICS'.
wa_stxbitmaps
-tdid       = 'BMAP'.
wa_stxbitmaps
-tdbtype    = 'BCOL'.
wa_stxbitmaps
-docid      = l_docid.
wa_stxbitmaps
-widthpix   = l_width_pix.
wa_stxbitmaps
-heightpix  = l_height_pix.
wa_stxbitmaps
-widthtw    = l_width_tw.
wa_stxbitmaps
-heighttw   = l_height_tw.
wa_stxbitmaps
-resolution = l_resolution.
wa_stxbitmaps
-resident   = space.
wa_stxbitmaps
-autoheight = 'X'.
wa_stxbitmaps
-bmcomp     = space.
INSERT INTO stxbitmaps VALUES wa_stxbitmaps.
IF sy-subrc <> 0.
UPDATE stxbitmaps FROM wa_stxbitmaps.
IF sy-subrc <> 0.
MESSAGE e285(td) WITH imagename 'STXBITMAPS'.
ENDIF.
ENDIF.

* Set description in BDS attributes
wa_bds_properties
-prop_name  = 'DESCRIPTION'.
wa_bds_properties
-prop_value = imagedesc.
APPEND wa_bds_properties TO l_bds_properties.

CALL METHOD l_bds_object->change_properties
EXPORTING
classname 
= c_bds_classname
classtype 
= c_bds_classtype
object_key
= l_object_key
doc_id    
= l_docid
doc_ver_no
= '1'
doc_var_id
= '1'
CHANGING
properties
= l_bds_properties
EXCEPTIONS
OTHERS     = 1.

PERFORM dequeue_graphic USING 'GRAPHICS'
imagename
'BMAP'
'BCOL'.

ENDIF.

ENDFORM.                    "import_bitmap_bds_local

 

With the use of this modified subroutine, we can batch upload converted BMP files to Document Server. We can run this report as scheduled job so that it gets the employee photo, converts it to BMP format and uploads it to Document Server.

 

You can find the source code of the sample report as attachment (bitmap automization.txt) to this document.

 

 

Hope this document helps.

 

Murat Kaya - 2014


Viewing all articles
Browse latest Browse all 935

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>