APEX Media Extension - User Manual

Release 20.1 February 2020

Provided by:

APEX R&D Logo

About AME

APEX Media Extension (AME) makes it easy to process or convert media before or after it is stored in the Oracle Database. Using our Oracle Application Express (APEX) plug-in, PL/SQL API, and REST API you can:

In a future version of AME, video and audio will be added to the feature list.

AME APEX Sample Application

Import via Application Builder

  1. Access your target Workspace
  2. Select the Application Builder
  3. Select Import and select the file in apex/ame_sample_apex_app.sql
  4. Follow the wizard to finish the import

Note: The AME Sample Application will also install all supporting objects, so after the import you can simply start using the application.
If the import times out or is very slow, try importing via command line as described in the following section.

Import via Command Line

To import the AME Sample Application via command line locate ame_sample_apex_app.sql in apex/ and if needed, move it to a location that can be accessed by your database. Connect to the schema in which you would like to install the application and run the following:

begin
    apex_application_install.set_workspace('AMEDEMO'); -- replace AMEDEMO with your workspace
    apex_application_install.generate_offset;
    apex_application_install.set_schema('AMEDEMO');  -- replace AMEDEMO with your schema 
    apex_application_install.set_application_alias('AME_' || apex_application_install.get_application_id);
    apex_application_install.set_auto_install_sup_obj(p_auto_install_sup_obj => true );
end;
/

@ame_sample_apex_app.sql

Note: The AME Sample Application will also install all supporting objects, so after the import you can simply start using the application.

Trying the AOP Sample Application

The APEX application that comes with AME shows different examples of how APEX Media Extension can be used inside an application.

By inspecting elements of these pages, you can quickly learn how to use AME Plug-in and PL/SQL API.

APEX Plug-in

About

The APEX Media Extension APEX plug-in requires Oracle APEX 18.1 or higher.

The AME plug-ins are relying on a PL/SQL package (ame_api_pkg which is a synonym for ame_api20_pkg) that needs to be compiled first.

To make the package available, go into SQL Plus, SQLcl, SQL Developer or SQL Workshop and run the SQL Script ame_db_pkg.sql which you find in the db directory of the zip you downloaded.

Alternatively, you can run the install.sql file which will install some additional packages which show case how to use AOP from PL/SQL.

If you imported the AME Sample App and ran the Supporting Objects, the packages are automatically installed.

Import and plug-in Attributes

Follow these steps to import the plug-in in your application:

  1. Access your target Workspace
  2. Select the Application Builder
  3. Select the Application where you wish to import the plug-in > (plug-ins belong to an application, not a workspace)
  4. Access Shared Components > Plug-Ins
  5. Click Import >
  6. Browse and locate the installer files in apex/region_type_plugin_be_apexrnd_ame.sql)
  7. Complete the wizard.

Follow these steps to finish your Plug-in installation by adding your Plug-in API key:

  1. Login into https://www.apexmediaextension.com
  2. Copy your API key from the Dashboard
  3. Access your target APEX Workspace
  4. Select the Application Builder
  5. Select the Application where you wish to import the plug-in (plug-ins belong to an application, not a workspace)
  6. Access Shared Components > Component Settings
  7. Here select APEX Media Extension (AME) [Plug-in]
  8. Add you API key that you copied in step 2
  9. Click Apply
  10. Installation is now completed

Installation note:

To use the AME PL/SQL API you may need to configure your ACL (Access Control List) settings to allow access to: http(s)://api.apexmediaextension.com

How to use the AOP Plug-in

Simply add a new region called AME (plug-in) on your APEX page.

PL/SQL API

The AME PL/SQL API ame_api_pkg consists out of 8 different ways to deal with images. In this section we give an overview by procedure and function.

/**
 * @Description: Convert one or more files by using a SQL query, PL/SQL Function returning SQL or JSON
 *               This returns a blob which includes the output 
 *               AME 20.1 will return one file. In AME 20.2 multiple files will be returned as zip
 *
 * @Param: p_source_type type of source: c_source_type_sql ('SQL'), c_source_type_plsql_sql ('PLSQL_SQL'), c_source_type_plsql ('PLSQL_JSON'), c_source_type_json ('JSON')
 * @Param: p_source Format of query: 
 *            select "file", 
 *                   "quality", "width", "max_width", "height", "max_height",
 *                   cursor("horizontal", "vertical") as "flip", 
 *                   cursor("value", "resize") as "rotate", 
 *                   cursor("font", "font_size", "x", "y", "rotation", "text", "image", "width", "height") as "overlay" ,
 *                   cursor("x", "y", "width", "height") as "crop",
 *                   "output_filename", "output_mime_type"
 *              from my_table 
 * @Param: p_binds Binds defined in the source (not necessary for APEX Page Items)
 * @Param: p_output_to Where does the blob or file need to be sent to: 
 *            - c_output_browser: the browser will open the file          
 *            - c_output_inline: the output is defined for showing inline in a region
 *            - c_output_directory: the file is stored on the ame Server in this directory
 *            - c_output_cloud: a file is sent to the cloud (Dropbox, Amazon S3, Google Drive) using the credentials defined in g_cloud_provider, g_cloud_location and g_cloud_access_token
 * @Param: p_debug Turning debugging on will generate the JSON that is sent to the ame Server in a file. The actual request to the ame Server is not done. Following constants can be used:
 *            - c_debug_remote: store the JSON in your dashboard on https://www.apexofficeprint.com
 *            - c_debug_local: store the JSON local on your pc
 *            - c_debug_application_item: depending the Application item ame_debug, Remote (Yes) or Local (Local) or no debugging is done
 * @Param: p_ame_url Description: URL where the AME Server is running. For the ame Cloud use c_ame_url
 * @Param: p_api_key Description: API Key which can be found when you login at https://www.apexofficeprint.com/ape/
 * @Param: p_failover_ame_url: URL where the ame Failover Server is running. For the ame Cloud use c_ame_url_fallback
 * @Param: p_failover_procedure: Procedure which is called when the failover URL is being used, so you are warned the main ame server has issues.
 * @Param: p_log_procedure: Procedure which can be defined to do your own extra logging.
 * @Return: Converted file in blob
 *
 * @Example:
  -- SQL
  select 
      ame_api_pkg.convert_files_b(
              p_source_type      => 'SQL',
              p_source           => q'[select apex_web_service.blob2clobbase64(blob_content) as "file", 
                                              :P14_MAX_WIDTH as "max_width", :P14_MAX_HEIGHT as "max_height"
                                              --cursor
                                          from ame_images      
                                        where id = 1 
              ]',
              p_ame_url          => 'http://api.apexmediaextension.com',
              p_api_key          => ''
            ) as new_image
  from ame_images
  where id = 1;

  -- PL/SQL    
  declare
    l_new_blob  blob;
  begin
    -- for now only 1 image is supported with convert_files_b, 
    -- see convert_files_c to convert multiple images in one call
    l_new_blob := ame_api_pkg.convert_files_b(
                    p_source_type      => ame_api_pkg.c_source_type_sql,
                    p_source           => q'[
                      select 'http://www.apexofficeprint.com/docs/media/e2MonwE.jpg' as "file", 
                            640 as "max_width", 480 as "max_height",
                            cursor(select null as "image", null as "width", null as "height", 'watermark' as "text", 'open sans' as "font", 22 as "font_size", '#FFFFFF' as "font_color", 10 as "x", 10 as "y", 45 as "rotation" from dual
                                    union all
                                    select 'https://www.apexrnd.be/apexrnd/images/apex-rd-logo.png' as "image", 60 as "width", 60 as "height", null as "text", null as "font", null as "font_size", null as "font_color", 10 as "x", 10 as "y", 45 as "rotation" from dual 
                                  ) as "overlay", 
                            'nice.png' as "output_filename", 'image/png' as "output_mime_type"
                        from dual
                    ]',
                    p_ame_url          => ame_api_pkg.c_ame_url,
                    p_api_key          => ''
                  );         
    sys.htp.p('length new blob: ' || to_char(dbms_lob.getlength(l_new_blob)));        
  end;

  -- JSON
  declare
    l_new_blob  blob;
  begin
    l_new_blob := ame_api_pkg.convert_files_b(
                    p_source_type      => ame_api_pkg.c_source_type_json,
                    p_source           => q'!
                        [ {
                          "file": "http://www.apexofficeprint.com/docs/media/e2MonwE.jpg",
                          "max_width": 640,
                          "max_height": 480,
                          "overlay": [{
                            "text": "Watermark",
                            "font": "open sans",
                            "font_size": 22,
                            "x": 25,
                            "y": 40,
                            "rotation": 0
                          },{
                            "image":"https://www.apexrnd.be/apexrnd/images/apex-rd-logo.png",
                            "x": 10,
                            "y": 10,
                            "width": 60,
                            "height": 60
                          }],
                          "output_filename": "nice.png",
                          "output_mime_type": "image/png"
                        } ]
                    !',
                    p_ame_url          => ame_api_pkg.c_ame_url,
                    p_api_key          => ''
                  );    
    sys.htp.p('length new blob: ' || to_char(dbms_lob.getlength(l_new_blob)));        
  end;   
 */
