подскажите, как вырезать середину изображения.

  • Автор темы Духовность™
  • Дата начала

Духовность™

Guest
Духовность™
не надо резать середину общую, высчитаваешь отношение высоты оригинала в высоте нужного изображения, так же получаешь индекс для отношения ширины. выбрать меньши и отресазить картинку с учётом этого индекса. получается одна сторона нужного размера, другая забольшая. затем режем кусок, по одной оси у нас с размерами всё ок, для другой вырезаем с обрезая лишние отступы.

хотя, наверное, можно и без промежуточного этапа, но к чёрту, нужно писать человекопонятный код, а не машино-ресурсооптимизированный алгоритм.
что-то не совсем догоняю..

Сначала я вычисляю отношение высоты оригинала к высоте нужного изображения:
PHP:
$ratio_width  = $this->actualWidth  / $this->resizedWidth;
$ratio_height = $this->actualHeight / $this->resizedHeight;
выбираю меньший:
PHP:
$ratio = min($ratio_width, $ratio_height);
а дальше что я должен сделать? вычислить область считывания?
 

Активист

Активист
Команда форума
Ну смотри.
Задача: сделать миниатюру строго 100x100.

1. Есть сурс 1500x1000
2. ratio = max(100/1500, 100/1000); = 0.1
3. Получаем картинку: 1500*0.1x1000*0.1 = 150x100
4. Вычислить сдвиг по x 150-100 = 50, по y 100-100 = 0
5. в функцию ресайза вставляем координаты x1, y1, x2, y2. т.е., 50/2, 0/2, 100, 100.
(делим на два потму как нужно отразать ровно половину от излишки сверху и снизу/справа и слева
 

baev

‹°°¬•
Команда форума
Активист, так у него так и делается.

Вообще, вся тема на пустом месте раздута…
 

Духовность™

Guest
baev
Ну если Вы умный и все знаете, то либо ответьте как делать, либо помолчите, ок? Раздута она из-за умников, которые уже достали своими многозначительными ничего не значащими репликами. Толку от ваших реплик - меньше нуля.

Активист
Я попробовал твой алгоритм, но что-то не так работает. Я добился генерации изображений 100х100, но мне нужно генерировать не изображения с прямопропорциональными соотношениями сторон. А задавая иные размеры получившийся результат растягивается. Т.е. алгоритм ещё пилить и пилить.
 

iceman

говнокодер
Духовность™
тебе нужно открыть учебник по Геометрии и его пилить.
и определится что ты хочешь.
 

prolis

Новичок

Духовность™

Guest
Духовность™
тебе нужно открыть учебник по Геометрии и его пилить.
и определится что ты хочешь.
Я прекрасно знаю, что я хочу - я описал это в первом посте. И не надо мне советовать, что мне пилить. Ещё один умник.
 

baev

‹°°¬•
Команда форума
Духовность™, тема раздута из-за того, что кто-то сразу поленился пояснить, в чём конкретно проблема.
Вот это: «данный алгоритм дает сбой - вертикальное горизонтальное изображение размером 500х499 дает белиберду» — это не описание проблемы.
(«Вертикальное горизонтальное изображение» — это вообще шедевр…)

Здесь:
PHP:
if ($this->actualWidth > $this->actualHeight)
{
    $width = floor($this->resizedHeight * $this->ratio);
            
    $thumbnailResource = imageCreateTrueColor($this->resizedWidth, $this->resizedHeight);

    imageCopyResampled(
        $thumbnailResource,
            $this->getSourceImage(),
            0, 0, // позиции х и у с которых начинать вставлять в принимающий прямоугольник
            ($this->actualWidth - $width) / 2, 0, // позиции х и у с которых начинать отсчет считывания прямоугольника
            $width, // ширина принимающего прямоугольника
            $this->resizedHeight, // высота принимающего прямоугольника
            $this->actualWidth, // ширина считываемого прямоугольника
            $this->actualHeight // высота считываемого прямоугольника
    );
— я не вижу ошибок в алгоритме.
Другое дело, что из этого кода не видно, как считается $this->ratio, но с этим — уже явно сюда:
http://phpfaq.ru/debug
 

Духовность™

Guest
— я не вижу ошибок в алгоритме.
ошибка тут в этом:
PHP:
($this->actualWidth - $width) / 2
я не пойму, как вычислит х координату, начиная с которой надо читать исходное изображение. Приведенный выше код вычисляет координату в рамках координат изображения, которое должно получиться. А надо читать большой исходник.
 

baev

‹°°¬•
Команда форума
Духовность™, по-моему, Вы сами себя запутали.
Из мануала:
In other words, imagecopyresampled() will take an rectangular area from src_image of width src_w and height src_h at position (src_x,src_y) and place it in a rectangular area of dst_image of width dst_w and height dst_h at position (dst_x,dst_y).
Мне в Вашем коде только одно не понятно: зачем там одновременно $width и $this->resizedWidth?
 

Духовность™

Guest
И где тут ошибка?
ошибка в том, что из ширины исходного изображения я отнимаю ширину текущего изображения и делю все это на 2. Т.е. при ширине изображения в 1280 я задаю точку считывания где то в районе 560 и у меня считывается фактически правая часть изображения.

А мне нужно из ширины текущего изображения отнять число, пропорциональное ширине получившейся миниатюры. Как-то так.

PS: Ну не знаю я геометрию, не знаю.
 

baev

‹°°¬•
Команда форума
Так, кажется я понял.
Метод $this->getSourceImage() должен возвращать уже уменьшённое изображение.
 

baev

‹°°¬•
Команда форума
флоппик, и?
В названии метода написано, что нельзя уменьшать?

А для функции imageCopyResampled(), вообще, — что на вход подаётся, то и называется «исходным изображением».
 

Духовность™

Guest
Духовность™, по-моему, Вы сами себя запутали.
не спорю. я сейчас взорвусь уже.


Вот мой код, который якобы должен масштабировать и обрезать изображение альбомной направленности. Я в упор не могу понять, как вычислить Х-координату:
PHP:
<?php
error_reporting(E_ALL);

// параметры будущего изображения
$resizedWidth = '80';
$resizedHeight = '120';
// путь к оригиналу
$src_path = 'D:/big.jpeg';

// источник
$src = imageCreateFromJPEG($src_path);
// ширина источника
$actualWidth  = imagesx($src);
// выстота источника
$actualHeight = imagesy($src);

// ресурс новго изображения
$thumbnailResource = imageCreateTrueColor($resizedWidth, $resizedHeight);
// отношение
$ratio = $actualWidth / $actualHeight;

// ** где-то тут ошибка ***
$width = floor($resizedHeight * $ratio);

$xpos = ($actualWidth - $width) / 2;
// ** где-то тут ошибка ***

imageCopyResampled(
	$thumbnailResource,
    $src,
    0, 0, // позиции х и у с которых начинать вставлять в принимающий прямоугольник
    $xpos, 0, // позиции х и у с которых начинать отсчет считывания прямоугольника
    
    $width, // ширина принимающего прямоугольника
    $resizedHeight, // высота принимающего прямоугольника
    $actualWidth, // ширина считываемого прямоугольника
    $actualHeight // высота считываемого прямоугольника
);

imageJPEG($thumbnailResource, 'D:/smal.jpeg', 100);
 

флоппик

promotor fidei
Команда форума
Партнер клуба
Ну, вообще, когда метод называется ПолучитьИсходноеИзображение() возвращать обработанное несколько некрасиво, как мне кажется. Через полгода не вспомнить, что метод делает не то, о чем сообщает в названии.
 

Духовность™

Guest
Ну, вообще, когда метод называется ПолучитьИсходноеИзображение() возвращать обработанное несколько некрасиво, как мне кажется. Через полгода не вспомнить, что метод делает не то, о чем сообщает в названии.
Это не мой код, я допиливаю.
 
Сверху