cancel
Showing results for 
Search instead for 
Did you mean: 

Get Image Variants using Java API

Former Member
0 Kudos

Hi All,

Can someone post some sample code to get the binary data for an image variant? I have no problem getting the binary data for Original variant using the RetrieveBlobCommand class. Once I have that how do I get the binary data for the image variants related to that Original variant?

I'm using new Java API for SP06 Patch 2.

Thanks,

Mark

Accepted Solutions (1)

Accepted Solutions (1)

Former Member
0 Kudos

Hi Mark,

Use the RetrieveBlobCommand, and use the method setImageVariantId() to the variant you are interested in. You can use the constant ImageVariantId.THUMNBNAIL to get the thumbnail, or else another ID for custom-defined variants.

Regards,

Walter

Former Member
0 Kudos

Hi Walter,

Thanks for giving me the tip to solve the puzzle. I'll post a code example later today for other to follow.

Best Regards,

Mark

Former Member
0 Kudos

Here is code example with incorporation of the tip provided by Walter. Enjoy.

import java.util.*;
import java.io.*;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

import com.sap.mdm.blobs.*;
import com.sap.mdm.blobs.commands.*;
import com.sap.mdm.commands.*;
import com.sap.mdm.data.*;
import com.sap.mdm.data.commands.*;
import com.sap.mdm.net.*;
import com.sap.mdm.ids.*;
import com.sap.mdm.schema.*;
import com.sap.mdm.schema.commands.*;
import com.sap.mdm.session.*;
import com.sap.mdm.valuetypes.*;

public class ImageProgram
{
  public static void main(String[ ] args)
  {
    UserSessionContext usc = new UserSessionContext( "mdm_server", "repository", "Admin" );
    String session = SessionManager.getInstance( ).createSession( usc, SessionTypes.USER_SESSION_TYPE, "" );

    GetRepositorySchemaCommand grsc = null;
    ResultDefinition rd = null;
    try
    {
      grsc = new GetRepositorySchemaCommand( usc );
      grsc.setSession( session );
      grsc.execute( );

      FieldProperties[] flds = grsc.getRepositorySchema( ).getTableSchema( "Images" ).getFields( );
      for ( FieldProperties fId : flds )
      {
        String regStrName = fId.getName( ).get( "engUSA" );  /* sap: shouldn't this be an iso standard, what's up with the home grown codes? */
        System.out.println( "Id = " + fId.getId( ).id + "\t\t\tName = " + regStrName + "\t\t\tCode = " + fId.getCode( ) );
      }

      rd = new ResultDefinition( grsc.getRepositorySchema( ).getTableId( "Images" ) );
      rd.setSelectFields( new FieldId[] { new FieldId(-100), new FieldId(-201), new FieldId(-203), new FieldId(-205) } );

    }
    catch( Exception ex )
    {
      ex.printStackTrace( );
    }

    try
    {
      ImageVariantProperties[] ivps = grsc.getRepositorySchema( ).getImageVariants( );

      RetrieveRecordsByValueCommand rrbvc = new RetrieveRecordsByValueCommand( usc );
      rrbvc.setSession( session );
      rrbvc.setResultDefinition( rd );
      FieldId fId = grsc.getRepositorySchema( ).getFieldId( "Images", "Name" );
      rrbvc.setFieldId( fId );
      rrbvc.setFieldValues( new StringValue[] { new StringValue( "Your Image Name" ) } );
      rrbvc.execute( );
      RecordResultSet rrs = rrbvc.getRecords( );

      Record[] recs = rrs.getRecords( );

      for ( Record rec: recs )
      {
        BinaryBlobRecord brec = (BinaryBlobRecord)rec;

        for ( ImageVariantProperties ivp : ivps )
        {
          RetrieveBlobCommand rbc = new RetrieveBlobCommand( usc );
          rbc.setTableId( grsc.getRepositorySchema( ).getTableId( "Images" ) );
          rbc.setRecordId( rec.getId( ) );
          rbc.setImageVariantId( ivp.getId( ) );
          try
          {
            rbc.execute( );
            MultiregionValue mrv = (MultiregionValue)rbc.getBlob( );
            if ( ! mrv.isNull( ) )
            {
              BinaryValue imgVar = (BinaryValue) mrv.getValue( "engUSA" );
              byte[] binData = imgVar.getBytes( );

              // Create a ByteBuffer using the byte array
              ByteBuffer bbuf = ByteBuffer.wrap( binData );

              // Create a file name based on some path and the original name of the file.
              String originalFileName = brec.getOriginalName( ).toString( );
              if( ivp.getId( ).id != ImageVariantId.ORIGINAL.id )
              {
                // Add the variant name to the original name and determine the
                // file extension based on byte signature of the binary data value.
                originalFileName = originalFileName.substring( 0, originalFileName.lastIndexOf( "." ) ) +
                                      "_" + ivp.getName( ).get( "engUSA" ).toString( ) + "." +
                                      ImageProgram.getFileExtension( binData );
              }

              File file = new File( "C:\\Temp\\" + originalFileName );

              // Set to true if the bytes should be appended to the file;
              // set to false if the bytes should replace current bytes
              // (if the file exists)
              boolean append = false;

              try
              {
                  // Create a writable file channel
                  FileChannel wChannel = new FileOutputStream(file, append).getChannel();

                  // Write the ByteBuffer contents; the bytes between the ByteBuffer's
                  // position and the limit is written to the file
                  wChannel.write(bbuf);

                  // Close the file
                  wChannel.close();
              }
              catch ( IOException ex )
              {
                ex.printStackTrace( );
              }

            }
          }
          catch ( CommandException ex )
          {
            if ( ! ex.getCause( ).getMessage( ).equalsIgnoreCase( "no query results returned" ) )
              ex.printStackTrace( );
          }
          catch ( Exception ex )
          {
            ex.printStackTrace( );
          }
        }
      }

    }
    catch( ConnectionException ex )
    {
      ex.printStackTrace( );
    }
    catch ( CommandException ex )
    {
      System.out.println( ex.getMessage( ) + "\n\n" );
      ex.printStackTrace( );
    }
    catch ( Exception ex )
    {
      ex.printStackTrace( );
    }

    SessionManager.getInstance( ).destroySession( usc, SessionTypes.USER_SESSION_TYPE );
  }

