News:

Wondering if this will always be free?  See why free is better.

Main Menu

Automatic Attachment Rotation (and Resize)

Started by dougiefresh, March 04, 2016, 07:34:59 PM

Previous topic - Next topic

GL700Wing

Quote from: Sir Osis of Liver on December 31, 2020, 05:21:40 PM

sprintf('<select id="orient[%1$d]" name="orient[%1$d]" style="height: 35px; margin: 0 10px 0 15px;">
<option value="1">ROTATE/FLIP IMAGE</option>
<option value="6">' . $txt['img_orientation6'] . '</option>
<option value="8">' . $txt['img_orientation8'] . '</option>
<option value="3">' . $txt['img_orientation3'] . '</option>
<option value="2">' . $txt['img_orientation2'] . '</option>
<option value="4">' . $txt['img_orientation4'] . '</option>
<option value="7">' . $txt['img_orientation7'] . '</option>
<option value="5">' . $txt['img_orientation5'] . '</option>
</select>', $attachment['id']);
Great - thanks!!

I finished a new version a couple of weeks ago (it has some minor bug fixes/changes) which I've installed on my forums and I'll incorporate this change in the next release.
Life doesn't have to be perfect to be wonderful ...

Slava
Ukraini!
"Before you allow people access to your forum, especially in an administrative position, you must be aware that that person can seriously damage your forum. Therefore, you should only allow people that you trust, implicitly, to have such access." -Douglas

@rjen

I am testing witch SMF 2.0.18 (beta testing) on 7.4 and this MOD is throwing some errors when an attachment is uploaded hat is NOT an image...

Errors:

https://test.my-forum.com/index.php?action=post2;start=0;board=26
8: Trying to access array offset on value of type bool
File: /home/deb77453/domains/my-forum.com/public_html/test/Sources/Subs-AutoRotation.php
Line: 514

https://test.my-forum.com/index.php?action=post2;start=0;board=26
8: Trying to access array offset on value of type bool
File: /home/deb77453/domains/my-forum.com/public_html/test/Sources/Subs-AutoRotation.php
Line: 507

https://test.my-forum.com/index.php?action=post2;start=0;board=26
8: Trying to access array offset on value of type bool
File: /home/deb77453/domains/my-forum.com/public_html/test/Sources/Subs-AutoRotation.php
Line: 506

https://test.my-forum.com/index.php?action=post2;start=0;board=26
8: Trying to access array offset on value of type bool
File: /home/deb77453/domains/my-forum.com/public_html/test/Sources/Subs-AutoRotation.php
Line: 505

These are caused by the $info in line 504 not being populated. PHP7.4 does not like that...
This can be fixed by not executing the rotation code if the attachment is not an image...

   // Find out the image dimensions and type and if it's a JPEG image.
   $info = @getimagesize($filename);

File: Subs-AutoRotation.php

Find:

// Find out the image dimensions and type and if it's a JPEG image.
$info = @getimagesize($filename);
$width = $info[0];
$height = $info[1];
$type = $info[2];

// Find out if this image needs to be rotated, reformatted, resized and/or compressed.
$autoRotate = $modSettings['attachment_auto_rotate'];

// If this is a JPEG image find out if it has an EXIF orientation set.
$rotateImage = false;
if ($info['mime'] == 'image/jpeg')
{
$imageExif = @exif_read_data($filename);
if (isset($imageExif['Orientation']) || array_key_exists('Orientation', $imageExif))
$orientation = $imageExif['Orientation'];

if (!empty($orientation))
$rotateImage = in_array($orientation, [2, 3, 4, 5, 6, 7, 8]);
}

// Work out if the image should be reformatted to JPEG.
$reformatImage = $modSettings[$prefix . 'attachment_image_reformat'];
$preferred_format = $type;
// Only GIF and PNG image formats can be retained - all other image formats are converted to JPEG.
if ($reformatImage || ($type != 1 && $type != 3))
$preferred_format = 2;

// Set reformatImage to false if the image format is not changing.
$reformatImage = ($preferred_format == $type ? false : true);

// Work out if the image is being resized.
$resizeImage = AutoRotation_Aspect($width, $height, $prefix, $inAttachmentOtherGroups);

// Work out if the JPEG image should be compressed.
$compressImage = ($preferred_format == 2 && $jpegQuality > 0 && $jpegQuality < 100 ? true : false);

// Nothing to see here - this image doesn't need to be rotated, reformatted, resized and/or compressed.
if (!$rotateImage && !$reformatImage && !$resizeImage && !$compressImage)
return;
// Rotate the image if autoRotate is true, rotateImage is true, and resizeImage is false.
elseif ($autoRotate && $rotateImage && !$resizeImage)
{
AutoRotation_Process($filename, $orientation, $jpegQuality);

// Recheck the file size
$_FILES['attachment']['size'][$index] = filesize($filename);
}
// Rotate, reformat, resize and/or compress the image as required.
elseif (($autoRotate && $rotateImage) || $reformatImage || $resizeImage || $compressImage)
{
// Resize/reformat the image ...
require_once($sourcedir . '/Subs-Graphics.php');
if (resizeImageFile($filename, $filename . '.temp', $width, $height, $preferred_format, $jpegQuality))
{
// Delete the old tmp file and rename the new one.
unlink($filename);
rename($filename . '.temp', $filename);

// Rotate the image if autoRotate is true and rotateImage is true.
if ($autoRotate && $rotateImage)
AutoRotation_Process($filename, $orientation, $jpegQuality);

// Recheck the file size
$_FILES['attachment']['size'][$index] = filesize($filename);

// Change the file suffix to 'jpg' if necessary.
$filename = $_FILES['attachment']['name'][$index];
if ($preferred_format == 2 && strrchr($filename, '.') != '.jpg')
$_FILES['attachment']['name'][$index] = substr($filename, 0, -(strlen(strrchr($filename, '.')))) . '.jpg';
}
}
}