function convert_files_b(
  p_source_type           in varchar2 default c_source_type_sql,
  p_source                in clob,
  p_binds                 in wwv_flow_plugin_util.t_bind_list default c_binds,
  p_output_to             in varchar2 default null,
  p_debug                 in varchar2 default null,
  p_ame_url               in varchar2 default null,
  p_api_key               in varchar2 default null,
  p_ame_mode              in varchar2 default null,
  p_failover_ame_url      in varchar2 default null,
  p_failover_procedure    in varchar2 default null,
  p_log_procedure         in varchar2 default null
) return blob;


/**
 * @Description: Convert one or more files by using a SQL query, PL/SQL Function returning SQL or JSON
 *               This returns a clob which includes the output in a JSON format
 *
 * @Param: p_source_type type of source: c_source_type_sql ('SQL'), c_source_type_plsql_sql ('PLSQL_SQL'), c_source_type_plsql ('PLSQL_JSON'), c_source_type_json ('JSON')
 * @Param: p_source Format of query: 
 *            select "file", 
 *                   "quality", "width", "max_width", "height", "max_height",
 *                   cursor("horizontal", "vertical") as "flip", 
 *                   cursor("value", "resize") as "rotate", 
 *                   cursor("font", "font_size", "x", "y", "rotation", "text", "image", "width", "height") as "overlay" ,
 *                   cursor("x", "y", "width", "height") as "crop",
 *                   "output_filename", "output_mime_type"
 *              from my_table 
 * @Param: p_output_to Where does the blob or file need to be sent to: 
 *            - c_output_browser: the browser will open the file          
 *            - c_output_inline: the output is defined for showing inline in a region
 *            - c_output_directory: the file is stored on the ame Server in this directory
 *            - c_output_cloud: a file is sent to the cloud (Dropbox, Amazon S3, Google Drive) using the credentials defined in g_cloud_provider, g_cloud_location and g_cloud_access_token
 * @Param: p_binds Binds defined in the source (not necessary for APEX Page Items)
 * @Param: p_debug Turning debugging on will generate the JSON that is sent to the ame Server in a file. The actual request to the ame Server is not done. Following constants can be used:
 *            - c_debug_remote: store the JSON in your dashboard on https://www.apexofficeprint.com
 *            - c_debug_local: store the JSON local on your pc
 *            - c_debug_application_item: depending the Application item ame_debug, Remote (Yes) or Local (Local) or no debugging is done
 * @Param: p_ame_url Description: URL where the AME Server is running. For the ame Cloud use c_ame_url
 * @Param: p_api_key Description: API Key which can be found when you login at https://www.apexofficeprint.com/ape/
 * @Param: p_failover_ame_url: URL where the ame Failover Server is running. For the ame Cloud use c_ame_url_fallback
 * @Param: p_failover_procedure: Procedure which is called when the failover URL is being used, so you are warned the main ame server has issues.
 * @Param: p_log_procedure: Procedure which can be defined to do your own extra logging.
 * @Return: Converted file in blob
 *
 * @Example:
  -- SQL
  select 
      ame_api_pkg.convert_files_c(
              p_source_type      => 'SQL',
              p_source           => q'[select apex_web_service.blob2clobbase64(blob_content) as "file", 
                                              :P14_MAX_WIDTH as "max_width", :P14_MAX_HEIGHT as "max_height"
                                              --cursor
                                          from ame_images      
                                        where id = 1 
              ]',
              p_ame_url          => 'http://api.apexmediaextension.com',
              p_api_key          => ''
            ) as new_image
  from ame_images
  where id in (1,2);

  -- PL/SQL    
  declare
    l_new_clob  clob;
  begin
    l_new_clob := ame_api_pkg.convert_files_c(
                    p_source_type      => ame_api_pkg.c_source_type_sql,
                    p_source           => q'[
                      select 'http://www.apexofficeprint.com/docs/media/e2MonwE.jpg' as "file", 
                            640 as "max_width", 480 as "max_height",
                            cursor(select null as "image", null as "width", null as "height", 'watermark' as "text", 'open sans' as "font", 22 as "font_size", '#FFFFFF' as "font_color", 10 as "x", 10 as "y", 45 as "rotation" from dual
                                    union all
                                    select 'https://www.apexrnd.be/apexrnd/images/apex-rd-logo.png' as "image", 60 as "width", 60 as "height", null as "text", null as "font", null as "font_size", null as "font_color", 10 as "x", 10 as "y", 45 as "rotation" from dual 
                                  ) as "overlay", 
                            'nice.png' as "output_filename", 'image/png' as "output_mime_type"
                        from dual
                    ]',
                    p_ame_url          => ame_api_pkg.c_ame_url,
                    p_api_key          => ''
                  );
    sys.htp.p('length new clob: ' || to_char(dbms_lob.getlength(l_new_clob)));                          
  end;
 */
function convert_files_c(
  p_source_type           in varchar2 default c_source_type_sql,
  p_source                in clob,
  p_binds                 in wwv_flow_plugin_util.t_bind_list default c_binds,
  p_debug                 in varchar2 default null,
  p_ame_url               in varchar2 default null,
  p_api_key               in varchar2 default null,
  p_ame_mode              in varchar2 default null,
  p_failover_ame_url      in varchar2 default null,
  p_failover_procedure    in varchar2 default null,
  p_log_procedure         in varchar2 default null
) return clob;

/**
 * @Description: Convert one image by specifying a blob or url
 *
 * @Param: p_source_blob the blob of the image you want to adjust
 * @Param: p_source_url the url of the image you want to adjust (AME Server needs to be able to access it)
 * @Param: p_manipulator specifies which image/video manipulator to use. Available manipulators: "sharp" (default) or "jimp".
 * @Param: p_quality the quality of a JPEG image; values 0 till 100
 * @Param: p_width the new width of the image; will not be proporsional 
 * @Param: p_max_width the new width of the image; will be proporsional 
 * @Param: p_height the new height of the image; will not be proporsional 
 * @Param: p_max_height the new height of the image; will be proporsional 
 * @Param: p_resize_method the method to use for resizing: Sharp: nearest_neighbour,bicubic,mitchell,lanczos2,lanczos3,resize,methods 
 *                                                         Jimp: nearest_neighbour,bilinear,bicubic,hermite,bezier
 * @Param: p_crop select a part of the image {"x":"","y":"","width":"","height":""}
 * @Param: p_flip flip or mirror the image; {"horizontal":true, 
 *                                           "vertical":true}
 * @Param: p_rotate rotate the image {"value":90, //degrees, clockwise 
 *                                    "resize": true // if the width and height should be resized -> default false;}
 * @Param: p_overlay put one or more text and/or image watermarks [{"font_size":"22px","font": "open sans","x": 25,"y": 40,"text": "Watermark",}, 
 *                                                                 {"x": 25,"y": 40,"rotation": 0,"image": "base64:xxxx","width":100,"height":100}] 
 * @Param: p_greyscale make an image grey
 * @Param: p_output_filename the name of the output file
 * @Param: p_output_mime_type the mime/type of the output
 * @Return: Converted file in blob
 *
 * @Example:
  -- SQL
  begin
    ame_api_pkg.g_api_key := '';
  end; 

  select 
      ame_api_pkg.convert_image_b1(
        p_source_blob      => blob_content,
        p_max_width        => 100,
        p_flip             => '{"vertical": true}',
        p_output_filename  => 'output.jpg',
        p_output_mime_type => 'image/jpeg'
      ) as new_image
  from ame_images
  where id = 1;

  -- PL/SQL
  -- make sure your API Key is set before you do call
  declare
    l_new_blob  blob;
  begin
    ame_api_pkg.g_api_key := '';

    for r in (select blob_content 
                from ame_images
              where id = 1)
    loop
      -- for now only 1 image is supported
      l_new_blob := ame_api_pkg.convert_image_b1(
                      p_source_blob      => r.blob_content,
                      p_max_width        => 100,
                      p_flip             => '{"vertical": true}',
                      p_output_filename  => 'output.jpg',
                      p_output_mime_type => 'image/jpeg'
                    );    
      sys.htp.p('length orig blob: ' || to_char(dbms_lob.getlength(r.blob_content)));        
      sys.htp.p('length new blob: ' || to_char(dbms_lob.getlength(l_new_blob)));        
    end loop;
  end;  
 */
function convert_image_b1(
  p_source_blob      in blob default null,
  p_source_url       in varchar2 default null,
  p_manipulator      in varchar2 default null,
  p_quality          in varchar2 default null,
  p_width            in number default null,
  p_max_width        in number default null,
  p_height           in number default null,
  p_max_height       in number default null,
  p_resize_method    in varchar2 default null,
  p_crop             in varchar2 default null,
  p_flip             in varchar2 default null,
  p_rotate           in number default null,
  p_overlay          in varchar2 default null,
  p_greyscale        in varchar2 default null,
  p_output_filename  in varchar2 default null,
  p_output_mime_type in varchar2 default null  
) return blob;


/**
 * @Description: Convert one image by specifying a blob or url
 *
 * @Param: p_source_blob the blob of the image you want to adjust
 * @Param: p_source_url the url of the image you want to adjust (AME Server needs to be able to access it)
 * @Param: p_manipulator specifies which image/video manipulator to use. Available manipulators: "sharp" (default) or "jimp".
 * @Param: p_quality the quality of a JPEG image; values 0 till 100
 * @Param: p_width the new width of the image; will not be proporsional 
 * @Param: p_max_width the new width of the image; will be proporsional 
 * @Param: p_height the new height of the image; will not be proporsional 
 * @Param: p_max_height the new height of the image; will be proporsional 
 * @Param: p_resize_method the method to use for resizing: Sharp: nearest_neighbour,bicubic,mitchell,lanczos2,lanczos3,resize,methods 
 *                                                         Jimp: nearest_neighbour,bilinear,bicubic,hermite,bezier
 * @Param: p_crop_x x coordinates to start crop of image
 * @Param: p_crop_y y coordinates to start crop of image
 * @Param: p_crop_width width of selection
 * @Param: p_crop_height height of selection
 * @Param: p_flip_horizontal (Y/N) horizontal flip the image
 * @Param: p_flip_vertical (Y/N) vertical flip the image
 * @Param: p_rotate_degrees rotate the image clockwise e.g. 90
 * @Param: p_overlay_text put text on top of the image        
 * @Param: p_overlay_font font for text, default is open sans
 * @Param: p_overlay_font_size font size
 * @Param: p_overlay_font_color white or black
 * @Param: p_overlay_txt_x x coordinates
 * @Param: p_overlay_txt_y y coordinates
 * @Param: p_overlay_txt_rotation rotate text
 * @Param: p_overlay_image put another image on top of the image
 * @Param: p_overlay_img_x x coordinates
 * @Param: p_overlay_img_y y coordinates
 * @Param: p_overlay_img_rotation rotate image
 * @Param: p_overlay_img_width width of image
 * @Param: p_overlay_img_height height of image
 * @Param: p_greyscale make an image grey
 * @Param: p_output_filename the name of the output file
 * @Param: p_output_mime_type the mime/type of the output
 * @Return: Converted file in blob
 *
 * @Example:
  -- SQL
  begin
    ame_api_pkg.g_api_key := '';
  end; 

  select 
      ame_api_pkg.convert_image_b2(
        p_source_blob      => blob_content,
        p_max_width        => 100,
        p_flip_vertical    => 'Y',
        p_output_filename  => 'output.jpg',
        p_output_mime_type => 'image/jpeg'
      ) as new_image
  from ame_images
  where id = 1;

  -- PL/SQL
  -- make sure your API Key is set before you do call
  declare
    l_new_blob  blob;
  begin
    ame_api_pkg.g_api_key := '';

    for r in (select blob_content 
                from ame_images
              where id = 1)
    loop
      l_new_blob := ame_api_pkg.convert_image_b2(
                      p_source_blob      => r.blob_content,
                      p_max_width        => 100,
                      p_flip_vertical    => 'Y',
                      p_output_filename  => 'output.jpg',
                      p_output_mime_type => 'image/jpeg'
                    );    
      sys.htp.p('length orig blob: ' || to_char(dbms_lob.getlength(r.blob_content)));        
      sys.htp.p('length new blob: ' || to_char(dbms_lob.getlength(l_new_blob)));        
    end loop;
  end;  
 */
