FIX: Прозрачность PNG при ресайзе

+23
2.02K
Добрый день. Предлагаю исправление "забытой Богом" библиотеки
/includes/graphic.inc.php
Исправлено поведение при обработке прозрачности в PNG: теперь при изменении размера картинки сохраняется прозрачность
Это актуально для всех ресайзов: аватарки, фотоальбомы, статьи и пр...
необходимо заменить функцию function img_resize

  1. function img_resize($src, $dest, $maxwidth, $maxheight=160, $is_square=false, $watermark=false, $rgb=0xFFFFFF, $quality=80)
  2. {
  3. if (!file_exists($src)) return false;
  4.  
  5. $upload_dir = dirname($dest);
  6. if (!is_writable($upload_dir)){ @chmod($dest, 0755); }
  7.  
  8. $size = getimagesize($src);
  9.  
  10. if ($size === false) return false;
  11.  
  12. $new_width = $size[0];
  13. $new_height = $size[1];
  14.  
  15. if (($new_height <= $maxheight) && ($new_width <= $maxwidth)){
  16. @copy($src, $dest);
  17. return true;
  18. }
  19.  
  20. // Определяем исходный формат по MIME-информации, предоставленной
  21. // функцией getimagesize, и выбираем соответствующую формату
  22. // imagecreatefrom-функцию.
  23. $format = strtolower(substr($size['mime'], strpos($size['mime'], '/')+1));
  24. $icfunc = "imagecreatefrom" . $format;
  25. if (!function_exists($icfunc)) return false;
  26.  
  27. $isrc = $icfunc($src);
  28. if ($rgb==0xFFFFFF)
  29. $rgb = imagecolorallocatealpha($isrc,0x00,0x00,0x00,127);
  30.  
  31.  
  32. if($is_square){
  33. $idest = imagecreatetruecolor($maxwidth,$maxwidth);
  34. imagealphablending($idest, true);
  35. imagesavealpha($idest, true);
  36. imagefill($idest, 0, 0, $rgb);
  37. // вырезаем квадратную серединку по x, если фото горизонтальное
  38. if ($new_width>$new_height)
  39. imagecopyresampled($idest, $isrc, 0, 0, round((max($new_width,$new_height)-min($new_width,$new_height))/2), 0, $maxwidth, $maxwidth, min($new_width,$new_height), min($new_width,$new_height));
  40. // вырезаем квадратную верхушку по y,
  41. if ($new_width<$new_height)
  42. imagecopyresampled($idest, $isrc, 0, 0, 0, 0, $maxwidth, $maxwidth, min($new_width,$new_height), min($new_width,$new_height));
  43. // квадратная картинка масштабируется без вырезок
  44. if ($new_width==$new_height)
  45. imagecopyresampled($idest, $isrc, 0, 0, 0, 0, $maxwidth, $maxwidth, $new_width, $new_width);
  46. } else {
  47. while ($new_width>$maxwidth) { $new_width *= 0.99; $new_height *= 0.99; }
  48. while ($new_height>$maxheight) { $new_width *= 0.99; $new_height *= 0.99; }
  49. $idest = imagecreatetruecolor($new_width, $new_height);
  50. imagealphablending($idest, true);
  51. imagesavealpha($idest, true);
  52. imagefill($idest, 0, 0, $rgb);
  53. imagecopyresampled($idest, $isrc, 0, 0, 0, 0, $new_width, $new_height, $size[0], $size[1]);
  54.  
  55. }
  56.  
  57. if ($watermark) { img_watermark($idest, $new_width, $new_height); }
  58.  
  59. imageinterlace($idest,1);
  60.  
  61. // вывод картинки и очистка памяти
  62. if ($format=='png'){
  63. imagealphablending($idest, true);
  64. imagesavealpha($idest, true);
  65. imagepng($idest,$dest);
  66. }
  67. else{
  68. imagejpeg($idest,$dest,$quality);
  69. }
  70.  
  71. imagedestroy($isrc);
  72. imagedestroy($idest);
  73. return true;
  74. }
Вопрос: почему выкладываю сюда, а не вношу изменения в сам Инстант?
Ответ: не пускают в разработчики, стучался. Общался с Fuze, MadMax. R2 так и не отозвался. Так что пардон, в исходники залить не могу

и обращаю внимание, что после расайза в комопненте фотоальбом, каталога картинка будет иметь расширение jpg, т.к. оно задается в коде модуля принудительно (ищите @img_resize в коде фронтенда). Однако современные браузеры справляются с этой задачей и отображают пнг с прозрачностью

пример vrame.com.ua/frames/frame128.html — основное изображение (слева) с прозрачностью

R124054188127
Z230845734769
U184007373206
+1
Darik Darik 12 лет назад #
спс, актуально +1
+1
reload reload 12 лет назад #
спасибо - полезно +
tarzan:
не пускают в разработчики.. в исходники залить не могу
Что бы добавили то, что вы считаете необходимым, достаточно написать/описать проблему в трекере, или как он там зовется)
Возможно и добавят если решение действительно хорошее и правильное.
Вы представьте если всем начнут давать возможность изменять релиз по своему усмотрению)
зы:Создайте свой мод, закиньте на свой сервер и укажите ссылку для скачивания, если вам уж сильно охота это делать. Правда сомневаюсь что пользоваться такими сборками будут) сами наверное понимаете почему.
+1
Protomoto Protomoto 12 лет назад #
чтоб написать тикет, нужно зарегаться на траке, нужно чтоб туда пустили. А меня не пустили

Я понимаю насколько сложно удовлетворять некоторые тикеты, тем более мелочные - поэтому я готов самостоятельно вносить изменения
Вы представьте если всем начнут давать возможность изменять релиз по своему усмотрению)
почему по своему? Есть коллективная разработка, главный разработчик решает, вносить то или иное изменение.
Создайте свой мод, закиньте на свой сервер и укажите ссылку для скачивания, если вам уж сильно охота это делать
нет, мне совсем не охота. Потом этот мод поддерживать пожизненно? Я хотел бы один раз исправить этот баг и забыть про него. А так самому приходится создавать свою папку с фиксами и накатывать ее на каждую установку. Я, как веб-разработчик, ставлю каждый месяц по паре релизов. Делать дурную работу нет времени. Вот и причина порождения ненужных форков
+1
oll oll 12 лет назад #
почему выкладываю сюда, а не вношу изменения в сам Инстант?
А и не стоит,нет перспективы , как только полная замена класса!
САЙТ PHP CLASS не могу пободрать современный класс для обработки изображений.Останока на двух- и в каждом есть свои недостатки и преимущества.
Двойка покажет ,что в перспективе.
0
Страна Тем Страна Тем 12 лет назад #
Спасибо!
-1
letsgo letsgo 12 лет назад #
Спасибо. Хорошее решение.
0
Эд Эд 12 лет назад #
На версии 1.9 не работает - прозрачность не сохраняется. Заменил код, загрузил картинку на прозрачном фоне - результат плачевный, к сожалению...
Картинко

Еще от автора

Алфавитный указатель в статьях
Возникла необходимость навигации по статьям в категории через Алфавитный указатель (как в Универсальном каталоге) Реализовал.
Субдомен имени пользователя (user.instantcms.ru)
Продолжаем усоциаливать инстант Как сделать имена типа user.instantcms.ru Открываем core/cms.
Прямое имя пользователя (без /users/)
А как можно сделать чтоб адрес выглядел не как сейчас например http://instantcms.ru/users/nikitka просто http://instantcms.
Используя этот сайт, вы соглашаетесь с тем, что мы используем файлы cookie.