  public static String getFileExtension( byte[] fileData )
  {
    byte gifSignature[] = { 0x47, 0x49, 0x46 }; //GIF
    byte fileSignature1[] = { fileData[0], fileData[1], fileData[2] };
    if ( Arrays.equals( gifSignature, fileSignature1 ))
    {
      return"gif";
    }

    byte jpgSignature[] = { ((byte)0xFF), ((byte)0xD8), ((byte)0xFF), ((byte)0xE1) }; //Exif JPG
    byte fileSignature2[] = { fileData[0], fileData[1], fileData[2], fileData[3] };
    if ( Arrays.equals( jpgSignature, fileSignature2 ))
    {
      return "jpg";
    }

    byte jpgSignature1[] = { ((byte)0xFF), ((byte)0xD8), ((byte)0xFF), ((byte)0xE0) }; //JFIF JPG
    if ( Arrays.equals( jpgSignature1, fileSignature2 ))
    {
      return "jpg";
    }

    byte pngSignature[] = { 0x50, 0x4E, 0x47 }; //PNG
    byte fileSignature3[] = { fileData[1], fileData[2], fileData[3] };
    if ( Arrays.equals( pngSignature, fileSignature3 ))
    {
      return "png";
    }

    byte bmpSignature[] = { 0x42, 0x4D }; //BMP
    byte fileSignature4[] = { fileData[0], fileData[1] };
    if ( Arrays.equals( bmpSignature, fileSignature4 ))
    {
      return "bmp";
    }

    byte tifSignature[] = { 0x49, 0x49, 0x2A }; //TIF
    byte fileSignature5[] = { fileData[0], fileData[1], fileData[2] };
    if ( Arrays.equals( tifSignature, fileSignature5 ))
    {
      return "tif";
    }

    return "jpg";
  }
}

Answers (2)

Answers (2)

Former Member
0 Kudos

Hi Mark,

"A variant defines the structure of the image but does not specify if the variant is actually required for a particular image.

Instead, each image lookup field in the repository has a Variants property that allows you to associate one or more variants with the image lookup field, and in so doing, identify which variants should be generated when an image is associated with that particular field.

For each variant, all the images associated with that variant will be generated according to the specifications of the variant and the crop/rotate settings stored for that image. MDM tracks the changes to the variant definitions, the variant associations, each image, and the crop/rotate settings for each image, and thus know when the variants need to be regenerated."

Refer to the link below.

http://java.sun.com/developer/technicalArticles/Media/AdvancedImage/

Regards,

Neethu

Former Member
0 Kudos

Sample code please...quotes from other sources and references to javadocs are useless to me unless they themselves have sample code that shows me how to get the binary data for the image variant out of the SAP MDM repository.

Please my fellow MDMers, hold your replies unless you have sample code that can build upon what I have provided above or other alternate source code.

Thanks,

Mark