function convert_image_b2(
  p_source_blob          in blob default null,
  p_source_url           in varchar2 default null,
  -- manipulator
  p_manipulator          in varchar2 default null,
  -- quality jpeg
  p_quality              in varchar2 default null,
  -- resize   
  p_width                in number default null,
  p_max_width            in number default null,
  p_height               in number default null,
  p_max_height           in number default null,
  p_resize_method        in varchar2 default null,
  -- crop
  p_crop_x               in number default null,
  p_crop_y               in number default null,
  p_crop_width           in number default null,
  p_crop_height          in number default null,
  -- flip   
  p_flip_horizontal      in varchar2 default null,
  p_flip_vertical        in varchar2 default null,
  -- rotate   
  p_rotate_degrees       in number default null,
  -- overlay (watermark)
  p_overlay_text         in varchar2 default null,
  p_overlay_font         in varchar2 default null,
  p_overlay_font_size    in number default null,
  p_overlay_font_color   in varchar2 default null,
  p_overlay_txt_x        in number default null,
  p_overlay_txt_y        in number default null,
  p_overlay_txt_rotation in number default null,
  p_overlay_image        in clob default null,
  p_overlay_img_x        in number default null,
  p_overlay_img_y        in number default null,
  p_overlay_img_rotation in number default null,
  p_overlay_img_width    in number default null,
  p_overlay_img_height   in number default null,
  -- greyscale
  p_greyscale            in varchar2 default null,
  -- output
  p_output_filename      in varchar2 default null,
  p_output_mime_type     in varchar2 default null  
) return blob;


/**
 * @Description: Convert one image by specifying a blob or url
 *
 * @Param: p_source_blob the blob of the image you want to adjust
 * @Param: p_source_url the url of the image you want to adjust (AME Server needs to be able to access it)
 * @Param: p_manipulator specifies which image/video manipulator to use. Available manipulators: "sharp" (default) or "jimp".
 * @Param: p_quality the quality of a JPEG image; values 0 till 100
 * @Param: p_width the new width of the image; will not be proporsional 
 * @Param: p_max_width the new width of the image; will be proporsional 
 * @Param: p_height the new height of the image; will not be proporsional 
 * @Param: p_max_height the new height of the image; will be proporsional 
 * @Param: p_resize_method the method to use for resizing: Sharp: nearest_neighbour,bicubic,mitchell,lanczos2,lanczos3,resize,methods 
 *                                                         Jimp: nearest_neighbour,bilinear,bicubic,hermite,bezier
 * @Param: p_crop_x x coordinates to start crop of image
 * @Param: p_crop_y y coordinates to start crop of image
 * @Param: p_crop_width width of selection
 * @Param: p_crop_height height of selection
 * @Param: p_flip_horizontal (Y/N) horizontal flip the image
 * @Param: p_flip_vertical (Y/N) vertical flip the image
 * @Param: p_rotate_degrees rotate the image clockwise e.g. 90
 * @Param: p_overlay_sql put one or more texts and/or images on top of the image
 *           use following syntax for the SQL statement:
 *           select 'url or base64 encoded blob' as "image", 50 as "width", 30 as "height", 50 as "max_width", 50 as "max_height",
                    'watermark' as "text", 'open sans' as "font", 12 as "font_size", 'white' as "font_color", 
                    10 as "x", 10 as "y", 45 as "rotation" 
               from table
 * @Param: p_greyscale make an image grey
 * @Param: p_output_filename the name of the output file
 * @Param: p_output_mime_type the mime/type of the output
 * @Return: Converted file in blob
 *
 * @Example:
  declare
    l_orig_blob blob;
    l_new_blob  blob;
  begin
    select blob_content
      into l_orig_blob
      from ame_images
      where id=1;

    ame_api_pkg.g_api_key := '';

    l_new_blob := ame_api_pkg.convert_image_b3(
                    p_source_blob      => l_orig_blob,
                    p_overlay_sql      => q'[
                      select 'watermark' as "text", 'open sans' as "font", 40 as "font_size", 'white' as "font_color", null as "image", 50 as "x", 10 as "y", 45 as "rotation" , null as "width", null as "height" from dual
                      union all
                      select null as "text", null as "font", null as "font_size", null as "font_color", 'https://www.apexrnd.be/apexrnd/images/apex-rd-logo.png' as "image", 10 as "x", 10 as "y", 90 as "rotation", 90 as "width", 50 as "height" from dual
                      union all
                      select null as "text", null as "font", null as "font_size", null as "font_color", 'https://www.apexrnd.be/apexrnd/images/apex-rd-logo.png' as "image", 200 as "x", 100 as "y", 0 as "rotation", 80 as "max_width", 60 as "max_height" from dual
                    ]',
                    p_output_filename  => 'output.jpg',
                    p_output_mime_type => 'image/jpeg'
                  );
    sys.htp.p('length orig blob: ' || to_char(dbms_lob.getlength(l_orig_blob)));        
    sys.htp.p('length new blob: ' || to_char(dbms_lob.getlength(l_new_blob)));        
  end;
 */
function convert_image_b3(
  p_source_blob          in blob default null,
  p_source_url           in varchar2 default null,
  -- manipulator
  p_manipulator          in varchar2 default null,
  -- quality jpeg
  p_quality              in varchar2 default null,
  -- resize   
  p_width                in number default null,
  p_max_width            in number default null,
  p_height               in number default null,
  p_max_height           in number default null,
  p_resize_method        in varchar2 default null,
  -- crop
  p_crop_x               in number default null,
  p_crop_y               in number default null,
  p_crop_width           in number default null,
  p_crop_height          in number default null,
  -- flip   
  p_flip_horizontal      in varchar2 default null,
  p_flip_vertical        in varchar2 default null,
  -- rotate   
  p_rotate_degrees       in number default null,
  -- overlay (watermark)
  p_overlay_sql          in varchar2 default null,
  -- greyscale
  p_greyscale            in varchar2 default null,
  -- output
  p_output_filename      in varchar2 default null,
  p_output_mime_type     in varchar2 default null  
) return blob;