Replace by:

// Find out the image dimensions and type and if it's a JPEG image.
$info = @getimagesize($filename);
if($info) {
$width = $info[0];
$height = $info[1];
$type = $info[2];

// Find out if this image needs to be rotated, reformatted, resized and/or compressed.
$autoRotate = $modSettings['attachment_auto_rotate'];

// If this is a JPEG image find out if it has an EXIF orientation set.
$rotateImage = false;
if ($info['mime'] == 'image/jpeg')
{
$imageExif = @exif_read_data($filename);
if (isset($imageExif['Orientation']) || array_key_exists('Orientation', $imageExif))
$orientation = $imageExif['Orientation'];

if (!empty($orientation))
$rotateImage = in_array($orientation, [2, 3, 4, 5, 6, 7, 8]);
}

// Work out if the image should be reformatted to JPEG.
$reformatImage = $modSettings[$prefix . 'attachment_image_reformat'];
$preferred_format = $type;
// Only GIF and PNG image formats can be retained - all other image formats are converted to JPEG.
if ($reformatImage || ($type != 1 && $type != 3))
$preferred_format = 2;

// Set reformatImage to false if the image format is not changing.
$reformatImage = ($preferred_format == $type ? false : true);

// Work out if the image is being resized.
$resizeImage = AutoRotation_Aspect($width, $height, $prefix, $inAttachmentOtherGroups);

// Work out if the JPEG image should be compressed.
$compressImage = ($preferred_format == 2 && $jpegQuality > 0 && $jpegQuality < 100 ? true : false);

// Nothing to see here - this image doesn't need to be rotated, reformatted, resized and/or compressed.
if (!$rotateImage && !$reformatImage && !$resizeImage && !$compressImage)
return;
// Rotate the image if autoRotate is true, rotateImage is true, and resizeImage is false.
elseif ($autoRotate && $rotateImage && !$resizeImage)
{
AutoRotation_Process($filename, $orientation, $jpegQuality);

// Recheck the file size
$_FILES['attachment']['size'][$index] = filesize($filename);
}
// Rotate, reformat, resize and/or compress the image as required.
elseif (($autoRotate && $rotateImage) || $reformatImage || $resizeImage || $compressImage)
{
// Resize/reformat the image ...
require_once($sourcedir . '/Subs-Graphics.php');
if (resizeImageFile($filename, $filename . '.temp', $width, $height, $preferred_format, $jpegQuality))
{
// Delete the old tmp file and rename the new one.
unlink($filename);
rename($filename . '.temp', $filename);

// Rotate the image if autoRotate is true and rotateImage is true.
if ($autoRotate && $rotateImage)
AutoRotation_Process($filename, $orientation, $jpegQuality);

// Recheck the file size
$_FILES['attachment']['size'][$index] = filesize($filename);

// Change the file suffix to 'jpg' if necessary.
$filename = $_FILES['attachment']['name'][$index];
if ($preferred_format == 2 && strrchr($filename, '.') != '.jpg')
$_FILES['attachment']['name'][$index] = substr($filename, 0, -(strlen(strrchr($filename, '.')))) . '.jpg';
}
}
}
}

