Skip to Content

Background

In recent times, almost all tablets/mobile devices have got a camera with great resolution. As a result, the size of captured images is usually heavy (in mb).

Now as a agentry consultant you always think of optimising the transmit time. An image that needs to be uploaded with size of around 2-3 mb takes considerable amount of transmit time (may be more if network is not up to the mark).

Moreover, if any customer is using HANA DB, a single image itself can consume significant space. To overcome this scenario resizing can be beneficial.

To overcome these issues, resizing the image captured from mobile in the java layer was a good option, as there is no such option available in the Embedded Image property type or Image Capture field edit type in Agentry Editor.

I shall be describing the steps to resize the image in correspondence to Picture Upload in Workorder  (SAP Work Manager) in WPF client.

 

Steps (Agentry Editor)

  1. Find out the transaction responsible for capturing the image. For Workorder it is “DocumentLinkPictureAddForWorkOrder”.
  2. In the transaction, a property “ZResizeValue” is added. This property acts as a resizing factor. This was provided to give the end users an option to select how much resizing they want. In case if the user thinks that the image is important they can upload the image as it is.
  3. In the next step, we need to identify the Screen that is used to capture the image. Here it is “DocumentLinkAddAsPicture_iPad_Detail” Screen in “DocumentLinkAddAsPicture” Screen set. In the screen, there are three radio buttons added for selection of resizing factor.

The values for the buttons are set as “L”, “M”, “S” respectively for LARGE, MEDIUM, SMALL. The ZResizeValue property is assigned to these three buttons.

As a result, once the transaction is applied whichever button is selected, the corresponding resizing factor is saved in ZResizeValue property.

Steps (Java/Config Panel)

  1. A new custom BAPI class is created to upload the image. Here the targeted system is BDS. The resizing process will be same for DMS (only the import parameters will be different).Required mapping should be maintained in Config panel to instantiate the custom BAPI Class.

 

  1. In the standard code, the fileData(HexString) is converted into a Byte Array. This Byte Array is in turn passed to the import structure  “IS_FILE_CONTENT_BIN”. To resize the image, this Byte Array of the actual image is used to create a Buffer Image and the resizing factor (ZResizeValue property of the transaction) is used to scale down the size of the image. The relevant java code is as follows:
    public void setParameters(SAPObject obj)
    		    throws Exception{
    /* Other required code*/
    String imageString = "";
    	String fileresize = this._user.getString("transaction.ZResizeValue");  //achieving the file resize parameter from client (L= Large, M= Medium, S= Small)ResizeValue
    if (this._documentLink.isPicture()) {
    		      imageString = this._documentLink.getPicture();
    		    }
    /* Other required code*/
    byte[] bytes = ConversionUtility.hexStringToByteArray(imageString);
    //byte array created from the file data
    
    if(!(fileresize.equalsIgnoreCase(""))&& this._documentLink.isPicture() ){
    		    	
    		    	bytes = getResizedImage(bytes, this._documentLink.getFileType(), fileresize);
    		    }
    //getResizedImage() method is called only if the file is image and the resizing factor is present.
    
    /* Other required code*/
    setValue(this._imports, log, "IS_FILE_CONTENT_BIN", bytes);
    
    //the resized byte array is passed to the BAPI Wrapper.
    }
    
    public byte[] getResizedImage(byte [] bytes, String filetype, String filesize) throws FileNotFoundException, IOException{
    
    //the method to resize the image and provide a byte array out of it.
    
    		InputStream inputStream = new ByteArrayInputStream(bytes);
    		float imageQuality = 0.0f;
    		if(filesize.equalsIgnoreCase("L")){
    			imageQuality = 1.0f;
    		} 
    		if (filesize.equalsIgnoreCase("M")){
    			imageQuality = 0.7f;
    		}
    		if (filesize.equalsIgnoreCase("S")){
    			imageQuality = 0.5f;
    		}
    //the image quality is defined by the resizing factor. L=100%, M=70%, S=50%
    
    		BufferedImage bufferedImage = ImageIO.read(inputStream);
    		int scaledwidth = bufferedImage.getWidth();
            int scaledheight = bufferedImage.getHeight();
    // a buffered image for actual image is created to get the actual height and width 
    
            byte [] imageInByte;
            
            BufferedImage resizedImage = new BufferedImage((int) ((int)scaledwidth*imageQuality),(int) ((int)scaledheight*imageQuality) , bufferedImage.getType());
    //a resized buffer image is created
    
    		Graphics2D g2d = resizedImage.createGraphics();
            g2d.drawImage(bufferedImage, 0, 0,(int) ((int)scaledwidth*imageQuality),(int) ((int)scaledheight*imageQuality), null);
            g2d.dispose();
    
    //the actual image is scaled to the resized image 
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
    		ImageIO.write(resizedImage, filetype, baos);
    		baos.flush();
    		imageInByte = baos.toByteArray();
    		baos.close();
    //the resized image is converted to Byte Array
    		
    		
    		return imageInByte;
    		
    		
    	}
    ​
  • NOTE: If the resizing factor is fixed and not a user selection, step 2 and 3 can be avoided. Java coding changes should be done accordingly.

After this solution was implemented, the image size was significantly resized .2 mb images were resized to aprrox 400-500 Kbs (with 50% resizing). In turn it also helped to reduce the transmit time while image upload.

To report this post you need to login first.

1 Comment

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

Leave a Reply