/**
 * @Description: Convert one image by specifying a blob or url
 *
 * @Param: p_source_blob the blob of the image you want to adjust
 * @Param: p_source_url the url of the image you want to adjust (AME Server needs to be able to access it)
 * @Param: p_manipulator specifies which image/video manipulator to use. Available manipulators: "sharp" (default) or "jimp".
 * @Param: p_quality the quality of a JPEG image; values 0 till 100
 * @Param: p_width the new width of the image; will not be proporsional 
 * @Param: p_max_width the new width of the image; will be proporsional 
 * @Param: p_height the new height of the image; will not be proporsional 
 * @Param: p_max_height the new height of the image; will be proporsional 
 * @Param: p_resize_method the method to use for resizing: Sharp: nearest_neighbour,bicubic,mitchell,lanczos2,lanczos3,resize,methods 
 *                                                         Jimp: nearest_neighbour,bilinear,bicubic,hermite,bezier
 * @Param: p_crop_x x coordinates to start crop of image
 * @Param: p_crop_y y coordinates to start crop of image
 * @Param: p_crop_width width of selection
 * @Param: p_crop_height height of selection
 * @Param: p_flip_horizontal (Y/N) horizontal flip the image
 * @Param: p_flip_vertical (Y/N) vertical flip the image
 * @Param: p_rotate_degrees rotate the image clockwise e.g. 90
 * @Param: p_overlay_sql put one or more texts and/or images on top of the image
 *           use following syntax for the SQL statement:
 *           select 'url or base64 encoded blob' as "image", 50 as "width", 30 as "height", 50 as "max_width", 50 as "max_height",
                    'watermark' as "text", 'open sans' as "font", 12 as "font_size", 'white' as "font_color", 
                    10 as "x", 10 as "y", 45 as "rotation" 
               from table
 * @Param: p_greyscale make an image grey
 * @Param: p_output_filename the name of the output file
 * @Param: p_output_mime_type the mime/type of the output
 * @Out: o_initial_width output initial width
 * @Out: o_initial_height output initial height
 * @Out: o_initial_mime_type output initial mime type
 * @Out: o_initial_extension output extension e.g. jpg
 * @Out: o_output_width output new width
 * @Out: o_output_height output new height
 * @Out: o_output_mime_type output new mime type
 * @Out: o_output_extension output new extension
 * @Out: o_output_blob output image (blob)
 * @Out: o_meta_data  output meta data
 *
 * @Example:
  declare
    l_amt               integer := 4000;
    l_pos               integer := 1;
    l_buf               varchar2(32000);      
    l_orig_blob         blob;
    l_initial_width     number;
    l_initial_height    number;
    l_initial_mime_type varchar2(200);
    l_initial_extension varchar2(200);
    l_output_width      number;
    l_output_height     number;
    l_output_mime_type  varchar2(200);
    l_output_extension  varchar2(200);
    l_output_blob       blob;
    l_meta_data         clob;
  begin
    select blob_content
      into l_orig_blob
      from ame_images
      where id=1;

    ame_api_pkg.g_api_key := '';

    ame_api_pkg.convert_image_o1(
      p_source_blob      => l_orig_blob,
      p_overlay_sql      => q'[
        select 'watermark' as "text", 'open sans' as "font", 40 as "font_size", 'white' as "font_color", null as "image", 50 as "x", 10 as "y", 45 as "rotation" , null as "width", null as "height" from dual
        union all
        select null as "text", null as "font", null as "font_size", null as "font_color", 'https://www.apexrnd.be/apexrnd/images/apex-rd-logo.png' as "image", 10 as "x", 10 as "y", 90 as "rotation", 90 as "width", 50 as "height" from dual
        union all
        select null as "text", null as "font", null as "font_size", null as "font_color", 'https://www.apexrnd.be/apexrnd/images/apex-rd-logo.png' as "image", 200 as "x", 100 as "y", 0 as "rotation", 80 as "max_width", 60 as "max_height" from dual
      ]',
      p_output_filename  => 'output.jpg',
      p_output_mime_type => 'image/jpeg',
      o_initial_width    => l_initial_width,
      o_initial_height   => l_initial_height,
      o_initial_mime_type=> l_initial_mime_type,
      o_initial_extension=> l_initial_extension,
      o_output_width     => l_output_width,
      o_output_height    => l_output_height,
      o_output_mime_type => l_output_mime_type,
      o_output_extension => l_output_extension,
      o_output_blob      => l_output_blob,
      o_meta_data        => l_meta_data                           
    );

    sys.htp.p('length orig blob: ' || to_char(dbms_lob.getlength(l_orig_blob)));        
    sys.htp.p('image initial width: ' || to_char(l_initial_width));
    sys.htp.p('image initial height: ' || to_char(l_initial_height));
    sys.htp.p('initial mime_type: ' || l_initial_mime_type);
    sys.htp.p('initial extension: ' || l_initial_extension);        
    sys.htp.p('length new blob: ' || to_char(dbms_lob.getlength(l_output_blob)));        
    sys.htp.p('image width: ' || to_char(l_output_width));
    sys.htp.p('image height: ' || to_char(l_output_height));
    sys.htp.p('mime_type: ' || l_output_mime_type);
    sys.htp.p('extension: ' || l_output_extension);        
    sys.htp.p('meta data: ');
    -- as the meta data can be over 32K we will loop over it
    if dbms_lob.getlength(l_meta_data) > 0
    then
      loop
        begin
          dbms_lob.read(l_meta_data, l_amt, l_pos, l_buf);
          l_pos := l_pos+l_amt;
          l_amt := 4000;
          sys.htp.prn(l_buf);
        exception
        when no_data_found then
          exit;
        end;
      end loop;        
    end if;          
  end;
 */
 procedure convert_image_o1(
  p_source_blob          in blob default null,
  p_source_url           in varchar2 default null,
  -- manipulator
  p_manipulator          in varchar2 default null,
  -- quality jpeg
  p_quality              in varchar2 default null,
  -- resize   
  p_width                in number default null,
  p_max_width            in number default null,
  p_height               in number default null,
  p_max_height           in number default null,
  p_resize_method        in varchar2 default null,
  -- crop
  p_crop_x               in number default null,
  p_crop_y               in number default null,
  p_crop_width           in number default null,
  p_crop_height          in number default null,
  -- flip   
  p_flip_horizontal      in varchar2 default null,
  p_flip_vertical        in varchar2 default null,
  -- rotate   
  p_rotate_degrees       in number default null,
  -- overlay (watermark)
  p_overlay_sql          in varchar2 default null,
  -- greyscale
  p_greyscale            in varchar2 default null,
  -- output
  p_output_filename      in varchar2 default null,
  p_output_mime_type     in varchar2 default null,
  -- output variables
  o_initial_width        out number,
  o_initial_height       out number, 
  o_initial_mime_type    out varchar2,
  o_initial_extension    out varchar2,
  o_output_width         out number,
  o_output_height        out number,
  o_output_mime_type     out varchar2,
  o_output_extension     out varchar2,
  o_output_blob          out blob,
  o_meta_data            out clob
);


