forked from Cavemanon/cavepaintings
PSR-2. I'm not a huge fan, but ugly consistency beats no consistency...
This commit is contained in:
@ -15,221 +15,228 @@
|
||||
/**
|
||||
* This class is just a wrapper around SCoreException.
|
||||
*/
|
||||
class ImageRotateException extends SCoreException {
|
||||
/** @var string */
|
||||
public $error;
|
||||
class ImageRotateException extends SCoreException
|
||||
{
|
||||
/** @var string */
|
||||
public $error;
|
||||
|
||||
public function __construct(string $error) {
|
||||
$this->error = $error;
|
||||
}
|
||||
public function __construct(string $error)
|
||||
{
|
||||
$this->error = $error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This class handles image rotate requests.
|
||||
*/
|
||||
class RotateImage extends Extension {
|
||||
class RotateImage extends Extension
|
||||
{
|
||||
public function onInitExt(InitExtEvent $event)
|
||||
{
|
||||
global $config;
|
||||
$config->set_default_bool('rotate_enabled', true);
|
||||
$config->set_default_int('rotate_default_deg', 180);
|
||||
}
|
||||
|
||||
public function onInitExt(InitExtEvent $event) {
|
||||
global $config;
|
||||
$config->set_default_bool('rotate_enabled', true);
|
||||
$config->set_default_int('rotate_default_deg', 180);
|
||||
}
|
||||
public function onImageAdminBlockBuilding(ImageAdminBlockBuildingEvent $event)
|
||||
{
|
||||
global $user, $config;
|
||||
if ($user->is_admin() && $config->get_bool("rotate_enabled")) {
|
||||
/* Add a link to rotate the image */
|
||||
$event->add_part($this->theme->get_rotate_html($event->image->id));
|
||||
}
|
||||
}
|
||||
|
||||
public function onSetupBuilding(SetupBuildingEvent $event)
|
||||
{
|
||||
$sb = new SetupBlock("Image Rotate");
|
||||
$sb->add_bool_option("rotate_enabled", "Allow rotating images: ");
|
||||
$sb->add_label("<br>Default Orientation: ");
|
||||
$sb->add_int_option("rotate_default_deg");
|
||||
$sb->add_label(" deg");
|
||||
$event->panel->add_block($sb);
|
||||
}
|
||||
|
||||
public function onPageRequest(PageRequestEvent $event)
|
||||
{
|
||||
global $page, $user;
|
||||
|
||||
public function onImageAdminBlockBuilding(ImageAdminBlockBuildingEvent $event) {
|
||||
global $user, $config;
|
||||
if($user->is_admin() && $config->get_bool("rotate_enabled")) {
|
||||
/* Add a link to rotate the image */
|
||||
$event->add_part($this->theme->get_rotate_html($event->image->id));
|
||||
}
|
||||
}
|
||||
|
||||
public function onSetupBuilding(SetupBuildingEvent $event) {
|
||||
$sb = new SetupBlock("Image Rotate");
|
||||
$sb->add_bool_option("rotate_enabled", "Allow rotating images: ");
|
||||
$sb->add_label("<br>Default Orientation: ");
|
||||
$sb->add_int_option("rotate_default_deg");
|
||||
$sb->add_label(" deg");
|
||||
$event->panel->add_block($sb);
|
||||
}
|
||||
|
||||
public function onPageRequest(PageRequestEvent $event) {
|
||||
global $page, $user;
|
||||
if ($event->page_matches("rotate") && $user->is_admin()) {
|
||||
// Try to get the image ID
|
||||
$image_id = int_escape($event->get_arg(0));
|
||||
if (empty($image_id)) {
|
||||
$image_id = isset($_POST['image_id']) ? $_POST['image_id'] : null;
|
||||
}
|
||||
if (empty($image_id)) {
|
||||
throw new ImageRotateException("Can not rotate Image: No valid Image ID given.");
|
||||
}
|
||||
|
||||
$image = Image::by_id($image_id);
|
||||
if (is_null($image)) {
|
||||
$this->theme->display_error(404, "Image not found", "No image in the database has the ID #$image_id");
|
||||
} else {
|
||||
|
||||
/* Check if options were given to rotate an image. */
|
||||
if (isset($_POST['rotate_deg'])) {
|
||||
|
||||
/* get options */
|
||||
|
||||
$deg = 0;
|
||||
|
||||
if (isset($_POST['rotate_deg'])) {
|
||||
$deg = int_escape($_POST['rotate_deg']);
|
||||
}
|
||||
|
||||
/* Attempt to rotate the image */
|
||||
try {
|
||||
$this->rotate_image($image_id, $deg);
|
||||
|
||||
//$this->theme->display_rotate_page($page, $image_id);
|
||||
|
||||
$page->set_mode("redirect");
|
||||
$page->set_redirect(make_link("post/view/".$image_id));
|
||||
} catch (ImageRotateException $e) {
|
||||
$this->theme->display_rotate_error($page, "Error Rotating", $e->error);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Private functions
|
||||
/* ----------------------------- */
|
||||
|
||||
if ( $event->page_matches("rotate") && $user->is_admin() ) {
|
||||
// Try to get the image ID
|
||||
$image_id = int_escape($event->get_arg(0));
|
||||
if (empty($image_id)) {
|
||||
$image_id = isset($_POST['image_id']) ? $_POST['image_id'] : null;
|
||||
}
|
||||
if (empty($image_id)) {
|
||||
throw new ImageRotateException("Can not rotate Image: No valid Image ID given.");
|
||||
}
|
||||
|
||||
$image = Image::by_id($image_id);
|
||||
if(is_null($image)) {
|
||||
$this->theme->display_error(404, "Image not found", "No image in the database has the ID #$image_id");
|
||||
} else {
|
||||
|
||||
/* Check if options were given to rotate an image. */
|
||||
if (isset($_POST['rotate_deg'])) {
|
||||
|
||||
/* get options */
|
||||
|
||||
$deg = 0;
|
||||
|
||||
if (isset($_POST['rotate_deg'])) {
|
||||
$deg = int_escape($_POST['rotate_deg']);
|
||||
}
|
||||
|
||||
/* Attempt to rotate the image */
|
||||
try {
|
||||
$this->rotate_image($image_id, $deg);
|
||||
|
||||
//$this->theme->display_rotate_page($page, $image_id);
|
||||
|
||||
$page->set_mode("redirect");
|
||||
$page->set_redirect(make_link("post/view/".$image_id));
|
||||
|
||||
} catch (ImageRotateException $e) {
|
||||
$this->theme->display_rotate_error($page, "Error Rotating", $e->error);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Private functions
|
||||
/* ----------------------------- */
|
||||
/**
|
||||
* This function could be made much smaller by using the ImageReplaceEvent
|
||||
* ie: Pretend that we are replacing the image with a rotated copy.
|
||||
*/
|
||||
private function rotate_image(int $image_id, int $deg)
|
||||
{
|
||||
global $database;
|
||||
|
||||
if (($deg <= -360) || ($deg >= 360)) {
|
||||
throw new ImageRotateException("Invalid options for rotation angle. ($deg)");
|
||||
}
|
||||
|
||||
$image_obj = Image::by_id($image_id);
|
||||
$hash = $image_obj->hash;
|
||||
if (is_null($hash)) {
|
||||
throw new ImageRotateException("Image does not have a hash associated with it.");
|
||||
}
|
||||
|
||||
$image_filename = warehouse_path("images", $hash);
|
||||
if (file_exists($image_filename)==false) {
|
||||
throw new ImageRotateException("$image_filename does not exist.");
|
||||
}
|
||||
$info = getimagesize($image_filename);
|
||||
/* Get the image file type */
|
||||
$pathinfo = pathinfo($image_obj->filename);
|
||||
$filetype = strtolower($pathinfo['extension']);
|
||||
|
||||
/*
|
||||
Check Memory usage limits
|
||||
|
||||
/**
|
||||
* This function could be made much smaller by using the ImageReplaceEvent
|
||||
* ie: Pretend that we are replacing the image with a rotated copy.
|
||||
*/
|
||||
private function rotate_image(int $image_id, int $deg) {
|
||||
global $database;
|
||||
|
||||
if ( ($deg <= -360) || ($deg >= 360) ) {
|
||||
throw new ImageRotateException("Invalid options for rotation angle. ($deg)");
|
||||
}
|
||||
|
||||
$image_obj = Image::by_id($image_id);
|
||||
$hash = $image_obj->hash;
|
||||
if (is_null($hash)) {
|
||||
throw new ImageRotateException("Image does not have a hash associated with it.");
|
||||
}
|
||||
|
||||
$image_filename = warehouse_path("images", $hash);
|
||||
if (file_exists ( $image_filename )==false) { throw new ImageRotateException("$image_filename does not exist."); }
|
||||
$info = getimagesize($image_filename);
|
||||
/* Get the image file type */
|
||||
$pathinfo = pathinfo($image_obj->filename);
|
||||
$filetype = strtolower($pathinfo['extension']);
|
||||
|
||||
/*
|
||||
Check Memory usage limits
|
||||
|
||||
Old check: $memory_use = (filesize($image_filename)*2) + ($width*$height*4) + (4*1024*1024);
|
||||
New check: memory_use = width * height * (bits per channel) * channels * 2.5
|
||||
|
||||
It didn't make sense to compute the memory usage based on the NEW size for the image. ($width*$height*4)
|
||||
We need to consider the size that we are GOING TO instead.
|
||||
|
||||
The factor of 2.5 is simply a rough guideline.
|
||||
http://stackoverflow.com/questions/527532/reasonable-php-memory-limit-for-image-resize
|
||||
*/
|
||||
$memory_use = ($info[0] * $info[1] * ($info['bits'] / 8) * $info['channels'] * 2.5) / 1024;
|
||||
$memory_limit = get_memory_limit();
|
||||
|
||||
if ($memory_use > $memory_limit) {
|
||||
throw new ImageRotateException("The image is too large to rotate given the memory limits. ($memory_use > $memory_limit)");
|
||||
}
|
||||
|
||||
|
||||
/* Attempt to load the image */
|
||||
switch ( $info[2] ) {
|
||||
case IMAGETYPE_GIF: $image = imagecreatefromgif($image_filename); break;
|
||||
case IMAGETYPE_JPEG: $image = imagecreatefromjpeg($image_filename); break;
|
||||
case IMAGETYPE_PNG: $image = imagecreatefrompng($image_filename); break;
|
||||
default:
|
||||
throw new ImageRotateException("Unsupported image type or ");
|
||||
}
|
||||
|
||||
/* Rotate and resample the image */
|
||||
/*
|
||||
$image_rotated = imagecreatetruecolor( $new_width, $new_height );
|
||||
|
||||
if ( ($info[2] == IMAGETYPE_GIF) || ($info[2] == IMAGETYPE_PNG) ) {
|
||||
$transparency = imagecolortransparent($image);
|
||||
Old check: $memory_use = (filesize($image_filename)*2) + ($width*$height*4) + (4*1024*1024);
|
||||
New check: memory_use = width * height * (bits per channel) * channels * 2.5
|
||||
|
||||
if ($transparency >= 0) {
|
||||
$transparent_color = imagecolorsforindex($image, $trnprt_indx);
|
||||
$transparency = imagecolorallocate($image_rotated, $trnprt_color['red'], $trnprt_color['green'], $trnprt_color['blue']);
|
||||
imagefill($image_rotated, 0, 0, $transparency);
|
||||
imagecolortransparent($image_rotated, $transparency);
|
||||
}
|
||||
elseif ($info[2] == IMAGETYPE_PNG) {
|
||||
imagealphablending($image_rotated, false);
|
||||
$color = imagecolorallocatealpha($image_rotated, 0, 0, 0, 127);
|
||||
imagefill($image_rotated, 0, 0, $color);
|
||||
imagesavealpha($image_rotated, true);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
$image_rotated = imagerotate($image, $deg, 0);
|
||||
|
||||
/* Temp storage while we rotate */
|
||||
$tmp_filename = tempnam(ini_get('upload_tmp_dir'), 'shimmie_rotate');
|
||||
if (empty($tmp_filename)) {
|
||||
throw new ImageRotateException("Unable to save temporary image file.");
|
||||
}
|
||||
|
||||
/* Output to the same format as the original image */
|
||||
switch ( $info[2] ) {
|
||||
case IMAGETYPE_GIF: imagegif($image_rotated, $tmp_filename); break;
|
||||
case IMAGETYPE_JPEG: imagejpeg($image_rotated, $tmp_filename); break;
|
||||
case IMAGETYPE_PNG: imagepng($image_rotated, $tmp_filename); break;
|
||||
default:
|
||||
throw new ImageRotateException("Unsupported image type.");
|
||||
}
|
||||
|
||||
/* Move the new image into the main storage location */
|
||||
$new_hash = md5_file($tmp_filename);
|
||||
$new_size = filesize($tmp_filename);
|
||||
$target = warehouse_path("images", $new_hash);
|
||||
if(!@copy($tmp_filename, $target)) {
|
||||
throw new ImageRotateException("Failed to copy new image file from temporary location ({$tmp_filename}) to archive ($target)");
|
||||
}
|
||||
$new_filename = 'rotated-'.$image_obj->filename;
|
||||
|
||||
list($new_width, $new_height) = getimagesize($target);
|
||||
It didn't make sense to compute the memory usage based on the NEW size for the image. ($width*$height*4)
|
||||
We need to consider the size that we are GOING TO instead.
|
||||
|
||||
|
||||
/* Remove temporary file */
|
||||
@unlink($tmp_filename);
|
||||
The factor of 2.5 is simply a rough guideline.
|
||||
http://stackoverflow.com/questions/527532/reasonable-php-memory-limit-for-image-resize
|
||||
*/
|
||||
$memory_use = ($info[0] * $info[1] * ($info['bits'] / 8) * $info['channels'] * 2.5) / 1024;
|
||||
$memory_limit = get_memory_limit();
|
||||
|
||||
if ($memory_use > $memory_limit) {
|
||||
throw new ImageRotateException("The image is too large to rotate given the memory limits. ($memory_use > $memory_limit)");
|
||||
}
|
||||
|
||||
|
||||
/* Attempt to load the image */
|
||||
switch ($info[2]) {
|
||||
case IMAGETYPE_GIF: $image = imagecreatefromgif($image_filename); break;
|
||||
case IMAGETYPE_JPEG: $image = imagecreatefromjpeg($image_filename); break;
|
||||
case IMAGETYPE_PNG: $image = imagecreatefrompng($image_filename); break;
|
||||
default:
|
||||
throw new ImageRotateException("Unsupported image type or ");
|
||||
}
|
||||
|
||||
/* Rotate and resample the image */
|
||||
/*
|
||||
$image_rotated = imagecreatetruecolor( $new_width, $new_height );
|
||||
|
||||
/* Delete original image and thumbnail */
|
||||
log_debug("image", "Removing image with hash ".$hash);
|
||||
$image_obj->remove_image_only();
|
||||
|
||||
/* Generate new thumbnail */
|
||||
send_event(new ThumbnailGenerationEvent($new_hash, $filetype));
|
||||
|
||||
/* Update the database */
|
||||
$database->Execute(
|
||||
"UPDATE images SET
|
||||
if ( ($info[2] == IMAGETYPE_GIF) || ($info[2] == IMAGETYPE_PNG) ) {
|
||||
$transparency = imagecolortransparent($image);
|
||||
|
||||
if ($transparency >= 0) {
|
||||
$transparent_color = imagecolorsforindex($image, $trnprt_indx);
|
||||
$transparency = imagecolorallocate($image_rotated, $trnprt_color['red'], $trnprt_color['green'], $trnprt_color['blue']);
|
||||
imagefill($image_rotated, 0, 0, $transparency);
|
||||
imagecolortransparent($image_rotated, $transparency);
|
||||
}
|
||||
elseif ($info[2] == IMAGETYPE_PNG) {
|
||||
imagealphablending($image_rotated, false);
|
||||
$color = imagecolorallocatealpha($image_rotated, 0, 0, 0, 127);
|
||||
imagefill($image_rotated, 0, 0, $color);
|
||||
imagesavealpha($image_rotated, true);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
$image_rotated = imagerotate($image, $deg, 0);
|
||||
|
||||
/* Temp storage while we rotate */
|
||||
$tmp_filename = tempnam(ini_get('upload_tmp_dir'), 'shimmie_rotate');
|
||||
if (empty($tmp_filename)) {
|
||||
throw new ImageRotateException("Unable to save temporary image file.");
|
||||
}
|
||||
|
||||
/* Output to the same format as the original image */
|
||||
switch ($info[2]) {
|
||||
case IMAGETYPE_GIF: imagegif($image_rotated, $tmp_filename); break;
|
||||
case IMAGETYPE_JPEG: imagejpeg($image_rotated, $tmp_filename); break;
|
||||
case IMAGETYPE_PNG: imagepng($image_rotated, $tmp_filename); break;
|
||||
default:
|
||||
throw new ImageRotateException("Unsupported image type.");
|
||||
}
|
||||
|
||||
/* Move the new image into the main storage location */
|
||||
$new_hash = md5_file($tmp_filename);
|
||||
$new_size = filesize($tmp_filename);
|
||||
$target = warehouse_path("images", $new_hash);
|
||||
if (!@copy($tmp_filename, $target)) {
|
||||
throw new ImageRotateException("Failed to copy new image file from temporary location ({$tmp_filename}) to archive ($target)");
|
||||
}
|
||||
$new_filename = 'rotated-'.$image_obj->filename;
|
||||
|
||||
list($new_width, $new_height) = getimagesize($target);
|
||||
|
||||
|
||||
/* Remove temporary file */
|
||||
@unlink($tmp_filename);
|
||||
|
||||
/* Delete original image and thumbnail */
|
||||
log_debug("image", "Removing image with hash ".$hash);
|
||||
$image_obj->remove_image_only();
|
||||
|
||||
/* Generate new thumbnail */
|
||||
send_event(new ThumbnailGenerationEvent($new_hash, $filetype));
|
||||
|
||||
/* Update the database */
|
||||
$database->Execute(
|
||||
"UPDATE images SET
|
||||
filename = :filename, filesize = :filesize, hash = :hash, width = :width, height = :height
|
||||
WHERE
|
||||
id = :id
|
||||
",
|
||||
array(
|
||||
"filename"=>$new_filename, "filesize"=>$new_size, "hash"=>$new_hash,
|
||||
"width"=>$new_width, "height"=>$new_height, "id"=>$image_id
|
||||
)
|
||||
);
|
||||
|
||||
log_info("rotate", "Rotated Image #{$image_id} - New hash: {$new_hash}");
|
||||
}
|
||||
[
|
||||
"filename"=>$new_filename, "filesize"=>$new_size, "hash"=>$new_hash,
|
||||
"width"=>$new_width, "height"=>$new_height, "id"=>$image_id
|
||||
]
|
||||
);
|
||||
|
||||
log_info("rotate", "Rotated Image #{$image_id} - New hash: {$new_hash}");
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user