Вы находитесь на странице: 1из 15

https://blogs.sap.

com/2014/06/22/employee-photo-bitmap-automation-for-dynamic-employee-photos-insmartforms/

Employee Photo Bitmap Automation (for Dynamic


Employee Photos in Smartforms)
June 22, 2014 | 254 Views |

Murat Kaya
more by this author
ABAP Development
bitmapconversiondynamicemployeephotopicturesmartforms;

share 0

share 0

tweet

share 0

Follow

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).

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

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

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

We can see and print the image succesfully.

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


SAP has a class CL_IGS_IMAGE_CONVERTOR for these purposes.

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

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.

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

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.

fetch_and_convert_emp_photo subroutine starts with employee photo check.

then we get the binary data for the file

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

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.

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.

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 w3paramcont_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 sysubrc 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

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 pernrpernr
TO imagename.
MOVE pernrpernr
TO imagedesc.
DATA: l_resolution TYPE stxbitmapsresolution.
DATA: l_docid
TYPE stxbitmapsdocid.
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 stxbitmapswidthtw,

l_height_tw
TYPE stxbitmapsheighttw,
l_width_pix
TYPE stxbitmapswidthpix,
l_height_pix
TYPE stxbitmapsheightpix.
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 sysubrc 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 sysubrc.
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 sysubrc <> 0.
PERFORM dequeue_graphic USING GRAPHICS
imagename
BMAP
BCOL.
MESSAGE ID symsgid TYPE symsgty NUMBER symsgno
WITH symsgv1 symsgv2 symsgv3 symsgv4

RAISING conversion_failed.
ENDIF.
* Save bitmap in BDS
CREATE OBJECT l_bds_object.
wa_bds_componentsdoc_count = 1.
wa_bds_componentscomp_count = 1.
wa_bds_componentsmimetype
= c_bds_mimetype.
wa_bds_componentscomp_size = l_bds_bytecount.
APPEND wa_bds_components TO l_bds_components.
IF l_docid IS INITIAL.

graphic is new

wa_bds_signaturedoc_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 sysubrc <> 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 sysubrc = 0.
l_docid = wa_bds_signaturedoc_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
AND tdid
= BMAP
AND tdname
= imagename
AND tdbtype = BCOL.
SELECT SINGLE tabname FROM bds_locl INTO l_tab
WHERE classname = c_bds_classname
AND classtype = c_bds_classtype.
IF sysubrc = 0.
SELECT SINGLE object_key FROM (l_tab) INTO l_object_key
WHERE loio_id = wa_stxbitmapsdocid+10(32)
AND classname = c_bds_classname
AND classtype = 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 sysubrc = 1. inconsistency STXBITMAPS BDS; repeat check in
wa_bds_signaturedoc_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 sysubrc <> 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 sysubrc = 0.
l_docid = wa_bds_signaturedoc_id.
ELSE.
PERFORM dequeue_graphic USING GRAPHICS
imagename
BMAP
BCOL.
MESSAGE e285(td) WITH imagename BDS.
ENDIF.
ELSEIF sysubrc = 2.
PERFORM dequeue_graphic USING GRAPHICS
imagename
BMAP
BCOL.
MESSAGE e285(td) WITH imagename BDS.
ENDIF.
ENDIF.
* Save bitmap header in STXBITPMAPS
wa_stxbitmapstdname
= imagename.
wa_stxbitmapstdobject
= GRAPHICS.
wa_stxbitmapstdid
= BMAP.
wa_stxbitmapstdbtype
= BCOL.
wa_stxbitmapsdocid
= l_docid.
wa_stxbitmapswidthpix
= l_width_pix.
wa_stxbitmapsheightpix = l_height_pix.
wa_stxbitmapswidthtw
= l_width_tw.
wa_stxbitmapsheighttw
= l_height_tw.
wa_stxbitmapsresolution = l_resolution.
wa_stxbitmapsresident
= space.
wa_stxbitmapsautoheight = X.
wa_stxbitmapsbmcomp
= space.
INSERT INTO stxbitmaps VALUES wa_stxbitmaps.
IF sysubrc <> 0.
UPDATE stxbitmaps FROM wa_stxbitmaps.
IF sysubrc <> 0.
MESSAGE e285(td) WITH imagename STXBITMAPS.
ENDIF.
ENDIF.
* Set description in BDS attributes

wa_bds_propertiesprop_name = DESCRIPTION.
wa_bds_propertiesprop_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

Alert Moderator

7 Comments
You must be Logged on to comment or reply to a post.

1.

Anil SuprajJune 23, 2014 at 7:38 am


Hi Murat,
Nice document

Thanks,
Anil

like (0)
2.

Ravi ShankarJune 23, 2014 at 9:41 am

New Things Learned .. Thanks

like (0)

3.

Irfan MATAKOctober 15, 2014 at 8:24 am

Dear Murat ,
Thanks for sharing, this is useful information.
Best Regards,
rfan.

like (0)
4.

Vinson ZengJuly 24, 2015 at 3:48 am

Thank for sharing


It Just help me

like (0)
5.

Tyu LssssOctober 30, 2015 at 7:53 am

thanks for sharing.


i have a question about it.
after we convert the jpg photos to bmp, do we still need to upload photos via se78 ? or it would
automatically proccess this step

like (0)

1.

Francesco AmigoniDecember 11, 2015 at 10:53 am


If it is yet unanswered: It is done automatically by the methods in the l_bds_object instance of the
class (in the function Z*). No need to manually upload in SE78

like (0)

6.

Francesco AmigoniDecember 11, 2015 at 10:50 am


It was THE thing I was looking for.

Very well explained, it fitted perfectly with my knowledge of the whole topic adding the solution.

like (0)