/**
 * @Description: Convert one image by specifying a blob or url
 *
 * @Param: p_source_blob the blob of the image you want to adjust
 * @Param: p_source_url the url of the image you want to adjust (AME Server needs to be able to access it)
 * @Param: p_manipulator specifies which image/video manipulator to use. Available manipulators: "sharp" (default) or "jimp".
 * @Param: p_quality the quality of a JPEG image; values 0 till 100
 * @Param: p_width the new width of the image; will not be proporsional 
 * @Param: p_max_width the new width of the image; will be proporsional 
 * @Param: p_height the new height of the image; will not be proporsional 
 * @Param: p_max_height the new height of the image; will be proporsional 
 * @Param: p_resize_method the method to use for resizing: Sharp: nearest_neighbour,bicubic,mitchell,lanczos2,lanczos3,resize,methods 
 *                                                         Jimp: nearest_neighbour,bilinear,bicubic,hermite,bezier
 * @Param: p_crop_x x coordinates to start crop of image
 * @Param: p_crop_y y coordinates to start crop of image
 * @Param: p_crop_width width of selection
 * @Param: p_crop_height height of selection
 * @Param: p_flip_horizontal (Y/N) horizontal flip the image
 * @Param: p_flip_vertical (Y/N) vertical flip the image
 * @Param: p_rotate_degrees rotate the image clockwise e.g. 90
 * @Param: p_overlay_sql put one or more texts and/or images on top of the image
 *           use following syntax for the SQL statement:
 *           select 'url or base64 encoded blob' as "image", 50 as "width", 30 as "height", 50 as "max_width", 50 as "max_height",
                    'watermark' as "text", 'open sans' as "font", 12 as "font_size", 'white' as "font_color", 
                    10 as "x", 10 as "y", 45 as "rotation" 
               from table
 * @Param: p_greyscale make an image grey
 * @Param: p_output_filename the name of the output file
 * @Param: p_output_mime_type the mime/type of the output
 * @Out: o_output_blob output image (blob)
 * @Out: o_meta_data  output meta data
 *
 * @Example:
  declare
    l_amt               integer := 4000;
    l_pos               integer := 1;
    l_buf               varchar2(32000);      
    l_orig_blob         blob;
    l_output_blob       blob;
    l_meta_data         clob;
  begin
    select blob_content
      into l_orig_blob
      from ame_images
      where id=1;

    ame_api_pkg.g_api_key := '';

    ame_api_pkg.convert_image_o2(
      p_source_blob      => l_orig_blob,
      p_overlay_sql      => q'[
        select 'watermark' as "text", 'open sans' as "font", 40 as "font_size", 'white' as "font_color", null as "image", 50 as "x", 10 as "y", 45 as "rotation" , null as "width", null as "height" from dual
        union all
        select null as "text", null as "font", null as "font_size", null as "font_color", 'https://www.apexrnd.be/apexrnd/images/apex-rd-logo.png' as "image", 10 as "x", 10 as "y", 90 as "rotation", 90 as "width", 50 as "height" from dual
        union all
        select null as "text", null as "font", null as "font_size", null as "font_color", 'https://www.apexrnd.be/apexrnd/images/apex-rd-logo.png' as "image", 200 as "x", 100 as "y", 0 as "rotation", 80 as "max_width", 60 as "max_height" from dual
      ]',
      p_output_filename  => 'output.jpg',
      p_output_mime_type => 'image/jpeg',
      o_output_blob      => l_output_blob,
      o_meta_data        => l_meta_data                           
    );

    sys.htp.p('length blob: ' || to_char(dbms_lob.getlength(l_output_blob)));        
    sys.htp.p('meta data: ');
    -- as the meta data can be over 32K we will loop over it
    if dbms_lob.getlength(l_meta_data) > 0
    then
      loop
        begin
          dbms_lob.read(l_meta_data, l_amt, l_pos, l_buf);
          l_pos := l_pos+l_amt;
          l_amt := 4000;
          sys.htp.prn(l_buf);
        exception
        when no_data_found then
          exit;
        end;
      end loop;        
    end if;          
  end;
 */
procedure convert_image_o2(
  p_source_blob          in blob default null,
  p_source_url           in varchar2 default null,
  -- manipulator
  p_manipulator          in varchar2 default null,
  -- quality jpeg
  p_quality              in varchar2 default null,
  -- resize   
  p_width                in number default null,
  p_max_width            in number default null,
  p_height               in number default null,
  p_max_height           in number default null,
  p_resize_method        in varchar2 default null,
  -- crop
  p_crop_x               in number default null,
  p_crop_y               in number default null,
  p_crop_width           in number default null,
  p_crop_height          in number default null,
  -- flip   
  p_flip_horizontal      in varchar2 default null,
  p_flip_vertical        in varchar2 default null,
  -- rotate   
  p_rotate_degrees       in number default null,
  -- overlay (watermark)
  p_overlay_sql          in varchar2 default null,
  -- greyscale
  p_greyscale            in varchar2 default null,
  -- output
  p_output_filename      in varchar2 default null,
  p_output_mime_type     in varchar2 default null,
  -- output variables
  o_output_blob          out blob,
  o_meta_data            out clob
);


/**
 * @Description: Get the meta data from an image by specifying a blob or url
 *
 * @Param: p_source_blob the blob of the image you want to adjust
 * @Param: p_source_url the url of the image you want to adjust (AME Server needs to be able to access it)
 * @Out: o_output_width output new width
 * @Out: o_output_height output new height
 * @Out: o_output_mime_type output new mime type
 * @Out: o_meta_data  output meta data
 *
 * @Example:
  declare
    l_amt        integer := 4000;
    l_pos        integer := 1;
    l_buf        varchar2(32000);      
    l_orig_blob  blob;
    l_width      number(6);
    l_height     number(6);
    l_mime_type  varchar2(200);
    l_extension  varchar2(10);
    l_meta_data  clob;
  begin
    select blob_content
      into l_orig_blob
      from ame_images
      where id=1;

    ame_api_pkg.g_api_key := '';

    ame_api_pkg.get_image_properties(
      p_source_blob  => l_orig_blob,
      o_width        => l_width,     
      o_height       => l_height,    
      o_mime_type    => l_mime_type, 
      o_extension    => l_extension,
      o_meta_data    => l_meta_data 
    ); 

    sys.htp.p('image width: ' || to_char(l_width));
    sys.htp.p('image height: ' || to_char(l_height));
    sys.htp.p('mime_type: ' || l_mime_type);
    sys.htp.p('extension: ' || l_extension);        
    sys.htp.p('meta data: ');
    -- as the meta data can be over 32K we will loop over it
    if dbms_lob.getlength(l_meta_data) > 0
    then
      loop
        begin
          dbms_lob.read(l_meta_data, l_amt, l_pos, l_buf);
          l_pos := l_pos+l_amt;
          l_amt := 4000;
          sys.htp.prn(l_buf);
        exception
        when no_data_found then
          exit;
        end;
      end loop;        
    end if;  
  end;
 */
