300, 'max_height' => 500, 'wm_filename' => 'inc/wm.png', 'h_margin' => 'c', 'v_margin' => -20) */ function parseFormat($format) { $res = Array (); $format_parts = explode(';', $format); foreach ($format_parts as $format_part) { if (preg_match('/resize:(\d*)x(\d*)/', $format_part, $regs)) { $res['max_width'] = $regs[1]; $res['max_height'] = $regs[2]; } elseif (preg_match('/wm:([^\|]*)\|([^\|]*)\|([^\|]*)/', $format_part, $regs)) { $res['wm_filename'] = FULL_PATH.THEMES_PATH.'/'.$regs[1]; $res['h_margin'] = $regs[2]; $res['v_margin'] = $regs[3]; } elseif ($format_part == 'img_size' || $format_part == 'img_sizes') { $res['image_size'] = true; } } return $res; } /** * Resized given image to required dimensions & saves resized image to "resized" subfolder in source image folder * * @param string $src_image full path to image (on server) * @param mixed $max_width maximal allowed resized image width or false if no limit * @param mixed $max_height maximal allowed resized image height or false if no limit * @return string direct url to resized image */ function ResizeImage($src_image, $max_width, $max_height = null) { $image_size = false; if(isset($max_height)) { $params['max_height'] = $max_height; $params['max_width'] = $max_width; } else { $params = $this->parseFormat($max_width); if (array_key_exists('image_size', $params)) { // image_size param shouldn't affect resized file name (crc part) $image_size = $params['image_size']; unset($params['image_size']); } } if ($params['max_width'] > 0 || $params['max_height'] > 0) { list ($params['max_width'], $params['max_height'], $needs_resize) = $this->GetImageDimensions($src_image, $params['max_width'], $params['max_height']); $src_path = dirname($src_image); if ($needs_resize || array_key_exists('wm_filename', $params) && $params['wm_filename']) { // resize required OR watermarking required -> change resulting image name ! $dst_image = preg_replace('/^'.preg_quote($src_path, '/').'(.*)\.(.*)$/', $src_path . DIRECTORY_SEPARATOR . 'resized\\1_' . crc32(serialize($params)) . '.\\2', $src_image); if (!file_exists($dst_image) || filemtime($src_image) > filemtime($dst_image)) { // resized image not available OR should be recreated due source image change $params['dst_image'] = $dst_image; $image_resized = $this->ScaleImage($src_image, $params); if (!$image_resized) { // resize failed, because of server error $dst_image = $src_image; } } // resize/watermarking ok $src_image = $dst_image; } } if ($image_size) { // return only image size (resized or not) $image_info = $this->getImageInfo($src_image); return $image_info ? $image_info[3] : ''; } $base_url = rtrim($this->Application->BaseURL(), '/'); return str_replace(DIRECTORY_SEPARATOR, '/', preg_replace('/^'.preg_quote(FULL_PATH, '/').'(.*)/', $base_url.'\\1', $src_image)); } /** * Proportionally resizes given image to destination dimensions * * @param string $src_image full path to source image (already existing) * @param string $dst_image full path to destination image (will be created) * @param int $dst_width destination image width (in pixels) * @param int $dst_height destination image height (in pixels) */ function ScaleImage($src_image, $params) { $image_info = $this->getImageInfo($src_image); if (!$image_info) { return false; } /* list ($params['max_width'], $params['max_height'], $resized) = $this->GetImageDimensions($src_image, $params['max_width'], $params['max_height']); if (!$resized) { // image dimensions are smaller or equals to required dimensions return false; }*/ if (!$this->Application->ConfigValue('ForceImageMagickResize') && function_exists('imagecreatefromjpeg')) { // try to resize using GD $resize_map = Array ( 'image/jpeg' => 'imagecreatefromjpeg:imagejpeg:jpg', 'image/gif' => 'imagecreatefromgif:imagegif:gif', 'image/png' => 'imagecreatefrompng:imagepng:png', ); $mime_type = $image_info['mime']; if (!isset($resize_map[$mime_type])) { return false; } list ($read_function, $write_function, $file_extension) = explode(':', $resize_map[$mime_type]); $src_image_rs = @$read_function($src_image); if ($src_image_rs) { $dst_image_rs = imagecreatetruecolor($params['max_width'], $params['max_height']); if ($file_extension == 'png') { // preserve transparency of PNG images $transparent_color = imagecolorallocate($dst_image_rs, 0, 0, 0); imagecolortransparent($dst_image_rs, $transparent_color); } imagecopyresampled($dst_image_rs, $src_image_rs, 0, 0, 0, 0, $params['max_width'], $params['max_height'], $image_info[0], $image_info[1]); if(array_key_exists('wm_filename', $params) && $params['wm_filename'] && file_exists($params['wm_filename'])) { $logo_img = imagecreatefrompng($params['wm_filename']); list($logo_width, $logo_height) = getimagesize($params['wm_filename']); //if(($params['max_width'] > $logo_width * 2) && ($params['max_height'] > $logo_height * 2)) //{ imagealphablending($dst_image_rs, true); //imagecopy($dst_image_rs, $logo_img, $params['max_width'] - $logo_width - $right_margin, $params['max_height'] - $logo_height - $bottom_margin, 0, 0, $logo_width, $logo_height); if ($params['h_margin'] == 'c') { $x_position = round($params['max_width']/2 - $logo_width/2); } elseif ($params['h_margin'] >= 0) { $x_position = $params['h_margin']; } else { $x_position = $params['max_width'] - (-$params['h_margin'] + $logo_width); } if ($params['v_margin'] == 'c') { $y_position = round($params['max_height']/2 - $logo_height/2); } elseif ($params['v_margin'] >= 0) { $y_position = $params['v_margin']; } else { $y_position = $params['max_height'] - (-$params['v_margin'] + $logo_height); } imagecopy($dst_image_rs, $logo_img, $x_position, $y_position, 0, 0, $logo_width, $logo_height); //} } return @$write_function($dst_image_rs, $params['dst_image'], 100); } } else { // try to resize using ImageMagick exec('/usr/bin/convert '.$src_image.' -resize '.$params['max_width'].'x'.$params['max_height'].' '.$params['dst_image'], $shell_output, $exec_status); return $exec_status == 0; } return false; } /** * Returns destination image size without actual resizing (useful for HTML tag) * * @param string $src_image full path to source image (already existing) * @param int $dst_width destination image width (in pixels) * @param int $dst_height destination image height (in pixels) * @return Array resized image dimensions (0 - width, 1 - height) */ function GetImageDimensions($src_image, $dst_width, $dst_height) { $image_info = $this->getImageInfo($src_image); if (!$image_info) { return false; } $orig_width = $image_info[0]; $orig_height = $image_info[1]; $too_large = is_numeric($dst_width) ? ($orig_width > $dst_width) : false; $too_large = $too_large || (is_numeric($dst_height) ? ($orig_height > $dst_height) : false); if ($too_large) { $width_ratio = $dst_width ? $dst_width / $orig_width : 1; $height_ratio = $dst_height ? $dst_height / $orig_height : 1; $ratio = min($width_ratio, $height_ratio); $width = ceil($orig_width * $ratio); $height = ceil($orig_height * $ratio); } else { $width = $orig_width; $height = $orig_height; } return Array ($width, $height, $too_large); } /** * Returns image dimensions + checks if given file is existing image * * @param string $src_image full path to source image (already existing) * @return mixed */ function getImageInfo($src_image) { if (!file_exists($src_image)) { return false; } $image_info = @getimagesize($src_image); if (!$image_info) { trigger_error('Image '.$src_image.' missing or invalid', E_USER_WARNING); return false; } return $image_info; } /** * Returns maximal image size (width & height) among fields specified * * @param kDBItem $object * @param string $fields * @param string $format any format, that returns full url (e.g. files_resized:WxH, resize:WxH, full_url, full_urls) * @return string */ function MaxImageSize(&$object, $fields, $format = null) { static $cached_sizes = Array (); $cache_key = $object->getPrefixSpecial().'_'.$object->GetID(); if (!isset($cached_sizes[$cache_key])) { $images = Array (); $fields = explode(',', $fields); foreach ($fields as $field) { $image_data = $object->GetField($field, $format); if (!$image_data) { continue; } $images = array_merge($images, explode('|', $image_data)); } $max_width = 0; $max_height = 0; $base_url = rtrim($this->Application->BaseURL(), '/'); foreach ($images as $image_url) { $image_path = preg_replace('/^'.preg_quote($base_url, '/').'(.*)/', FULL_PATH.'\\1', $image_url); $image_info = $this->getImageInfo($image_path); $max_width = max($max_width, $image_info[0]); $max_height = max($max_height, $image_info[1]); } $cached_sizes[$cache_key] = Array ($max_width, $max_height); } return $cached_sizes[$cache_key]; } /** * Puts existing item images (from subitem) to virtual fields (in main item) * * @param kCatDBItem $object */ function LoadItemImages(&$object) { if (!$this->Application->prefixRegistred($object->Prefix.'-img')) { return ; } $max_image_count = $this->Application->ConfigValue($object->Prefix.'_MaxImageCount'); $sql = 'SELECT * FROM '.TABLE_PREFIX.'Images WHERE ResourceId = '.$object->GetDBField('ResourceId').' ORDER BY ImageId ASC LIMIT 0, '.(int)$max_image_count; $item_images = $this->Conn->Query($sql); $image_counter = 1; foreach ($item_images as $item_image) { $image_path = $item_image['ThumbPath']; if ($item_image['DefaultImg'] == 1 || $item_image['Name'] == 'main') { // process primary image separately if (array_key_exists('PrimaryImage', $object->Fields)) { $object->SetDBField('PrimaryImage', $image_path); $object->SetOriginalField('PrimaryImage', $image_path); $object->Fields['PrimaryImage']['original_field'] = $item_image['Name']; } continue; } if (array_key_exists('Image'.$image_counter, $object->Fields)) { $object->SetDBField('Image'.$image_counter, $image_path); $object->SetOriginalField('Image'.$image_counter, $image_path); $object->Fields['Image'.$image_counter]['original_field'] = $item_image['Name']; } $image_counter++; } } /** * Saves newly uploaded images to external image table * * @param kCatDBItem $object */ function SaveItemImages(&$object) { if (!$this->Application->prefixRegistred($object->Prefix.'-img')) { return ; } $table_name = $this->Application->getUnitOption('img', 'TableName'); $max_image_count = $this->Application->getUnitOption($object->Prefix, 'ImageCount'); // $this->Application->ConfigValue($object->Prefix.'_MaxImageCount'); $i = 0; while ($i < $max_image_count) { $field = $i ? 'Image'.$i : 'PrimaryImage'; $field_options = $object->GetFieldOptions($field); $image_src = $object->GetDBField($field); if ($image_src) { if (isset($field_options['original_field'])) { $key_clause = 'Name = '.$this->Conn->qstr($field_options['original_field']).' AND ResourceId = '.$object->GetDBField('ResourceId'); if ($object->GetDBField('Delete'.$field)) { // if item was cloned, then new filename is in db (not in $image_src) $sql = 'SELECT ThumbPath FROM '.$table_name.' WHERE '.$key_clause; $image_src = $this->Conn->GetOne($sql); if (@unlink(FULL_PATH.$image_src)) { $sql = 'DELETE FROM '.$table_name.' WHERE '.$key_clause; $this->Conn->Query($sql); } } else { // image record found -> update $fields_hash = Array ( 'ThumbPath' => $image_src, ); $this->Conn->doUpdate($fields_hash, $table_name, $key_clause); } } else { // image record not found -> create $fields_hash = Array ( 'ResourceId' => $object->GetDBField('ResourceId'), 'Name' => $field, 'AltName' => $field, 'Enabled' => STATUS_ACTIVE, 'DefaultImg' => $i ? 0 : 1, // first image is primary, others not primary 'ThumbPath' => $image_src, ); $this->Conn->doInsert($fields_hash, $table_name); $field_options['original_field'] = $field; $object->SetFieldOptions($field, $field_options); } } $i++; } } } ?>