Running SMF 2.1 with latest TinyPortal at www.fjr-club.nl

GL700Wing

Quote from: @rjen on January 13, 2021, 05:07:36 AM
I am testing witch SMF 2.0.18 (beta testing) on 7.4 and this MOD is throwing some errors when an attachment is uploaded that is NOT an image...

<snip>...</snip>

These are caused by the $info in line 504 not being populated. PHP7.4 does not like that...
This can be fixed by not executing the rotation code if the attachment is not an image...

   // Find out the image dimensions and type and if it's a JPEG image.
   $info = @getimagesize($filename);

<snip>...</snip>

@rjen - Many thanks for letting me know about this issue - I have a new version of this mod just about ready to release.

The same code is executed on line 101 of ./Sources/Subs-AutoRotation.php but it is followed by the following check which I'll now add after line 504:
if (!$info)
return false;


I'll also check the other places where getimagesize is used in this mod and if necessary update the code to only continue if the attachment is an image.
Life doesn't have to be perfect to be wonderful ...

Slava
Ukraini!
"Before you allow people access to your forum, especially in an administrative position, you must be aware that that person can seriously damage your forum. Therefore, you should only allow people that you trust, implicitly, to have such access." -Douglas

@rjen

There's another change needed in teh inline attachments mod, I'll log that there...

By the way: the updates in the SMF2.0.18 code will require the install for this MOD to be slightly updated for 2.0.18.
Just a heads up for when 2.0.18 gets released...
Running SMF 2.1 with latest TinyPortal at www.fjr-club.nl

GL700Wing

Quote from: @rjen on January 13, 2021, 05:35:11 AM
There's another change needed in teh inline attachments mod, I'll log that there...

By the way: the updates in the SMF2.0.18 code will require the install for this MOD to be slightly updated for 2.0.18.
Just a heads up for when 2.0.18 gets released...
Thanks - I also have a new version of that mod just about ready for release so I think I'll wait until after SMF 2.0.18 has been released so that I make them both compatible with SMF 2.0.18.
Life doesn't have to be perfect to be wonderful ...

Slava
Ukraini!
"Before you allow people access to your forum, especially in an administrative position, you must be aware that that person can seriously damage your forum. Therefore, you should only allow people that you trust, implicitly, to have such access." -Douglas

@rjen

Missed this correction, sorry...

   ./Sources/Subs-ResizeExistingImages.php
   Search:
      $context['resize_results'][9999999] = '|' . $txt['resize_images_timeout'] . ' ' . array_sum(explode(' ', microtime())) - array_sum(explode(' ', $time_start));
   Replace:
      $context['resize_results'][9999999] = '|' . $txt['resize_images_timeout'] . ' ' . array_sum((explode(' ', microtime())) - array_sum(explode(' ', $time_start)));
Running SMF 2.1 with latest TinyPortal at www.fjr-club.nl

GL700Wing

Quote from: @rjen on January 13, 2021, 05:46:33 AM
Missed this correction, sorry...

   ./Sources/Subs-ResizeExistingImages.php
   Search:
      $context['resize_results'][9999999] = '|' . $txt['resize_images_timeout'] . ' ' . array_sum(explode(' ', microtime())) - array_sum(explode(' ', $time_start));
   Replace:
      $context['resize_results'][9999999] = '|' . $txt['resize_images_timeout'] . ' ' . array_sum((explode(' ', microtime())) - array_sum(explode(' ', $time_start)));

Noted and changed - thanks!
Life doesn't have to be perfect to be wonderful ...

Slava
Ukraini!
"Before you allow people access to your forum, especially in an administrative position, you must be aware that that person can seriously damage your forum. Therefore, you should only allow people that you trust, implicitly, to have such access." -Douglas

landyvlad

Q: If this mod is uninstalled / deleted will that affect any of the attachments already existing on the forum?
"Put as much effort into your question as you'd expect someone to give in an answer"

Please do not PM, IM or Email me with questions on astrophysics or theology.  You will get better and faster responses by asking homeless people in the street. Thank you.

Be the person your dog thinks you are.

GL700Wing

Quote from: landyvlad on February 02, 2021, 06:22:34 PM
Q: If this mod is uninstalled / deleted will that affect any of the attachments already existing on the forum?
No - although if you remove the database data (ie, the columns "proper_rotation" and "jpeg_quality" from "smf_attachments") and re-install the mod later on you will lose this information about existing attachments.
Life doesn't have to be perfect to be wonderful ...

Slava
Ukraini!
"Before you allow people access to your forum, especially in an administrative position, you must be aware that that person can seriously damage your forum. Therefore, you should only allow people that you trust, implicitly, to have such access." -Douglas

GL700Wing

Uploaded v6.00 - February 03, 2021
o Updated to support SMF 2.0.18/PHP 7.4.4 thanks to @rjen - ./Sources/Subs-AutoRotation.php and ./Sources/Subs-ResizeExistingImages.php.
o Improved layout as per suggestion made by Sir Osis of Liver.
o Added option to enable/disable reformatting/resizing of images using a single setting.
o Added option to enable/disable the use of different resizing options for some membergroups (introduced in V5.10) using a single setting.
o Added option for members who can use different resizing options so they can choose which settings to use (eg, standard or different) when attaching an image to posts or PMs. (See attachment)
o Minor bug fixes.
Life doesn't have to be perfect to be wonderful ...

Slava
Ukraini!
"Before you allow people access to your forum, especially in an administrative position, you must be aware that that person can seriously damage your forum. Therefore, you should only allow people that you trust, implicitly, to have such access." -Douglas

petewadey

Hi,
I'm getting the attached failed tests when trying to install the mod? Should I uninstall the previous version first?
Thanks

GL700Wing

#291
Quote from: petewadey on February 03, 2021, 03:46:55 AM
I'm getting the attached failed tests when trying to install the mod? Should I uninstall the previous version first?

Yes - you should always install the previous version of a mod unless it specifically offers an upgrade option.


I've installed this mod on a fresh install of SMF 2.0.18 and on several forums running SMF 2.0.17 (these forums have between 110 and 140 other mods installed) without encountering any errors during the installation.

The errors you're seeing are most likely caused by the code this mod is trying to change having been changed by one or more other mods you have installed.

You could try uninstalling some of the other mods but you may encounter the same issues when you try and reinstall them - best bet is to use the following instructions: https://wiki.simplemachines.org/smf/Error_in_mod_installation
Life doesn't have to be perfect to be wonderful ...

Slava
Ukraini!
"Before you allow people access to your forum, especially in an administrative position, you must be aware that that person can seriously damage your forum. Therefore, you should only allow people that you trust, implicitly, to have such access." -Douglas

petewadey

Thanks, I've done that and all seems well.

GL700Wing

Life doesn't have to be perfect to be wonderful ...

Slava
Ukraini!
"Before you allow people access to your forum, especially in an administrative position, you must be aware that that person can seriously damage your forum. Therefore, you should only allow people that you trust, implicitly, to have such access." -Douglas

petewadey

I changed the script in the text/x-generic file, but not the application/x-httpd-php file. I have just tried to change that file and get the attached warning?

petewadey

Too be a bit more clear, its the php~ file I changed. The error message was on the php file, which I have not yet changed. If that makes sense?

GL700Wing

Quote from: petewadey on February 03, 2021, 05:49:10 AM
I changed the script in the text/x-generic file, but not the application/x-httpd-php file. I have just tried to change that file and get the attached warning?
When reporting an issue it would be helpful if you also included version of SMF you're using and the name of the file that's throwing the error/you're editing ...

Based on the other code shown in the image you attached it looks like you're using SMF 2.0.17 or earlier and the file you're editing is ./Sources/ManageAttachments.php