Former Member
0 Kudos

Hi,

To retrieve image variants u can go through following link

https://help.sap.com/javadocs/MDM/current/com/sap/mdm/blobs/commands/RetrieveImageVariantsCommand.ht...

Reward points if helpful.

Regards

Nisha

Former Member
0 Kudos

I have found that RetrieveImageVariantsCommand is equivalent to doing this

GetRepositorySchemaCommand.getRepositorySchema.getImageVariants( )

That is, your suggestion is just an alternate for the schema command above unless I'm missing something. Hence, the request for sample code.

The question is still open with emphasis on sample code.

Thanks,

Mark

Former Member
0 Kudos

I thought I might post some sample code that would help clarify my question.

By the way, PDFs can be obtained in a similar manner.

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

import com.sap.mdm.blobs.*;
import com.sap.mdm.commands.*;
import com.sap.mdm.data.*;
import com.sap.mdm.data.commands.*;
import com.sap.mdm.net.*;
import com.sap.mdm.ids.*;
import com.sap.mdm.schema.*;
import com.sap.mdm.schema.commands.*;
import com.sap.mdm.session.*;
import com.sap.mdm.valuetypes.*;

public class ImageProgram
{
	public static void main(String[ ] args)
	{
		UserSessionContext usc = new UserSessionContext( "your_server", "your_repository", "Admin" );
		String session = SessionManager.getInstance( ).createSession( usc, SessionTypes.USER_SESSION_TYPE, "" );

		GetRepositorySchemaCommand grsc = null;
		ResultDefinition rd = null;
		try
		{
			grsc = new GetRepositorySchemaCommand( usc );
			grsc.setSession( session );
			grsc.execute( );

			FieldProperties[] flds = grsc.getRepositorySchema( ).getTableSchema( "Images" ).getFields( );
			for ( FieldProperties fId : flds )
			{
				String regStrName = fId.getName( ).get( "engUSA" ); /* sap: shouldn't this be an iso standard, what's up with the home grown codes? */
				System.out.println( "Id = " + fId.getId( ).id + "\t\t\tName = " + regStrName + "\t\t\tCode = " + fId.getCode( ) );				
			}

			rd = new ResultDefinition( grsc.getRepositorySchema( ).getTableId( "Images" ) );
			rd.setSelectFields( new FieldId[] { new FieldId(-100), new FieldId(-201), new FieldId(-203), new FieldId(-205) } );

		}
		catch( Exception ex )
		{
			ex.printStackTrace( );
		}

		try
		{
			RetrieveRecordsByValueCommand rrbvc = new RetrieveRecordsByValueCommand( usc );
			rrbvc.setSession( session );
			rrbvc.setResultDefinition( rd );
			rrbvc.setFieldId( grsc.getRepositorySchema( ).getFieldId( "Images", "Name" ); );
			rrbvc.setFieldValues( new StringValue[] { new StringValue( "Model 100" ) } );
			rrbvc.execute( );
			RecordResultSet rrs = rrbvc.getRecords( );

			Record[] recs = rrs.getRecords( );

			for ( Record rec: recs )
			{
				BinaryBlobRecord brec = (BinaryBlobRecord)rec;
				BinaryValue imageMdmValue = (BinaryValue)brec.getBinary( );
				byte[] binData = imageMdmValue.getBytes( );

				// Create a ByteBuffer using the byte array
				ByteBuffer bbuf = ByteBuffer.wrap( binData );

				// Create a file name based on some path and the original name of the file.
				File file = new File( "C:\\Temp\\" + brec.getOriginalName( ) );

				// Set to true if the bytes should be appended to the file;
				// set to false if the bytes should replace current bytes
				// (if the file exists)
				boolean append = false;

				try 
				{
					// Create a writable file channel
					FileChannel wChannel = new FileOutputStream(file, append).getChannel();

					// Write the ByteBuffer contents; the bytes between the ByteBuffer's
					// position and the limit is written to the file
					wChannel.write(bbuf);

					// Close the file
					wChannel.close();
				} 
				catch ( IOException ex ) 
				{
					ex.printStackTrace( );
				}

				/* How can I now get the binary data for all the variants related to this record? */
			}

		}
		catch( ConnectionException ex )
		{
			ex.printStackTrace( );
		}
		catch ( CommandException ex )
		{
			System.out.println( ex.getMessage( ) + "\n\n" );
			ex.printStackTrace( ); 
		}
		catch ( Exception ex )
		{
			ex.printStackTrace( );
		}

		SessionManager.getInstance( ).destroySession( usc, SessionTypes.USER_SESSION_TYPE );
	}
}