liberty
[ class tree: liberty ] [ index: liberty ] [ all elements ]

Source for file mime.image.php

Documentation is available at mime.image.php

  1. <?php
  2. /**
  3.  * @version        $Header$
  4.  *
  5.  * @author        xing  <xing@synapse.plus.com>
  6.  * @version        $Revision$
  7.  *  created        Thursday May 08, 2008
  8.  * @package        liberty
  9.  * @subpackage    liberty_mime_handler
  10.  ***/
  11.  
  12. /**
  13.  * setup
  14.  */
  15. global $gLibertySystem$gBitSystem;
  16.  
  17. /**
  18.  *  This is the name of the plugin - max char length is 16
  19.  * As a naming convention, the liberty mime handler definition should start with:
  20.  * PLUGIN_MIME_GUID_
  21.  */
  22. define'PLUGIN_MIME_GUID_IMAGE''mimeimage' );
  23.  
  24. $pluginParams array (
  25.     // Set of functions and what they are called in this paricular plugin
  26.     // Use the GUID as your namespace
  27.     'verify_function'     => 'mime_default_verify',
  28.     'store_function'      => 'mime_image_store',
  29.     'update_function'     => 'mime_image_update',
  30.     'load_function'       => 'mime_image_load',
  31.     'download_function'   => 'mime_default_download',
  32.     'expunge_function'    => 'mime_default_expunge',
  33.     'help_function'       => 'mime_image_help',
  34.     // Brief description of what the plugin does
  35.     'title'               => 'Advanced Image Processing',
  36.     'description'         => 'Extract image meta data and display relevant information to the user and pick individual display options for images.',
  37.     // Templates to display the files
  38.     'view_tpl'            => 'bitpackage:liberty/mime/image/view.tpl',
  39.     'attachment_tpl'      => 'bitpackage:liberty/mime/image/attachment.tpl',
  40.     // url to page with options for this plugin
  41.     'plugin_settings_url' => LIBERTY_PKG_URL.'admin/plugins/mime_image.php',
  42.     // This needs to be specified by plugins that are included by other plugins
  43.     'file_name'          => 'mime.image.php',
  44.     // This should be the same for all mime plugins
  45.     'plugin_type'         => MIME_PLUGIN,
  46.     // Set this to TRUE if you want the plugin active right after installation
  47.     'auto_activate'       => FALSE,
  48.     // Help page on bitweaver.org
  49.     //'help_page'           => 'LibertyMime+Image+Plugin',
  50.     // this should pick up all image
  51.     'mimetypes'           => array(
  52.         '#image/.*#i',
  53.     ),
  54. );
  55. // currently, there's only one option in the image edit file - panorama image setting
  56. if$gBitSystem->isFeatureActive'mime_image_panoramas' )) {
  57.     $pluginParams['edit_tpl'=  'bitpackage:liberty/mime/image/edit.tpl';
  58. }
  59. $gLibertySystem->registerPluginPLUGIN_MIME_GUID_IMAGE$pluginParams );
  60.  
  61. /**
  62.  * Store the data in the database
  63.  *
  64.  * @param array $pStoreRow File data needed to store details in the database - sanitised and generated in the verify function
  65.  * @access public
  66.  * @return TRUE on success, FALSE on failure - $pStoreRow[errors] will contain reason
  67.  */
  68. function mime_image_store&$pStoreRow {
  69.     // this will set the correct pluign guid, even if we let default handle the store process
  70.     $pStoreRow['attachment_plugin_guid'PLUGIN_MIME_GUID_IMAGE;
  71.     $pStoreRow['log'array();
  72.  
  73.     // if storing works, we process the image
  74.     if$ret mime_default_store$pStoreRow )) {
  75.         if!mime_image_store_exif_data$pStoreRow )) {
  76.             // if it all goes tits up, we'll know why
  77.             $pStoreRow['errors'$pStoreRow['log'];
  78.             $ret FALSE;
  79.         }
  80.     }
  81.     return $ret;
  82. }
  83.  
  84. /**
  85.  * mime_image_update update file information in the database if there were changes.
  86.  *
  87.  * @param array $pStoreRow File data needed to update details in the database
  88.  * @access public
  89.  * @return TRUE on success, FALSE on failure - $pStoreRow[errors] will contain reason
  90.  */
  91. function mime_image_update&$pStoreRow$pParams NULL {
  92.     global $gThumbSizes$gBitSystem;
  93.  
  94.     $ret TRUE;
  95.  
  96.     // this will set the correct pluign guid, even if we let default handle the store process
  97.     $pStoreRow['attachment_plugin_guid'PLUGIN_MIME_GUID_IMAGE;
  98.  
  99.     // if storing works, we process the image
  100.     if!empty$pStoreRow['upload'&& $ret mime_default_update$pStoreRow )) {
  101.         if!mime_image_store_exif_data$pStoreRow )) {
  102.             // if it all goes tits up, we'll know why
  103.             $pStoreRow['errors'$pStoreRow['log'];
  104.             $ret FALSE;
  105.         }
  106.     elseif$gBitSystem->isFeatureActive'mime_image_panoramas' && !empty$pParams['preference']['is_panorama'&& empty$pStoreRow['thumbnail_url']['panorama')) {
  107.         if!mime_image_create_panorama$pStoreRow )) {
  108.             $ret FALSE;
  109.         }
  110.     elseifempty$pParams['preference']['is_panorama'&& !empty$pStoreRow['thumbnail_url']['panorama')) {
  111.         // we remove the panorama setting in the database and the panorama thumb
  112.         ifLibertyAttachable::validateStoragePathSTORAGE_PKG_PATH.$pStoreRow['thumbnail_url']['panorama')) {
  113.             @unlinkSTORAGE_PKG_PATH.$pStoreRow['thumbnail_url']['panorama');
  114.         }
  115.     }
  116.  
  117.     return $ret;
  118. }
  119.  
  120. /**
  121.  * Load file data from the database
  122.  *
  123.  * @param array $pFileHash Contains all file information
  124.  * @param array $pPrefs Attachment preferences taken liberty_attachment_prefs
  125.  * @param array $pParams Parameters for loading the plugin - e.g.: might contain values such as thumbnail size from the view page
  126.  * @access public
  127.  * @return TRUE on success, FALSE on failure - $pStoreRow[errors] will contain reason
  128.  */
  129. function mime_image_load&$pFileHash&$pPrefs$pParams NULL {
  130.     global $gBitSystem;
  131.     // don't load a mime image if we don't have an image for this file
  132.     if$ret mime_default_load$pFileHash$pPrefs$pParams )) {
  133.         // fetch meta data from the db
  134.         $ret['meta'LibertyMime::getMetaData$ret['attachment_id']"EXIF" );
  135.  
  136.         // if we have GPS data and geo is active, we calculate geo stuff
  137.         if$gBitSystem->isPackageActive'geo' && $ret['gps'LibertyMime::getMetaData$ret['attachment_id']"GPS" ))) {
  138.             // longitude
  139.             if!empty$ret['gps']['gpslongitude')) {
  140.                 $ret['geo']['lng'$ret['gps']['gpslongitude'];
  141.                 if!empty$ret['gps']['gpslongituderef'&& $ret['gps']['gpslongituderef'== 'W' {
  142.                     $ret['geo']['lng'$ret['geo']['lng'];
  143.                 }
  144.             }
  145.             // latitude
  146.             if!empty$ret['gps']['gpslatitude')) {
  147.                 $ret['geo']['lat'$ret['gps']['gpslatitude'];
  148.                 if!empty$ret['gps']['gpslatituderef'&& $ret['gps']['gpslatituderef'== 'S' {
  149.                     $ret['geo']['lat'$ret['geo']['lat'];
  150.                 }
  151.             }
  152.             // set sea level data when available
  153.             if!empty$ret['gps']['gpsaltitude')) {
  154.                 list$dividend$divisor explode"/"$ret['gps']['gpsaltitude');
  155.                 $ret['geo']['amsl'$dividend $divisor;
  156.                 $ret['geo']['amsl_unit''m';
  157.             }
  158.  
  159.             // final check to see if we have enough data
  160.             ifempty$ret['geo']['lng'|| empty$ret['geo']['lat')) {
  161.                 unset$ret['geo');
  162.             }
  163.         }
  164.  
  165.         // check for panorama image
  166.         ifisset$ret['source_file'&& is_filedirname$ret['source_file')."/thumbs/panorama.jpg" )) {
  167.             // if the panorama doesn't have 180⁰ vertical field of view we will restrict up / down movement
  168.             if(( $ret['pano'LibertyMime::getMetaData$ret['attachment_id']"PANO" )) && !empty$ret['pano']['aspect')) {
  169.                 // calculation based on logarythmic regression curve
  170.                 $ret['pano']['pa'round40 31 log$ret['pano']['aspect'1.4 ));
  171.                 if$ret['pano']['pa'49 {
  172.                     $ret['pano']['pa'90;
  173.                 elseif$ret['pano']['pa'{
  174.                     $ret['pano']['pa'0;
  175.                 }
  176.             }
  177.             $ret['thumbnail_url']['panorama'storage_path_to_urldirname$ret['source_file')."/thumbs/panorama.jpg" );
  178.         }
  179.     }
  180.     return $ret;
  181. }
  182.  
  183. /**
  184.  * mime_image_store_exif_data Process a JPEG and store its EXIF data as meta data.
  185.  *
  186.  * @param array $pFileHash file details.
  187.  * @param array $pFileHash[upload] should contain a complete hash from $_FILES
  188.  * @access public
  189.  * @return TRUE on success, FALSE on failure
  190.  */
  191. function mime_image_store_exif_data$pFileHash {
  192.     global $gBitSystem;
  193.     if!empty$pFileHash['upload')) {
  194.         $upload &$pFileHash['upload'];
  195.     }
  196.  
  197.     if@BitBase::verifyId$pFileHash['attachment_id'&& $exifHash mime_image_get_exif_data$upload ) ) {
  198.         // only makes sense to store the GPS data if we at least have latitude and longitude
  199.         if!empty$exifHash['GPS')) {
  200.             LibertyMime::storeMetaData$pFileHash['attachment_id']'GPS'$exifHash['GPS');
  201.         }
  202.  
  203.         if!empty$exifHash['EXIF')) {
  204. //            LibertyMime::storeMetaData( $pFileHash['attachment_id'], 'EXIF', $exifHash['EXIF'] );
  205.         }
  206.     }
  207.  
  208.     return TRUE;
  209. }
  210.  
  211. /**
  212.  * mime_image_get_exif_data fetch meta data from uploaded image
  213.  *
  214.  * @param array $pUpload uploaded file data
  215.  * @access public
  216.  * @return array filled with exif goodies
  217.  */
  218. function mime_image_get_exif_data$pUpload {
  219.     $exifHash array();
  220.     iffunction_exists'exif_read_data' && !empty$pUpload['source_file'&& is_file$pUpload['source_file'&& preg_match"#/(jpe?g|tiff)#i"$pUpload['type')) {
  221.         // exif_read_data can be noisy due to crappy files, e.g. "Incorrect APP1 Exif Identifier Code" etc...
  222.         $exifHash @exif_read_data$pUpload['source_file']0TRUE );
  223.  
  224.         // extract more information if we can find it
  225.         ifini_get'short_open_tag' )) {
  226.             require_once UTIL_PKG_PATH.'jpeg_metadata_tk/JPEG.php';
  227.             require_once UTIL_PKG_PATH.'jpeg_metadata_tk/JFIF.php';
  228.             require_once UTIL_PKG_PATH.'jpeg_metadata_tk/PictureInfo.php';
  229.             require_once UTIL_PKG_PATH.'jpeg_metadata_tk/XMP.php';
  230.             require_once UTIL_PKG_PATH.'jpeg_metadata_tk/EXIF.php';
  231.  
  232.             // Retrieve the header information from the JPEG file
  233.             $jpeg_header_data get_jpeg_header_data$pUpload['source_file');
  234.  
  235.             // Retrieve EXIF information from the JPEG file
  236.             $Exif_array get_EXIF_JPEG$pUpload['source_file');
  237.  
  238.             // Retrieve XMP information from the JPEG file
  239.             $XMP_array read_XMP_array_from_textget_XMP_text$jpeg_header_data ) );
  240.  
  241.             // Retrieve Photoshop IRB information from the JPEG file
  242.             $IRB_array get_Photoshop_IRB$jpeg_header_data );
  243.             if!empty$exifHash['IFD0']['Software'&& preg_match'/photoshop/i'$exifHash['IFD0']['Software') ) {
  244.                 require_once UTIL_PKG_PATH.'jpeg_metadata_tk/Photoshop_File_Info.php';
  245.                 // Retrieve Photoshop File Info from the three previous arrays
  246.                 $psFileInfo get_photoshop_file_info$Exif_array$XMP_array$IRB_array );
  247.  
  248.                 if!empty$psFileInfo['headline') ) {
  249.                     $exifHash['headline'$psFileInfo['headline'];
  250.                 }
  251.  
  252.                 if!empty$psFileInfo['caption') ) {
  253.                     $exifHash['caption'$psFileInfo['caption'];
  254.                 }
  255.             }
  256.         }
  257.  
  258.         // only makes sense to store the GPS data if we at least have latitude and longitude
  259.         if!empty$exifHash['GPS')) {
  260.             // store GPS coordinates as deg decimal float
  261.             $gpsConv array'GPSLatitude''GPSDestLatitude''GPSLongitude''GPSDestLongitude' );
  262.             foreach$gpsConv as $conv {
  263.                 if!empty$exifHash['GPS'][$conv&& is_array$exifHash['GPS'][$conv)) {
  264.                     $exifHash['GPS'][$convmime_image_convert_exifgps$exifHash['GPS'][$conv);
  265.                 }
  266.             }
  267.         }
  268.     }
  269.  
  270.     return $exifHash;
  271. }
  272.  
  273. /**
  274.  * mime_image_convert_exifgps GPS EIXF data is stored as fractions in an array. here we convert this to a degree decimal float value for easy storing
  275.  *
  276.  * @param array $pParams array of positional data in fractions form EXIF tag
  277.  * @access public
  278.  * @return numeric value of positional data
  279.  */
  280. function mime_image_convert_exifgps$pParams {
  281.     $ret 0;
  282.     if!empty$pParams && is_array$pParams && count$pParams == {
  283.         list$lng['deg']$lng['min']$lng['sec'array_values$pParams );
  284.         foreach$lng as $key => $fraction {
  285.             list$dividend$divisor explode"/"$fraction );
  286.             $num $dividend $divisor;
  287.             if$key == 'min' {
  288.                 $num $num 60;
  289.             elseif$key == 'sec' {
  290.                 $num $num 3600;
  291.             }
  292.             $ret += $num;
  293.         }
  294.     }
  295.     return $ret;
  296. }
  297.  
  298. /**
  299.  * mime_image_create_panorama
  300.  *
  301.  * @param array $pStoreRow 
  302.  * @access public
  303.  * @return TRUE on success, FALSE on failure - mErrors will contain reason for failure
  304.  */
  305. function mime_image_create_panorama&$pStoreRow {
  306.     global $gBitSystem$gThumbSizes;
  307.     // we know the panorama image will be a jpeg, so we don't need the canThumbFunc check here
  308.     if(( $panoramaFunc liberty_get_function'panorama' )) && !empty$pStoreRow['source_file'&& is_file$pStoreRow['source_file')) {
  309.         // the panorama has to be a jpg
  310.         $gBitSystem->setConfig'liberty_thumbnail_format''jpg' );
  311.         $width $gBitSystem->getConfig'mime_image_panorama_width'3000 );
  312.         $gThumbSizes['panorama'array$width$width );
  313.  
  314.         // for the panorama, we will force a quality lower than 75 to reduce image size
  315.         if$gBitSystem->getConfig'liberty_thumbnail_quality'85 75 {
  316.             $gBitSystem->setConfig'liberty_thumbnail_quality'75 );
  317.         }
  318.  
  319.         $genHash array(
  320.             'attachment_id'   => $pStoreRow['attachment_id'],
  321.             'dest_branch'      => liberty_mime_get_storage_brancharray'sub_dir' => $pStoreRow['attachment_id']'user_id' =>$pStoreRow['user_id']'package' => liberty_mime_get_storage_sub_dir_name$pStoreRow ) ) ),
  322.             'file_name'       => dirname$pStoreRow['file_name')."/",
  323.             'source_file'     => $pStoreRow['source_file'],
  324.             'type'            => $pStoreRow['mime_type'],
  325.             'thumbnail_sizes' => array'panorama' ),
  326.         );
  327.         ifliberty_generate_thumbnails$genHash )) {
  328.             // we want to modify the panorama
  329.             $genHash['source_file'$genHash['icon_thumb_path'];
  330.             if!$panoramaFunc$genHash )) {
  331.                 $pStoreRow['errors']['panorama'$genHash['error'];
  332.             }
  333.         }
  334.  
  335.         returnempty$pStoreRow['errors'));
  336.     }
  337. }
  338.  
  339. /**
  340.  * liberty_magickwand_panorama_image - strictly speaking, this belongs in one of the image processing plugin files, but we'll leave it here for the moment
  341.  *
  342.  * @param array $pFileHash File hash - souce_file is required
  343.  * @param array $pOptions 
  344.  * @access public
  345.  * @return TRUE on success, FALSE on failure - mErrors will contain reason for failure
  346.  */
  347. function liberty_magickwand_panorama_image&$pFileHash$pOptions array() ) {
  348.     $magickWand NewMagickWand();
  349.     $pFileHash['error'NULL;
  350.     if!empty$pFileHash['source_file'&& is_file$pFileHash['source_file')) {
  351.         if!$pFileHash['error'liberty_magickwand_check_errorMagickReadImage$magickWand$pFileHash['source_file')$magickWand )) {
  352.             // calculate border width
  353.             $iwidth  roundMagickGetImageWidth$magickWand ));
  354.             $iheight roundMagickGetImageHeight$magickWand ));
  355.             $aspect  $iwidth $iheight;
  356.             $metaHash array(
  357.                 'width'  => $iwidth,
  358.                 'height' => $iheight,
  359.                 'aspect' => $aspect,
  360.             );
  361.             // store original file information that we can adjust the viewer
  362.             LibertyMime::storeMetaData$pFileHash['attachment_id']'PANO'$metaHash );
  363.             // we need to pad the image if the aspect ratio is not 2:1 (give it a wee bit of leeway that we don't add annoying borders if not really needed)
  364.             if$aspect 2.1 || $aspect 1.9 {
  365.                 $bwidth $bheight 0;
  366.                 if$aspect {
  367.                     $bheight round((( $iwidth $iheight );
  368.                 else {
  369.                     $bwidth round((( $iheight $iwidth );
  370.                 }
  371.                 // if the ratio has nothing to do with a panorama image - i.e. gives us a negative number here, we won't generate a panorama image
  372.                 if$bheight {
  373.                     $pixelWand NewPixelWand();
  374.                     PixelSetColor$pixelWand!empty$pOptions['background'$pOptions['background''black' ));
  375.                     if!$pFileHash['error'liberty_magickwand_check_errorMagickBorderImage$magickWand$pixelWand$bwidth$bheight )$magickWand )) {
  376.                         if!$pFileHash['error'liberty_magickwand_check_errorMagickWriteImage$magickWand$pFileHash['source_file')$magickWand )) {
  377.                             // yay!
  378.                         }
  379.                     }
  380.                     DestroyPixelWand$pixelWand );
  381.                 }
  382.             }
  383.         }
  384.     }
  385.     DestroyMagickWand$magickWand );
  386.     returnempty$pFileHash['error'));
  387. }
  388.  
  389. /**
  390.  * mime_image_help
  391.  *
  392.  * @access public
  393.  * @return string 
  394.  */
  395. function mime_image_help({
  396.     $help =
  397.         tra"If you have a panoramic image and you are using <strong>{attachment}</strong> to insert it, you can use <strong>panosize</strong> as you would with the size parameter to specify the size." )."<br />"
  398.         .tra"Example:" ).' '."{attachment id='13' panosize='small'}";
  399.     return $help;
  400. }
  401. ?>

Documentation generated on Wed, 29 Jul 2015 13:57:07 +0000 by phpDocumentor 1.5.0-lsces