procedure get_image_properties(
  p_source_blob          in blob default null,
  p_source_url           in varchar2 default null,
  -- output variables
  o_width                out number,
  o_height               out number, 
  o_mime_type            out varchar2,
  o_extension            out varchar2,
  o_meta_data            out clob
);

Manual (REST) call

Overview

Behind the scenes the AME APEX plug-in and PL/SQL API is creating a JSON file that will be sent to the AME server. Below you find more details about the JSON structure that is used. By understanding this JSON structure you can manually interact with the AME server in case you wanted to code in PL/SQL or other languages.

JSON File

The JSON file is a file that follows the standard JSON structure (http://json.org/).

This JSON file contains an JSON object meaning it starts with { and ends with }. This JSON object contains four compulsory JSON attributes/objects namely "media_files", "output", "api_key" and a few optional object "version", "request_origin" or "apex_version". The purpose of each object will now be explained.

"apex_version" attribute or "request_origin" attribute\

One of the two must be present. The apex_version will contain the version of oracle APEX where the call is happening from.

The request_origin attribute will give info about the callee.

"api_key" attribute

The API key that should be used for processing the request.

"manipulator" attribute

This is an optional attribute that will specify which image/video manipulator to use. Available manipulators: "sharp" or "jimp". (default "sharp");

"media_files" array

This array will contain the media files that need to be processed or analyzed. Each object inside this array will have the following structure:

{
    //Mandatory
    "file":"",//The content of the media file. 
            //This can be a URL (ftp or http), base64 encoded media file or a relative location from the server inside ame_resources folder.

    //Optional
    "return_output": true, //whether the output should be returned, if false, only the metadata will be returned back in base64.
    "output_mime_type":"", // the mime type of the output wished, default: mime type of the input file
    "greyscale": false, //whether the image should be greyscaled 
    "quality": 80, // quality of the output (JPEG quality): number between 0-100. 
    "rotate": 45, // the amount to rotate the image. (rotates counterclock wise).
    "flip": {
        "horizontal": true, //whether the image should be flipped horizontally
        "vertical": false, //whether the image should be flipped vertically
    },
    "overlay":[{ //array containing the overlays
                //Overlay is either text or image. 
                //For text
                "text": "Watermark", // The overlay text
                "font_size": "", //font size in pixels
                "font_color":"", //currently either white or black
                //for image    
                "image": "", //URL or base64 or location/ similar to file.
                //For both text and image.
                "x": 25, //x position where the overlay should be placed
                "y": 40, //y position where the overlay should be placed.
                "rotation": 0,  // whether the overlay should be rotated.
    }],

    "crop":{ //If the image should be cropped.
        "x":0, //The x position where the cropping should start
        "y":0, // The y position where the cropping should start
        "width":200, // The width of the crop
        "height":200 // The height of the crop
    },

    //resizing
    "width": 200, //output image width, absolute
    "height":  200,  //ouptut image height, absolute
    "max_width": 300, // maximum output width allowed for the output image, will be rescaled if the width of the input image is greater. Will keep aspect ratio.
    "max_height": 300, // maximum output width allowed for the output image, will be rescaled if the width of the input image is greater. Will keep aspect ratio.
    "resize_method": "nearest_neighbour" //the method to use for resizing, optional
    //Available resize methods for Sharp:
    //          nearest_neighbour
    //          bicubic
    //          mitchell
    //          lanczos2
    //          lanczos3
    //Available resize methods for Jimp:
    //          nearest_neighbour
    //          bilinear
    //          bicubic
    //          hermite
    //          bezier
}

"output" object

This object should contain what the output encoding should be:

"output": {
    "output_encoding":"raw" //can be either raw or base64.
}

When the ouput_encoding is raw, the processed binary file will be returned back. When the output_encoding is base64 a JSON array wll be sent back with the following structure:

[
    {
        "initialHeight": 1079, //will contain the inital height of the image.
        "initialWidth": 1224, // the initial width of the image.
        "height": 1079, // the height of the output image (might be changed if resizing happens)
        "width": 1224, // the widht of the output image.
        "input_mime_type": "image/jpeg", //input mime type
        "input_extension": "jpg", //input extension
        "output_mime_type": "image/jpeg", // mime type of the output file
        "output_filename": "dog.jpeg", // the output file name provided
        "output_extension": "jpg", // extension of the output
        "output": "", //Will contain the base64 encoded output image
        "meta_data": { //This object will contain the meta data thats found in the input image and the attributes will vary depending on the input provided. 
            "bits_per_sample": "8",
            "image_height": "1079px",
            "image_width": "1224px",
            "color_components": "3",
            "subsampling": "YCbCr4:2:0 (2 2)",
            "documentid": "xmp.did:e855160a-a4da-8647-adbe-228545e4e525",
            "instanceid": "xmp.iid:e855160a-a4da-8647-adbe-228545e4e525",
            "originaldocumentid": "adobe:docid:photoshop:ad6929cc-b8b5-11d9-a342-ccefd3333069",
            "history": "action: saved; instanceID: xmp.iid:13769CA4BBB6E3119318908B2E34C886; when: 2014-03-28T14:04:20-07:00; softwareAgent: Adobe Photoshop CS6 (Windows); changed: /, action: converted; parameters: from image/jpeg to application/vnd.adobe.photoshop, action: derived; parameters: converted from image/jpeg to application/vnd.adobe.photoshop, action: saved; instanceID: xmp.iid:14769CA4BBB6E3119318908B2E34C886; when: 2014-03-28T14:04:20-07:00; softwareAgent: Adobe Photoshop CS6 (Windows); changed: /, action: saved; instanceID: xmp.iid:e855160a-a4da-8647-adbe-228545e4e525; when: 2014-04-16T16:59:57-07:00; softwareAgent: Adobe Illustrator CC (Windows); changed: /",
            "derivedfrom": "instanceID: xmp.iid:610c07d7-91e0-5c4e-a82e-011f8599aecd; documentID: xmp.did:610c07d7-91e0-5c4e-a82e-011f8599aecd; originalDocumentID: adobe:docid:photoshop:ad6929cc-b8b5-11d9-a342-ccefd3333069; renditionClass: proof:pdf",
            "renditionclass": "proof:pdf",
            "legacyiptcdigest": "00000000000000000000000000000001",
            "colormode": "1",
            "creatortool": "Adobe Illustrator CC (Windows)",
            "modifydate": "2014-04-17T00:00:05Z",
            "createdate": "2014-04-16T16:59:57-07:00",
            "metadatadate": "2014-04-16T16:59:57-07:00",
            "thumbnails": "",
            "format": "image/jpeg",
            "marked": "False",
            "imagewidth": "1500",
            "imagelength": "1239",
            "bitspersample": "8, 8, 8, 8",
            "photometricinterpretation": "1",
            "orientation": "Horizontal (normal)",
            "samplesperpixel": "4",
            "xresolution": "1500000/10000",
            "yresolution": "1500000/10000",
            "resolutionunit": "2",
            "exifversion": "0221",
            "colorspace": "65535",
            "pixelxdimension": "1500",
            "pixelydimension": "1239"
        }
    }
]

"version" attribute

This attribute will contain the version of AME JSON structure. This will be used for backwards compatibility by the AME server.

Server (only On-Premises)

Coming soon.

Troubleshooting

Checking the connection to AME Server

Testing from a command prompt

curl -X POST -H 'Content-Type: application/json' -d @test.json http://api.apexmediaextension.com/ > test.jpg

Note, if you are in windows environment you can download curl from https://curl.haxx.se/download.html#Win64)

Testing from a REST client

Instead of using curl you can also use a RESTClient like Postman. You will have to add the header 'Content-Type: application/json' and give the data from the test.json into the body section.

Testing from PL/SQL

select apex_web_service.make_rest_request('http://api.apexmediaextension.com/', 'GET') from dual

Testing from Oracle APEX

Go into APEX > SQL Workshop, and try to connect to the AOP server

select apex_web_service.make_rest_request('http://api.apexmediaextension.com/', 'GET') from dual

Error ORA-29273: HTTP request failed

If you receive error ORA-29273: HTTP request failed ORA-06512: at "SYS.UTL_HTTP", line 1130 ORA-24247: network access denied by access control list (ACL) it means that your APEX_XXXXXX schema has not the rights to connect to the APEX Media Extension server (http(s)://api.apexmediaextension.com for the Cloud version or your local URL in case of the on-premise version). The script to correct the issue can be found under the ACL issue section in the Oracle APEX documentation. E.g. for APEX 18.1, APEX 18.2, APEX 19.1.

Error ORA-29024: Certificate validation failure

If you receive error ORA-29273: HTTP request failed ORA-06512: at "SYS.UTL_HTTP", line 1130 ORA-29024: Certificate validation failure, you need to take into account the certificates. There're two ways to get around this:

Here's an example when in the plug-in you would specify a local address: http://apexrnd.localdomain/ame/

<VirtualHost *:80>
ServerName  apexrnd.localdomain
ServerAlias apexrnd.localdomain
RewriteEngine On
ProxyVia On
ProxyRequests Off
SSLProxyEngine On
ProxyPass        /aop/   https://api.apexmediaextension.com/
ProxyPassReverse /aop/   https://api.apexmediaextension.com/
</VirtualHost>

ORA-29273: HTTP request failed ORA-12535: TNS:operation timed out

Please check your firewall if it allows outgoing connection from the database to the AME server. If you added the AME port to the firewall rules, make sure to restart the daemon.

If you're using a proxy, make sure to specify the proxy in Shared Components > Application Definition Attributes > Proxy Server or specify the global variable in the AME_API_PKG.g_proxy_override.

Error occurred while acquiring license or out of credits error

You receive: "Error occurred while acquiring license. Please make sure that your API key is correct and that you have enough printing credits. Contact AME if the problem persists."

This means you ran out of credits. Go to https://www.apexmediaextension.com and upgrade your package or send an email to support@apexmediaextension.com to see what we can do for your case.

The requested URL has been prohibited

If in APEX you force all outgoing connections to be HTTPS by setting: Manage Instance -> Security -> HTTP Protocol -> Require Outbound HTTPS -> No.

make sure you're calling AME also with HTTPS. If you're calling the AME cloud https://api.apexmediaextension.com make sure to load the certificate in your database or setup a proxy on your end.

Debugging

When running the Client-side APEX Plug-in, turn APEX Debug on and check the debug logs.

When using the Server-side PL/SQL API, ame_api_pkg, you can enable debug by calling:

 ame_api_pkg.g_debug := 'Local';

AME will now provide the JSON that is being send to the AME server in a global variable g_debug_json. Check this JSON or send this JSON to support@apexmediaextension.com to get help for your specific case.

Deinstallation

  1. For on-premises versions of AME: Remove server component.

    Stop the AME executable. Delete the server folder and its contents from your server.

  2. Remove the AME plug-ins from all applications.

In an application with AME plug-ins installed, navigate to Shared Components -> Plug-ins. For any of the plug-ins you have installed, APEX Media Extension (AME), remove all references to the plug-in from your application. Click the number in the References column of the report to view specific instances. Once the number of references is zero, you can delete the plug-in itself by opening the plug-in and clicking the Delete button.

  1. Optional: If installed, uninstall AOP Sample Application.

    In the APEX workspace where the sample application is installed, navigate to the Application Builder and select the AME Sample Application. In the right-hand sidebar under Tasks, click Delete this Application When prompted, under Deinstallation Options, check the boxes for both Remove Application Definition and Deinstall Supporting Objects. Then, click Deinstall. This will remove all AME related database objects as well, so you can skip Step 5.

  2. Remove AME Database Objects (If not done in Step 3).

Locate the install package used to install AME or downloaded from https://www.apexmediaextension.com

From SQL window: run ame_db_deinstall.sql which is located in the "db"-directory of the unzipped install package.

Or from APEX: navigate to SQL Workshop -> SQL Scripts -> Upload. Select ame_db_deinstall.sql which is located in the "db"-directory of the unzipped install package, give it a name and click the Upload button. Click the run icon for the script you just uploaded, confirm that the schema in the upper right-hand corner of the screen is correct and click Run Now. Some statements may fail depending on what objects were installed.

Tutorials

Coming soon.

FAQ

This section will be updated based on your feedback.

Copyright © 2015-2020, APEX R&D

All rights reserved.

Authors: Dimitri Gielis, Sunil Tandan, and Jackie McIlroy

This software and related documentation are provided under a license agreement containing restrictions on use and disclosure that are protected by intellectual property laws. Except as expressly permitted in your license agreement or allowed by law, you may not use, copy, reproduce, translate, broadcast, modify, license, transmit, distribute, exhibit, perform, publish, or display any part, in any form, or by any means. Reverse engineering, disassembly, or de-compilation of this software, unless required by law for interoperability, is prohibited. The information contained herein is subject to change without notice and is not warranted to be error-free. If you find any errors, please report them to us in writing.