Quote from: petewadey on February 03, 2021, 10:05:57 AM
Too be a bit more clear, its the php~ file I changed. The error message was on the php file, which I have not yet changed. If that makes sense?
The '.php~' file is a backup file and when you make manual edits you have to edit the main file (ie, the '.php' file).

Also, you need to type the edit exactly as it's shown (or preferably copy/paste it) - the edit you make must include all the '\' characters shown.

$time = filemtime(getAttachmentFilename($rowData[\'filename\'], $rowData[\'id_attach\'], $rowData[\'id_folder\'], false, $rowData[\'file_hash\']));
Life doesn't have to be perfect to be wonderful ...

Slava
Ukraini!
"Before you allow people access to your forum, especially in an administrative position, you must be aware that that person can seriously damage your forum. Therefore, you should only allow people that you trust, implicitly, to have such access." -Douglas

petewadey

Sorry I wasn't clear enough. It is in fact SMF 2.0.18 I'm using and it is the Sources/ManageAttachments.php that I'm trying to edit. I will try again with the code you have attached. Many thanks

petewadey

The code you just posted worked. Thanks.
It differs from the code I tried to use before which was
{
$time = filemtime(getAttachmentFilename($rowData['filename'], $rowData['id_attach'], $rowData['id_folder'], false, $rowData['file_hash']));
$link .= sprintf('%1$s?action=dlattach;topic=%2$d.0;attach=%3$d;ts=%4$d', $scripturl, $rowData['id_topic'], $rowData['id_attach'], $time);
}



GL700Wing

Quote from: petewadey on February 03, 2021, 05:12:22 PM
The code you just posted worked. Thanks.
It differs from the code I tried to use before which was <snip>
I'm glad you've got it working although what you've posted doesn't match what is working on my SMF 2.0.17 and SMF 2.0.18 forums - if this mod was already installed when you updated to SMF 2.0.18 it would have prevented the SMF 2.0.18 update from correctly updating that function in ./Sources/ManageAttachments.php.

You can confirm this by checking the full block of code for that function which, with this mod installed, should be as follows:
'function' => function($rowData) use ($modSettings, $context, $scripturl)
{
$link = '<a href="';

// In case of a custom avatar URL attachments have a fixed directory.
if ($rowData['attachment_type'] == 1)
$link .= sprintf('%1$s/%2$s', $modSettings['custom_avatar_url'], $rowData['filename']);

// By default avatars are downloaded almost as attachments.
elseif ($context['browse_type'] == 'avatars')
$link .= sprintf('%1$s?action=dlattach;type=avatar;attach=%2$d', $scripturl, $rowData['id_attach']);

// Normal attachments are always linked to a topic ID.
else
{
$time = filemtime(getAttachmentFilename($rowData['filename'], $rowData['id_attach'], $rowData['id_folder'], false, $rowData['file_hash']));
$link .= sprintf('%1$s?action=dlattach;topic=%2$d.0;attach=%3$d;ts=%4$d', $scripturl, $rowData['id_topic'], $rowData['id_attach'], $time);
}

$link .= '"';

// Show a popup on click if it's a picture and we know its dimensions.
if (!empty($rowData['width']) && !empty($rowData['height']))
$link .= sprintf(' onclick="return reqWin(this.href' . ($rowData['attachment_type'] == 1 ? '' : '+ \';image\'') . ', %1$d, %2$d, true);"', $rowData['width'] + 20, $rowData['height'] + 20);

$link .= sprintf('>%1$s</a>', preg_replace('~&amp;#(\\\\d{1,7}|x[0-9a-fA-F]{1,6});~', '&#\\\\1;', htmlspecialchars($rowData['filename'])));

// Show the dimensions.
if (!empty($rowData['width']) && !empty($rowData['height']))
$link .= sprintf(' <span class="smalltext">%1$dx%2$d</span>', $rowData['width'], $rowData['height']);

return $link;
},
Life doesn't have to be perfect to be wonderful ...

Slava
Ukraini!
"Before you allow people access to your forum, especially in an administrative position, you must be aware that that person can seriously damage your forum. Therefore, you should only allow people that you trust, implicitly, to have such access." -Douglas

Advertisement: