Вход • Регистрация

Черные поля при изменении размера изображений

  • 16 марта 2015 г.
  • При ресайзе изображений, если исходные пропорции не подходят, то на картинке создаются поля - черного цвета. Кто нибудь может знает где можно изменить этот цвет - например на белый?
  • 16 марта 2015 г.
  • Это известный баг, или "особенность" пхпшной функции resize. Мы как-то сражались на одном сайте, обгуглились, но по-моему так и не победили. Там надо в ядро интерпретатора на хостинге лезть, вроде
  • 17 марта 2015 г.
  • Вывод - используйте ресайз по меньшей стороне + обрезать по размеру необходимого изображения.
    • 17 марта 2015 г.
    • Это я знаю )) Но мне надо не по меньшей стороне.
      • 17 марта 2015 г. , редакция: 17 марта 2015 г.
      • Тогда наращивайте белым цветом картинку сами до нужных пропорций в графическом редакторе. Но это более трудозатратно.
        • 17 марта 2015 г.
        • я этот вопрос для того и задал - что вручную несколько сотен картинок не хочется обрабатывать в редакторе.
          Но в общем то мы вроде уже близко к решению этой проблемы - если все получится, выложу тут решение.
          • 17 марта 2015 г.
          • Можно в фотошопе поставить пакетную обработку
            • 17 марта 2015 г.
            • Я сторонник пакетной обработки, после фотошопа странички меньше весят - а это есть ГУТ!
  • 17 марта 2015 г.
  • Цитата
    Можно в фотошопе поставить пакетную обработку


    Можно но вопрос не об этом.
  • 17 марта 2015 г. , редакция: 17 марта 2015 г.
  • В общем задача решена. Если кому интересно - то описание будет чуть позже.
    • 17 марта 2015 г.
    • Дмитрий интересен данный вопрос тоже, я года полтора назад тоже создавал такую тему
  • 18 марта 2015 г. , редакция: 18 апреля 2015 г.
  • Заливка полей черным цветом - это не баг и не фича интерпретатора на хостинге, изменение цвета можно реализовать при помощи функции crop (файл includes/image.php), но "из коробки" она реализована весьма необычно.

    Допустим, нужно обрезать картинку 120*200 до размера 150*150, расположив изображение по центру.

    Очевидный подход: Создать новое изображение-приемник 150*150, и скопировать в него оригинальное изображение, сдвинув его относительно приемника на нужную величину. Для этого есть функция imagecopy ( приемник, источник, x приемника, y приемника, x источника, y источника, ширина источника, высота источника ) в нашем случае это будет: imagecopy ($out, $original, 15, -25, 0, 0, 120, 200);

    Существующий подход: В функции crop (при заданных начальных условиях) будет сделан такой вызов: imageCopy($out, $original, 0, 0, -15, 25, 150, 150);

    То есть, во-первых, ширина и высота источника задаются 150*150, а поскольку ширина исходной картинки в нашем примере 120, скопировать из оставшейся полоски в 30 пикселей ничего не удастся, и она окажется черной.

    Во-вторых, никакого смещения относительно приемника нет - копирование всегда происходит в верхний левый угол 0, 0, а смещается сама область копирования в источнике, здесь - влево на 15 пикселей от нуля, где, опять же, изображение отсутствует. В итоге слева и справа получим черные полосы по 15 пикселей.

    Желающим перейти от второго подхода к первому требуется:

    1. Поменять местами уменьшаемое и вычитаемое при вычислении смещения:
    Код
    case 'bottom':
    $y = $height - $info[1] - (int)$sy;
    break;
    case 'middle':
    $y = ceil($height/2) - ceil($info[1]/2) + (int)$sy;
    break;

    case 'right':
    $x = $width - $info[0] - (int)$sx;
    break;
    case 'center':
    $x = ceil($width/2) - ceil($info[0]/2) + (int)$sx;
    break;


    2. Заменить существующий вызов imageCopy на imageCopy($out, $original, $x, $y, 0, 0, $info[0], $info[1]);

    3. Залить подложку нужным цветом (или шахматкой, или расписать под хохлому):
    Код
    else // это ветка для не png картинок
    {
    imagefill($out, 0,0,0xffffff); // заливаем белым цветом
    $original = @imageCreateFromString(file_get_contents($original));
    imagealphablending($out , false);
    imagesavealpha($out , true);
    }


    Ниже целиком приведена обновленная функция crop.
    Код
    <?php
    public static function crop($original, $width, $height, $quality, $vertical, $sy, $horizontal, $sx)
    {
    $original_url = $original;
    $original = urldecode($original);
    $info = @getImageSize($original);

    if (! $info)
    return false;
    switch(trim($vertical))
    {
    case 'bottom':
    $y = $height - $info[1] - (int)$sy;
    break;
    case 'middle':
    $y = ceil($height/2) - ceil($info[1]/2) + (int)$sy;
    break;
    default:
    $y = (int)$sy;
    break;
    }
    switch (trim($horizontal))
    {
    case 'right':
    $x = $width - $info[0] - (int)$sx;
    break;
    case 'center':
    $x = ceil($width/2) - ceil($info[0]/2) + (int)$sx;
    break;
    default:
    $x = (int)$sx;
    break;
    }
    $out = imageCreateTrueColor($width, $height);

    //png
    if($info[2] == 3)
    {
    imagefill($out, 0, 0, imagecolorallocatealpha ($out, 0, 0, 0, 127));
    $original = imagecreatefrompng($original);
    imagesavealpha($out, true);
    }
    else
    {
    imagefill($out, 0,0,0xffffff);
    $original = @imageCreateFromString(file_get_contents($original));
    imagealphablending($out , false);
    imagesavealpha($out , true);
    }

    imageCopy($out, $original, $x, $y, 0, 0, $info[0], $info[1]);

    switch ($info[2])
    {
    case 1:
    imageGIF($out, $original_url);
    break;

    case 2:
    imageJPEG($out, $original_url, $quality);
    break;

    case 3:
    imagePNG($out, $original_url);
    break;
    }

    imageDestroy($out);
    imageDestroy($original);
    return true;
    }


    Всем спасибо! Приятного использования
  • 19 марта 2015 г.
  • А давайте предложим реализовать решение в дистрибутиве.
    Виталий, как думаете?
    • 19 марта 2015 г.
    • Я уже предложил заливать по умолчанию белым.
      На самом деле меня дезинформировал Garik, который в свое время занимался этим вопросом на одном проекте. А вот Марина говорит, что это не проблема и она всегда в ТП давала всем жаждущим инструкции, подобные Дмитриевым.
  • 06 мая 2015 г.
  • Два часа сегодня убил. Половина изображения белым заливалась, а вторая - чёрным. Спасибо, Dmitry (weissfl), работает! и чего я раньше не зашёл, хоккей бы посмотрел нормально
  • 27 сентября 2015 г.
  • Пригодилось сегодня! И правда, почему в коробке не сделать такое сразу?
  • 20 января 2016 г.
  • А кто-нибудь смотрел как обстоят дела в 6.0? Сегодня на 6.0.0.5 настроил в обработке изображений следующее:
    1. Изменить пропорционально 150х150
    2. Обрезать 150х150, от центра 0px, от центра 0px.

    Должно вроде как получиться изображение вписанное в квадрат, а пустые поля (если изображение не квадратное) заполниться по краям цветом. НО получил то что в прикрепленном файле!

    Решил воспользоваться схемой Dmitry (weissfl), НО не тут то было... там теперь всё по другому!

    Кто-нибудь решил эту проблему с обрезкой? и как теперь изменить цвет заливки на белый?
  • 22 января 2016 г.
  • Неужели у меня у одного такая проблема возникла на 6.0?
    • 22 января 2016 г.
    • Нет. Это у всех так.
      Для решения нужно править класс режущий картинки.
      Но копаться в нем явно некто не хочет. Да и из опыта понятно, что вы просто не верно настраиваете обезку картинок.
      • 22 января 2016 г.
      • Евгений, а как правильно? я тоже всегда с этими картинками мучаюсь
      • 22 января 2016 г.
      • Правда... а как правильно тогда настраивать? Просто когда правил файл includes/image.php в 5-й версии по инструкции DMITRY (WEISSFL) то всё работало как надо с указанными мной настройками.
        Тем более не пойму что я такого с настройках сделал (они указаны выше в посте моём)... что так обрезает с краев картинку и её сдвигает в сторону сильно (в том же посте во вложении видно)?
      • 22 января 2016 г.
      • Разработчики писали что он ввели новый метод обрезки изображений. Возможно после перехода на 6.х у вас начались проблемы имено из-за нового метода.

        Я делаю в несколько шагов. Сначала уменьшаю (кстати можно оставлять только одно значение, например ширину не вводя высоту, т.е. оставив поле пустым или просто прописав в поле значительно больший размер).
        После чего уже обрезаю по высоте если мне необходимы картинки именно такого размера.
        • 22 января 2016 г.
        • Цитата
          т.е. оставив поле пустым или просто прописав в поле значительно больший размер
          Лучше во избежание возможных проблем с вычислениями вводить именно "значительно больший размер", например 5000. С этим вариантом меньше всего проблем.
        • 22 января 2016 г.
        • Не метод, а библиотеку. Ну и не заменили, а добавили.
          Была только GD, она медленновата. Ввели imagick
          • 22 января 2016 г.
          • Цитата
            Не метод, а библиотеку.

            Я использовал слово метод в значении "способ", а не ООП, если вы хотите чтобы я говорил языком программистов я могу это делать, у меня достаточно квалификации, но вот не уверен что будут и понимать мои ответы простые пользователи. Зачем так не вежливо передергивать...
            • 22 января 2016 г.
            • Я не передергивал, просто уточнил, чтобы у других была полная информация. Против Вас вообще ничего не имел в этом сообщении
          • 22 января 2016 г.
          • Цитата
            Была только GD, она медленновата. Ввели imagick

            Раньше у вас вроде на этой странице все плагины и библиотеки были перечислены. Imagick или ImageMagick я там раньше видел, если мне память не изменяет.
        • 23 января 2016 г. , редакция: 23 января 2016 г.
        • Евгений, то что вы предлагаете (на скриншоте у вас) мне не подходит. Мне нужно, чтобы картинка по центру размещалась, а поля были одинаковыми по ширине или высоте с краев. Если я ставлю в обрезке ОТ ЦЕНТРА 0, то получаю то что на третьей картинке - а это вообще не правильный результат! Если ставлю обрезку СВЕРХУ 0 и СЛЕВА 0, как у вас на скриншоте, ТО работает правильно но не то что нужно мне (на второй картинке).
          А то что нужно мне - это на первой картинке. Нашёл как это сделать! Не знаю насколько это правильно сделал, НО работает и меня устраивает.

          Вот что сделал: в файле /includes/image.php закомментировал в функции function calcPosition строки
          Код
          $x = abs($x);
          $y = abs($y);

          И ЗАРАБОТАЛО!
          • 23 января 2016 г.
          • Наличие черных полей это задумка такая?
            • 23 января 2016 г.
            • Нет, это не моя задумка... так по умолчанию... мне нужно чтобы были не черные, а белые поля. А как поменять заливку полей на белый я не нашел как в 6-ке сделать.
              Мне нужно было просто чтобы картинки была полностью вписана в квадратную область, а поля белым залиты.
              ТП отписалась что рашили проблему с обрезкой от центра и в след.обновлении будет исправлено.
      • 22 января 2016 г.
      • Дополню.

        Я разрабатывал самописный проект ля одного из заказчиков. Там я использовал готовый класс (можно тут почитать).
        Там есть настройки фона изображения если его нужно принудительно увеличить. (демо тут)
        Код
        $foo->image_background_color = '#FF00FF';


        Я не знаю что именно сейчас использует Диафан, но скорее всего что-то похожее и если так, то можно допилить модуль под изменение цвета фона, и боле корректной логики обрезки изображения. Потому что сейчас в этом модуле хромает именно логика.
  • 22 января 2016 г.
  • Евгений, Павел, спасибо! Буду разбираться )

    Евгений, да никак не могу понять именно логику работы этой обрезки.

Новости

  • 24 апреля, среда
  • В новой сборке совершили революцию в структурировании кастомизированной информации в шаблонах, добавили авторегистрацию пользователей, усовершенствовали защиту от спама, актуализировали накопительную скидку, а также улучшили производительность и стабильность работы системы.
  • 12 января
  • После выхода сборки 7.1 мы выпустили уже три патча, в каждом из которых улучшаем административную часть сайта. Сборка DIAFAN.CMS 7.1.3 уже доступна к установке. 
  • 15 декабря 2023 г.
  • Подводим итоги 2023 года. Выпустили новую сборку DIAFAN.CMS 7.1.1, вводим новые тарифы на аренду сайта и коммерческую поддержку и автообновления с января 2024 г., строим планы на будущий год.