News:

Bored?  Looking to kill some time?  Want to chat with other SMF users?  Join us in IRC chat or Discord

Main Menu

SMF converts attachments from .jpg to .png

Started by rawonam, May 19, 2010, 03:38:52 AM

Previous topic - Next topic

Kays

Quote
If anyone is willing to post or email an unofficial fix for this, I'd be most grateful.  I saw Kays' mod, but converting all graphic file types to JPG is not what I want to do.

That mod already does have the option to preserve the file type if reencoding occurs.

If at first you don't succeed, use a bigger hammer. If that fails, read the manual.
My Mods

rawonam

OK, here we go, what I did for myself:

First of all, we need to fix the wrong sizes:

Open Subs-Post.php, find:
$size = @getimagesize($attachmentOptions['destination']);

Insert before:
// reencode before updating db info
    $max_width = 1000;
    $max_height = 800;

    $size = @getimagesize($attachmentOptions['destination']);
   
    // Reencode it if it smells bad.
    if ( isset($validImageTypes[$size[2]]) &&
         ( !checkImageContents($attachmentOptions['destination']) ||
          ($size[0]>$max_width || $size[1]>$max_height) && function_exists('imagecreatefrom'.$validImageTypes[$size[2]]) ) )
    {
            if (!reencodeImage($attachmentOptions['destination'], $max_width, $max_height))
            {
                    require_once($sourcedir . '/ManageAttachments.php');
                    removeAttachments(array(
                            'id_attach' => $attachmentOptions['id']
                    ));
                    $attachmentOptions['id'] = null;
                    $attachmentOptions['errors'][] = 'could_not_upload';

                    return false;
            }
    }

$attachmentOptions['filesize'] = filesize($attachmentOptions['destination']);
///////////////


In this code I introduced width and height limits, just change the values in the first two lines for your needs. It will reencode any image that has suspicious content or is larger than those limits.
If this image format is not supported, then it will ignore the size limits and attach the image as is, but in case of suspicious content an error will be displayed and the image won't be attached.

Next find:
width = {int:width},
Insert before:
size = {int:size},
Then find:
'width' => (int) $attachmentOptions['width'],
Insert before:
'size' => (int) $attachmentOptions['filesize'],

This will update the database if the file was reencoded to show correct size and dimensions.

To disable reencoding call that was already in the code, find:
if (isset($validImageTypes[$size[2]]) && !checkImageContents($attachmentOptions['destination']))
And insert before:
if (0)

Close Subs-Post.php.

Open Subs-Graphics.php, find:

Find:
function reencodeImage($fileName)
{
if (!resizeImageURL($fileName, $fileName . '.tmp', null, null))


Replace with:
function reencodeImage($fileName, $max_width, $max_height)
{
    // prevent scaling of smaller images
    $size = @getimagesize($fileName);
    if ( $size[0]<=$max_width && $size[1]<=$max_height )
    {
        $max_width = null;
        $max_height = null;
    }

if (!resizeImageURL($fileName, $fileName . '.tmp', $max_width, $max_height))

Find:
resizeImage($src_img, $destinationFile, imagesx($src_img), imagesy($src_img), $max_width === null ? imagesx($src_img) : $max_width, $max_height === null ? imagesy($src_img) : $max_height, true);

Replace with:
resizeImage($src_img, $destinationFile, imagesx($src_img), imagesy($src_img), $max_width === null ? imagesx($src_img) : $max_width, $max_height === null ? imagesy($src_img) : $max_height, true, $default_formats[$sizes[2]]);

This will pass current file format to the resizing function.

Find:
function resizeImage($src_img, $destName, $src_width, $src_height, $max_width, $max_height, $force_resize = false)
Replace with:
function resizeImage($src_img, $destName, $src_width, $src_height, $max_width, $max_height, $force_resize = false, $format = '')

Then find:
  if (!empty($modSettings['avatar_download_png']))

Insert before:
  if (!empty($format) && function_exists('image'.$format)) // mymod
  {
$imagefunc = 'image'.$format;
  $imagefunc($dst_img, $destName);
}
else

That's it. After these changes, the behavior will be as follows:
Reencoding will save the file in the same format as the source file, if it is supported by your server. Otherwise it will be saved as JPG/PNG (depending on whether "Use PNG for resized avatars" is checked).
Resized avatars will also be saved in the source format, if possible.

If you need a bit different behavior, tell me.

Kays

I don't know why you just didn't use the mod since it does all that already.

One problem with what you've got is that when the reencoding is done the attachment is already in the database. So if the file format or size is changed the database needs to be updated.


     if (!empty($format) && function_exists('image'.$format)) // mymod
     {
      $imagefunc = 'image'.$format;
        $imagefunc($dst_img, $destName);
   }
   else


This won't work with bitmap images.

Also did you change the location of the memory increase?

If at first you don't succeed, use a bigger hammer. If that fails, read the manual.
My Mods

rawonam

Quote from: Kays on May 20, 2010, 09:40:12 AM
I don't know why you just didn't use the mod since it does all that already.
I just want to know what happens, I don't trust automatic mod installations. Maybe I should have looked at your mod, but initially I had thought my changes would be simplier and insignificant.

Quote from: Kays on May 20, 2010, 09:40:12 AM
One problem with what you've got is that when the reencoding is done the attachment is already in the database. So if the file format or size is changed the database needs to be updated.
I do deal with it, I moved the reencoding call before DB update, and if there are changes, the DB is updated with correct values.

Quote from: Kays on May 20, 2010, 09:40:12 AM

     if (!empty($format) && function_exists('image'.$format)) // mymod
     {
      $imagefunc = 'image'.$format;
        $imagefunc($dst_img, $destName);
   }
   else

This won't work with bitmap images.
You mean because there is no "imagebmp()"? I know, then it'll default to JPG/PNG after else. Also, imagecreatefrombmp() function that is supplied with SMF is really bad, I'd rather have my bitmaps unchanged anyway, because bmps really get totally corrupt. But just in case the bmp is very large I still might want to reconvert it, at least to save space.

Quote from: Kays on May 20, 2010, 09:40:12 AM
Also did you change the location of the memory increase?
What do you mean?

engr_dood

#24
Quote from: Kays on May 20, 2010, 09:40:12 AM
I don't know why you just didn't use the mod since it does all that already.

I tried the mod in my test forum, which is a snapshot of our actual forum from a few months back.  I am using the Inline Attachments mod by Spuds.  After installing the Resize Attached Images mod, all the inline graphics, which normally show up as thumbnails, were shown as icons.  I changed an option in the Resize Attached Images mod so they were again displayed as thumbnails, but the displayed thumbnails were of a lower quality than before.  I began to worry that there would be conflicts between the two mods, so I uninstalled the Resize Attached Images mod.  After doing so, I compared the appearance of the actual and test forums.  It appears that every thumbnail in the test forum (the one that had the Resize Attached Images mod installed) is still of a lower quality than the original, even after uninstalling the Resize Attached Images mod.  So the Resize Attached Images mod doesn't appear to be a viable solution in all cases.

kmarabu

Maybe you have same problem as this - http://www.simplemachines.org/community/index.php?topic=373188.msg2558316#msg2558316

If you have issues with re-encoding attached images to PNG - check count of attachment folders used. With default settings after install RC2 all worked fine (without any re-encode), but when you add additional path as attachment folder... SMF start re-encoding.

Norv

SMF re-encodes images which fail a set of extreme security checks (it does not depend on how many attachment folders in fact, it may have been a coincidence for you...).
The issue should be solved in the next version.
To-do lists are for deferral. The more things you write down the later they're done... until you have 100s of lists of things you don't do.

File a security report | Developers' Blog | Bug Tracker


Also known as Norv on D* | Norv N. on G+ | Norv on Github

noaccess

Isn't there another way to do this and still continue with your security check? The file sizes increase too much. A small file that was initially 100kb JPG turns into a 300KB PNG,  :o

Joshua Dickerson

Come work with me at Promenade Group



Need help? See the wiki. Want to help SMF? See the wiki!

Did you know you can help develop SMF? See us on Github.

How have you bettered the world today?

Norv

Yes, this should be solved too, in the next version.
To-do lists are for deferral. The more things you write down the later they're done... until you have 100s of lists of things you don't do.

File a security report | Developers' Blog | Bug Tracker


Also known as Norv on D* | Norv N. on G+ | Norv on Github

naan

next version next version next version
:o :o :o :o :o :o



i want it now!
i want it now!

I have the same problem:
And i have not a webspace with more GB's.
http://www.simplemachines.org/community/index.php?topic=396064.0
naan.de // psaForum and other things.

Norv

To-do lists are for deferral. The more things you write down the later they're done... until you have 100s of lists of things you don't do.

File a security report | Developers' Blog | Bug Tracker


Also known as Norv on D* | Norv N. on G+ | Norv on Github

Advertisement: