Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
If you upload a user picture that respects the limits in maximum size, width and height, it is processed anyway and the processing adds unecessary noise (quite visible) to the picture by compressing it. (It remains otherwise the same width and height, of course.)
Probably
// Check that uploaded file is an image, with a maximum file size
// and maximum height/width.
$info = image_get_info($file->filepath);
list($maxwidth, $maxheight) = explode('x', variable_get('user_picture_dimensions', '85x85'));
if (!$info || !$info['extension']) {
form_set_error('picture_upload', t('The uploaded file was not an image.'));
}
else if (image_get_toolkit()) {
image_scale($file->filepath, $file->filepath, $maxwidth, $maxheight);
}
else if (filesize($file->filepath) > (variable_get('user_picture_file_size', '30') * 1000)) {
form_set_error('picture_upload', t('The uploaded image is too large; the maximum file size is %size kB.', array('%size' => variable_get('user_picture_file_size', '30'))));
}
else if ($info['width'] > $maxwidth || $info['height'] > $maxheight) {
form_set_error('picture_upload', t('The uploaded image is too large; the maximum dimensions are %dimensions pixels.', array('%dimensions' => variable_get('user_picture_dimensions', '85x85'))));
}
Code
function image_scale($source, $destination, $width, $height) {
$info = image_get_info($source);
// don't scale up
if ($width > $info['width'] && $height > $info['height']) {
return FALSE;
}
$aspect = $info['height'] / $info['width'];
if ($aspect < $height / $width) {
$width = (int)min($width, $info['width']);
$height = (int)round($width * $aspect);
}
else {
$height = (int)min($height, $info['height']);
$width = (int)round($height / $aspect);
}
return image_toolkit_invoke('resize', array($source, $destination, $width, $height));
}
Comment | File | Size | Author |
---|---|---|---|
#12 | image_scale.patch | 575 bytes | dvessel |
#11 | image_scale.in.image.inc.5.x.patch | 366 bytes | Chill35 |
#10 | image_scale.in.image.inc.4.7.4.patch | 370 bytes | Chill35 |
Comments
Comment #1
Chill35 CreditAttribution: Chill35 commentedIn the image_scale function why not doing this (added the equal size ) :
// don't scale up
if ($width >= $info['width'] && $height >= $info['height']) {
return FALSE;
}
Comment #2
Chill35 CreditAttribution: Chill35 commentedBigger or equal. I mean.
Comment #3
Chill35 CreditAttribution: Chill35 commentedOne way to solve this is to change one line in the image_scale function, which is not in the user.module. (But I guess there are other ways...)
Change this :
The reason why I think this is a bug to fix is that scenario :
Joe Bloe reads the restrictions, for example that his picture cannot exceed 85 by 85 pixels, goes into Photoshop or another app and resizes his picture EXACTLY to 85 by 85 pixels, makes it look real nice using "Save For Web". Then he uploads it and finds all that noise on it.
Comment #4
Chill35 CreditAttribution: Chill35 commentedIs it just me or the order in which the "if" and "else if" conditions are found in the user module does not seem logical...? It is probably me.
if (image is not a picture) {
say that 'The uploaded file was not an image.'
}
else if (we got the GDI) {
scale down the picture if necessary -- and even when it's not ;)
}
else if (its's still too big in kBytes) {
say it is so too heavy
}
else if (if the picture is too big !!! How could it be if it has been resized ? LOL...) {
say it is too big in height and width
}
Comment #5
Chill35 CreditAttribution: Chill35 commentedI tested the upload user picture widget and indeed there is something wrong with that code, I think.
The 2 last conditions are never met.
Comment #6
Chill35 CreditAttribution: Chill35 commentedI tested with the change in image.inc :
FROM THIS (line 120) :
TO THIS :
And pictures who are the right size (on the limit) are no longer processed : they are exactly the same size (in Bytes, not smaller) and they have no JPEG noise added to them (loss in quality)...
so I guess it works.
Comment #7
webchickThanks for tracking this down! How about making a patch for this?
There are some instructions here: http://drupal.org/patch
There's also some specific stuff if you're on Windows, for example: http://drupal.org/node/60234
Comment #8
Chill35 CreditAttribution: Chill35 commentedHi Webchick!
I have downloaded UnxUtils and will figure out how to create a patch using diff in the next days.
Thanks for the links.
Comment #9
webchickNo problem. :) Feel free to reply back if you get stuck.
Comment #10
Chill35 CreditAttribution: Chill35 commentedThis should fix a bug in includes/image.inc : in a scaling operation, if the target width and height are equal to the width and height of the original image, the image is still processed. The bug as it is experienced now shows that the image is processed unnecessarily. The resulting image has the same dimensions (w and h) but it's smaller in Bytes, it has been compressed again, so there has been quality loss. Pictures that not require scaling and respect KBytes limits should be left alone.
In the user module, Drupal tells the user about certain restrictions concerning the width, height and weight of the picture he may download to represent himself. If the user knows that he must, for example, download a picture not bigger than 85 by 85 pixels, he may create in his favorite image app a picture with this exact dimension and may be puzzled that his image once uploaded shows noise. That’s only one example. With the user uploading pictures with dimensions restrictions, the problem will probably be the same.
I changed the image_scale function :
To that :
The problem is the same in both 4.7.4 and 5.x
The patches attached are for review. They are identical as far as I can tell.
Comment #11
Chill35 CreditAttribution: Chill35 commentedThat's for 5.x.
Comment #12
dvessel CreditAttribution: dvessel commentedNice find. Here's a proper patch. Works as advertised.
Comment #13
Chill35 CreditAttribution: Chill35 commentedComment #14
Steven CreditAttribution: Steven commentedGood catch. Committed to HEAD and 4.7.
Comment #15
(not verified) CreditAttribution: commented