mirror of
https://github.com/Lastorder-DC/rhymix.git
synced 2026-01-04 17:21:39 +09:00
Implement auto-rotation of uploaded images
This commit is contained in:
parent
f3761fd934
commit
8c242327a8
7 changed files with 141 additions and 61 deletions
|
|
@ -480,9 +480,10 @@ class FileHandler
|
|||
* @param string $target_type If $target_type is set (gif, jpg, png, bmp), result image will be saved as target type
|
||||
* @param string $thumbnail_type Thumbnail type(crop, ratio)
|
||||
* @param int $quality Compression ratio (0~9)
|
||||
* @param int $rotate Rotation degrees (0~360)
|
||||
* @return bool TRUE: success, FALSE: failed
|
||||
*/
|
||||
public static function createImageFile($source_file, $target_file, $resize_width = 0, $resize_height = 0, $target_type = '', $thumbnail_type = 'crop', $quality = 100)
|
||||
public static function createImageFile($source_file, $target_file, $resize_width = 0, $resize_height = 0, $target_type = '', $thumbnail_type = 'crop', $quality = 100, $rotate = 0)
|
||||
{
|
||||
// check params
|
||||
if (($source_file = self::exists($source_file)) === FALSE)
|
||||
|
|
@ -544,49 +545,6 @@ class FileHandler
|
|||
}
|
||||
$target_type = strtolower($target_type);
|
||||
|
||||
// if original image is larger than specified size to resize, calculate the ratio
|
||||
$width_per = ($resize_width > 0 && $width >= $resize_width) ? $resize_width / $width : 1;
|
||||
$height_per = ($resize_height > 0 && $height >= $resize_height) ? $resize_height / $height : 1;
|
||||
|
||||
$per = NULL;
|
||||
if($thumbnail_type == 'ratio')
|
||||
{
|
||||
$per = ($width_per > $height_per) ? $height_per : $width_per;
|
||||
$resize_width = $width * $per;
|
||||
$resize_height = $height * $per;
|
||||
}
|
||||
else
|
||||
{
|
||||
$per = ($width_per < $height_per) ? $height_per : $width_per;
|
||||
}
|
||||
|
||||
// create temporary image with target size
|
||||
$thumb = NULL;
|
||||
if(function_exists('imagecreateTRUEcolor'))
|
||||
{
|
||||
$thumb = imagecreateTRUEcolor($resize_width, $resize_height);
|
||||
}
|
||||
else if(function_exists('imagecreate'))
|
||||
{
|
||||
$thumb = imagecreate($resize_width, $resize_height);
|
||||
}
|
||||
|
||||
if(!$thumb)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if($target_type == 'png' && function_exists('imagecolorallocatealpha') && function_exists('imagesavealpha') && function_exists('imagealphablending'))
|
||||
{
|
||||
imagefill($thumb, 0, 0, imagecolorallocatealpha($thumb, 0, 0, 0, 127));
|
||||
imagesavealpha($thumb, TRUE);
|
||||
imagealphablending($thumb, TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
imagefilledrectangle($thumb, 0, 0, $resize_width - 1, $resize_height - 1, imagecolorallocate($thumb, 255, 255, 255));
|
||||
}
|
||||
|
||||
// create temporary image having original type
|
||||
$source = NULL;
|
||||
switch($type)
|
||||
|
|
@ -636,27 +594,86 @@ class FileHandler
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
// resize original image and put it into temporary image
|
||||
$new_width = (int) ($width * $per);
|
||||
$new_height = (int) ($height * $per);
|
||||
|
||||
$x = 0;
|
||||
$y = 0;
|
||||
if($thumbnail_type == 'crop')
|
||||
// Rotate image
|
||||
if ($rotate)
|
||||
{
|
||||
$x = (int) ($resize_width / 2 - $new_width / 2);
|
||||
$y = (int) ($resize_height / 2 - $new_height / 2);
|
||||
$source = imagerotate($source, $rotate, 0);
|
||||
$width = imagesx($source);
|
||||
$height = imagesy($source);
|
||||
}
|
||||
|
||||
if(function_exists('imagecopyresampled'))
|
||||
// If resize not needed, skip thumbnail generation
|
||||
if ($width == $resize_width && $height == $resize_height)
|
||||
{
|
||||
imagecopyresampled($thumb, $source, $x, $y, 0, 0, $new_width, $new_height, $width, $height);
|
||||
$thumb = &$source;
|
||||
}
|
||||
else
|
||||
{
|
||||
imagecopyresized($thumb, $source, $x, $y, 0, 0, $new_width, $new_height, $width, $height);
|
||||
}
|
||||
// if original image is larger than specified size to resize, calculate the ratio
|
||||
$width_per = ($resize_width > 0 && $width >= $resize_width) ? $resize_width / $width : 1;
|
||||
$height_per = ($resize_height > 0 && $height >= $resize_height) ? $resize_height / $height : 1;
|
||||
|
||||
$per = NULL;
|
||||
if($thumbnail_type == 'ratio')
|
||||
{
|
||||
$per = ($width_per > $height_per) ? $height_per : $width_per;
|
||||
$resize_width = $width * $per;
|
||||
$resize_height = $height * $per;
|
||||
}
|
||||
else
|
||||
{
|
||||
$per = ($width_per < $height_per) ? $height_per : $width_per;
|
||||
}
|
||||
|
||||
// create temporary image with target size
|
||||
$thumb = NULL;
|
||||
if(function_exists('imagecreateTRUEcolor'))
|
||||
{
|
||||
$thumb = imagecreateTRUEcolor($resize_width, $resize_height);
|
||||
}
|
||||
else if(function_exists('imagecreate'))
|
||||
{
|
||||
$thumb = imagecreate($resize_width, $resize_height);
|
||||
}
|
||||
|
||||
if(!$thumb)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if($target_type == 'png' && function_exists('imagecolorallocatealpha') && function_exists('imagesavealpha') && function_exists('imagealphablending'))
|
||||
{
|
||||
imagefill($thumb, 0, 0, imagecolorallocatealpha($thumb, 0, 0, 0, 127));
|
||||
imagesavealpha($thumb, TRUE);
|
||||
imagealphablending($thumb, TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
imagefilledrectangle($thumb, 0, 0, $resize_width - 1, $resize_height - 1, imagecolorallocate($thumb, 255, 255, 255));
|
||||
}
|
||||
|
||||
// resize original image and put it into temporary image
|
||||
$new_width = (int) ($width * $per);
|
||||
$new_height = (int) ($height * $per);
|
||||
|
||||
$x = 0;
|
||||
$y = 0;
|
||||
if($thumbnail_type == 'crop')
|
||||
{
|
||||
$x = (int) ($resize_width / 2 - $new_width / 2);
|
||||
$y = (int) ($resize_height / 2 - $new_height / 2);
|
||||
}
|
||||
|
||||
if(function_exists('imagecopyresampled'))
|
||||
{
|
||||
imagecopyresampled($thumb, $source, $x, $y, 0, 0, $new_width, $new_height, $width, $height);
|
||||
}
|
||||
else
|
||||
{
|
||||
imagecopyresized($thumb, $source, $x, $y, 0, 0, $new_width, $new_height, $width, $height);
|
||||
}
|
||||
}
|
||||
|
||||
// create directory
|
||||
self::makeDir(dirname($target_file));
|
||||
|
||||
|
|
|
|||
|
|
@ -73,6 +73,8 @@ class fileAdminController extends file
|
|||
$config->image_autoconv['bmp2jpg'] = Context::get('image_autoconv_bmp2jpg') === 'Y' ? true : false;
|
||||
$config->image_autoconv['webp2jpg'] = Context::get('image_autoconv_webp2jpg') === 'Y' ? true : false;
|
||||
$config->image_autoconv_quality = max(50, min(100, intval(Context::get('image_autoconv_quality'))));
|
||||
$config->image_autorotate = Context::get('image_autorotate') === 'Y' ? true : false;
|
||||
$config->image_autorotate_quality = max(50, min(100, intval(Context::get('image_autorotate_quality'))));
|
||||
|
||||
// Check maximum file size
|
||||
if (PHP_INT_SIZE < 8)
|
||||
|
|
|
|||
|
|
@ -1051,11 +1051,41 @@ class fileController extends file
|
|||
// Check image type
|
||||
if($config->image_autoconv['bmp2jpg'] && function_exists('imagebmp') && $image_type === 6)
|
||||
{
|
||||
$convert = array($image_width, $image_height, 'jpg', $config->image_autoconv_quality ?: 75);
|
||||
$convert = array($image_width, $image_height, 'jpg', $config->image_autoconv_quality ?: 75, 0);
|
||||
}
|
||||
if($config->image_autoconv['webp2jpg'] && function_exists('imagewebp') && $image_type === 18)
|
||||
{
|
||||
$convert = array($image_width, $image_height, 'jpg', $config->image_autoconv_quality ?: 75);
|
||||
$convert = array($image_width, $image_height, 'jpg', $config->image_autoconv_quality ?: 75, 0);
|
||||
}
|
||||
|
||||
// Check image rotation
|
||||
if($config->image_autorotate && function_exists('exif_read_data'))
|
||||
{
|
||||
$exif = @exif_read_data($file_info['tmp_name']);
|
||||
if($exif && isset($exif['Orientation']))
|
||||
{
|
||||
switch ($exif['Orientation'])
|
||||
{
|
||||
case 3: $rotate = 180; break;
|
||||
case 6: $rotate = 270; break;
|
||||
case 8: $rotate = 90; break;
|
||||
default: $rotate = 0;
|
||||
}
|
||||
if ($rotate)
|
||||
{
|
||||
$convert = $convert ?: array($image_width, $image_height, $file_info['extension']);
|
||||
if ($rotate == 90 || $rotate == 270)
|
||||
{
|
||||
$image_height = $convert[0];
|
||||
$image_width = $convert[1];
|
||||
$convert[0] = $image_width;
|
||||
$convert[1] = $image_height;
|
||||
}
|
||||
$convert[3] = $config->image_autorotate_quality ?: 75;
|
||||
$convert[4] = $rotate;
|
||||
}
|
||||
}
|
||||
unset($exif);
|
||||
}
|
||||
|
||||
// Check image size
|
||||
|
|
@ -1108,7 +1138,8 @@ class fileController extends file
|
|||
$resize_height = $config->max_image_height;
|
||||
}
|
||||
$target_type = in_array($image_type, array(6, 8, 18)) ? 'jpg' : $file_info['extension'];
|
||||
$convert = array(intval($resize_width), intval($resize_height), $target_type, $config->max_image_size_quality ?: 75);
|
||||
$rotate = ($convert && $convert[4]) ? $convert[4] : 0;
|
||||
$convert = array(intval($resize_width), intval($resize_height), $target_type, $config->max_image_size_quality ?: 75, $rotate);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1116,12 +1147,13 @@ class fileController extends file
|
|||
// Convert image if necessary
|
||||
if ($convert)
|
||||
{
|
||||
$result = FileHandler::createImageFile($file_info['tmp_name'], $file_info['tmp_name'] . '.conv', $convert[0], $convert[1], $convert[2], 'crop', $convert[3]);
|
||||
$result = FileHandler::createImageFile($file_info['tmp_name'], $file_info['tmp_name'] . '.conv', $convert[0], $convert[1], $convert[2], 'crop', $convert[3], $convert[4]);
|
||||
if ($result)
|
||||
{
|
||||
$file_info['name'] = preg_replace('/\.' . preg_quote($file_info['extension'], '/') . '$/i', '.' . $convert[2], $file_info['name']);
|
||||
$file_info['tmp_name'] = $file_info['tmp_name'] . '.conv';
|
||||
$file_info['size'] = filesize($file_info['tmp_name']);
|
||||
$file_info['extension'] = $convert[2];
|
||||
$file_info['converted'] = true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -195,6 +195,8 @@ class fileModel extends file
|
|||
$config->max_image_size_quality = $file_config->max_image_size_quality;
|
||||
$config->image_autoconv = $file_config->image_autoconv;
|
||||
$config->image_autoconv_quality = $file_config->image_autoconv_quality;
|
||||
$config->image_autorotate = $file_config->image_autorotate;
|
||||
$config->image_autorotate_quality = $file_config->image_autorotate_quality;
|
||||
$config->download_grant = $file_config->download_grant;
|
||||
$config->allow_outlink = $file_config->allow_outlink;
|
||||
$config->allow_outlink_site = $file_config->allow_outlink_site;
|
||||
|
|
@ -215,6 +217,8 @@ class fileModel extends file
|
|||
if(!$config->max_image_size_quality) $config->max_image_size_quality = $file_module_config->max_image_size_quality;
|
||||
if(!$config->image_autoconv) $config->image_autoconv = $file_module_config->image_autoconv;
|
||||
if(!$config->image_autoconv_quality) $config->image_autoconv_quality = $file_module_config->image_autoconv_quality;
|
||||
if(!$config->image_autorotate) $config->image_autorotate = $file_module_config->image_autorotate;
|
||||
if(!$config->image_autorotate_quality) $config->image_autorotate_quality = $file_module_config->image_autorotate_quality;
|
||||
|
||||
// Default setting if not exists
|
||||
if(!$config->allowed_filesize) $config->allowed_filesize = '2';
|
||||
|
|
@ -226,6 +230,7 @@ class fileModel extends file
|
|||
if(!$config->max_image_size_quality) $config->max_image_size_quality = 75;
|
||||
if(!$config->image_autoconv) $config->image_autoconv = array();
|
||||
if(!$config->image_autoconv_quality) $config->image_autoconv_quality = 75;
|
||||
if(!$config->image_autorotate_quality) $config->image_autorotate_quality = 75;
|
||||
|
||||
return $config;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ $lang->image_resize_quality = 'Quality';
|
|||
$lang->image_autoconv = 'Auto-Convert Image';
|
||||
$lang->image_autoconv_bmp2jpg = 'BMP → JPG';
|
||||
$lang->image_autoconv_webp2jpg = 'WebP → JPG';
|
||||
$lang->image_autorotate = 'Auto-Rotate Image';
|
||||
$lang->inline_download_format = 'Open in current window';
|
||||
$lang->inline_download_image = 'Image';
|
||||
$lang->inline_download_audio = 'Audio';
|
||||
|
|
@ -44,6 +45,7 @@ $lang->about_allowed_size_limits = 'The file size will be limited to the value s
|
|||
$lang->about_allowed_filetypes = 'To allow an extension, use "*.[extention]". To allow multiple extensions, use ";" between each extension. ex) *.* or *.jpg;*.gif; ';
|
||||
$lang->about_max_image_size = 'You can limit the maximum width and/or height of uploaded images.<br />This limit does not apply to files uploaded by the administrator.';
|
||||
$lang->about_image_autoconv = 'Automatically convert types of images that often cause trouble or waste disk space into other types.<br />This also works for WebP images that incorrectly have the JPG extension.<br />If enabled, this feature also applies to images uploaded by the administrator.';
|
||||
$lang->about_image_autorotate = 'Automatically correct images that are rotated by mobile devices.<br />If enabled, this feature also applies to images uploaded by the administrator.';
|
||||
$lang->cmd_delete_checked_file = 'Delete Selected Item(s)';
|
||||
$lang->cmd_move_to_document = 'Move to Document';
|
||||
$lang->cmd_download = 'Download';
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ $lang->image_resize_quality = '화질';
|
|||
$lang->image_autoconv = '이미지 자동 변환';
|
||||
$lang->image_autoconv_bmp2jpg = 'BMP → JPG';
|
||||
$lang->image_autoconv_webp2jpg = 'WebP → JPG';
|
||||
$lang->image_autorotate = '이미지 자동 회전';
|
||||
$lang->inline_download_format = '다운로드시 현재 창 사용';
|
||||
$lang->inline_download_image = '이미지';
|
||||
$lang->inline_download_audio = '오디오';
|
||||
|
|
@ -44,6 +45,7 @@ $lang->about_allowed_size_limits = 'IE9 이하, 구버전 안드로이드 등에
|
|||
$lang->about_allowed_filetypes = '"*.확장자"로 지정할 수 있고 ";" 으로 여러 개 지정이 가능합니다. 예) *.* or *.jpg;*.gif;';
|
||||
$lang->about_max_image_size = '이미지 파일의 가로, 세로, 또는 가로세로 크기를 모두 제한할 수 있습니다.<br />관리자가 업로드한 파일에는 적용되지 않습니다.';
|
||||
$lang->about_image_autoconv = '종종 문제를 일으키거나 용량을 낭비하는 이미지 타입을 다른 타입으로 자동 변환합니다.<br />WebP 이미지에 JPG 확장자가 잘못 부여된 경우에도 변환할 수 있습니다.<br />관리자가 업로드한 파일에도 적용됩니다.';
|
||||
$lang->about_image_autorotate = '모바일 기기 등에서 잘못 회전된 이미지를 바로잡습니다.<br />관리자가 업로드한 파일에도 적용됩니다.';
|
||||
$lang->cmd_delete_checked_file = '선택항목 삭제';
|
||||
$lang->cmd_move_to_document = '문서로 이동';
|
||||
$lang->cmd_download = '다운로드';
|
||||
|
|
|
|||
|
|
@ -61,6 +61,26 @@
|
|||
<p class="x_help-block">{$lang->about_image_autoconv}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="x_control-group">
|
||||
<label class="x_control-label">{$lang->image_autorotate}</label>
|
||||
<div class="x_controls">
|
||||
<label for="image_autorotate_Y" class="x_inline">
|
||||
<input type="radio" name="image_autorotate" id="image_autorotate_Y" value="Y" checked="checked"|cond="$config->image_autorotate === true" disabled="disabled"|cond="!function_exists('exif_read_data')" />
|
||||
{$lang->cmd_yes}
|
||||
</label>
|
||||
<label for="image_autorotate_N" class="x_inline">
|
||||
<input type="radio" name="image_autorotate" id="image_autorotate_N" value="N" checked="checked"|cond="$config->image_autorotate !== true" disabled="disabled"|cond="!function_exists('exif_read_data')" />
|
||||
{$lang->cmd_no}
|
||||
</label>
|
||||
<select name="image_autorotate_quality" id="image_autorotate_quality" style="width:100px;min-width:100px">
|
||||
{@ $config->image_autorotate_quality = $config->image_autorotate_quality ?: 75}
|
||||
<!--@for($q = 50; $q <= 100; $q += 5)-->
|
||||
<option value="{$q}" selected="selected"|cond="$config->image_autorotate_quality == $q">{$lang->image_resize_quality} {$q}%</option>
|
||||
<!--@endfor-->
|
||||
</select>
|
||||
<p class="x_help-block">{$lang->about_image_autorotate}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="x_control-group">
|
||||
<label for="allowedFiletypes" class="x_control-label">{$lang->allowed_filetypes}</label>
|
||||
<div class="x_controls">
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue