Здравствуйте, дорогие друзья. Сегодня я покажу как быстро и легко можно написать класс, с помощью которого можно изменять изображения. Данный класс пригодится практически в каждом проекте, который вы будете делать в будущем. Я постараюсь создать класс, который будет не только соответствовать всем требованиям, но и будет легко расширяемым.
Введение
Для начала мы должны сформулировать главные требования, предъявляемые к нашему классу:
1. Класс должен быть легок в использовании
2. Не зависеть от формата (то есть открывать, изменять и сохранять разные форматы изображений)
3. Необходимо реализовать "умный" алгоритм изменения изображений. (При котором искажения изображения будет минимальным.)
Замечание: Данная статья это не прямое руководство, а всего лишь советы и подсказки к созданию класса для редактирования изображений.
Давайте закончим Введение и наконец приступим.
Шаг 1. Подготовка
Начнем с простого. Создаем в нашей рабочей папке два файла, один из которых называем index.php, а другой - resize-class.php.
Шаг 2. Подготовка
Для того, чтобы увидеть как на практике мы будем изменять изображения давайте откроем файл index.php и добавим туда сл. строки кода.
Между строк: спонсором данного поста является техцентр "Van Auto", который находиться по адресу Москва, ул. Сосинская, д. 43, (м. Волгоградский проспект), там я и нашел лобовое стекло на audi 100, в тот момент когда мне это было нужно больше всего.
Как вы видите, данный код - простейшее использование нашего класса. Мы открываем исходное изображение, затем указываем необходимые параметры (ширину, высоту, тип выходного изображения). Затем сохраняем изображение в нужном нам формате с указанным качеством. Сохраняем данный код в index.php и закрываем файл.
Шаг 3. Создаем основу для нашего класса
Суть Объектно-Ориентированного программирования (ООП) заключается в том, что один и тот же класс мы можем использовать несколько раз. В случае если необходимо дополнить класс новым функционалом, мы можем запросто его расширить, дописав необходимые строчки кода.
Давайте приступим к непосредственному созданию нашего класса. Откроем файл resize-class.php. Ниже показан пример основы для нашего класса, который мы назовем "resize". Обратите внимание на строку "// *** Class variables" где в дальнейшем будут располагаться переменные, необходимые нашему классу.
Метод _construct, называемый конструктором, это специальный метод класса который вызывается при создании объекта данного класса.
При описании данного метода очень важно не упустить двойное подчеркивание.
Шаг 4. Конструктор
Давайте немного изменим наш класс, добавив в него несколько переменных: $image, $width и $height. При открытии изображения мы автоматически задаем эти переменные.
Методы imagesx и imagesy будут использовать часть стандартной библиотеки в PHP - GD. Они возвращают ширину и высоту изображения.
Шаг 5. Открытие изображения
На предыдущем шаге мы вызывали метод openImage, а на этом шаге мы опишем этот метод. В зависимости от типа изображения скрипт должен определять какую функцию библиотеки GD вызвать. Это легко реализовать с помощью конструкции switch.
Шаг 6. Как изменять изображения
Теперь самое интересное... В этом шаге я всего-лишь объясню то, что мы будем делать в дальнейшем - поэтому НИКАКИХ домашних заданий здесь не будет ;) В следующем шаге мы создадим public-метод который и будет изменять пропорции наших изображений. Нам необходимо сохранять передаваемую высоту и ширину (чтобы потом использовать). На этом моменте давайте остановимся и немного поразмышляем. Но если в нашем распоряжении десятки-сотни не похожих друг на друга изображений по размерам? Если мы хотим изменять размер всех и сразу? Задавая каждому из них строгий размер, мы будем очень сильно их искажать.
In real life существует несколько методом решения данной проблемы:
1. Сохранять пропорции наших изображений
2. Сохранять приближенный размер изображения, удаляя (обрезая) все лишнее
Вы можете использовать любой из этих методов, в зависимости от того, что нужно именно вам.
Шаг 7. Ресайз изображений. Сделаем это!
Так. У нас есть 2-а способа, чтобы изменять изображения. Первый получает оптимальную высоту и ширину для нашего нового изображения. Высота и ширина возвращается как массив со значениями. Второй использует реальный размер нашего изображения.
Мы так же сохраним результат работы функции imagecreatetruecolor в переменной класса. Поэтому добавляем в наш класс строку ‘private $imageResized;’.
Все изменения с изображениями производятся с помощью GD Library. Многие реализуемые нами методы используют функции данной библиотеки.
Шаг 8. "Работа над ошибками"
Пока вы читали предыдущие 7 шагов, я быстренько набросал method-роутер для нашего класса. Вот он:
Шаг 9. Оптимальные изменения
Мы уже обсудили что делаю эти 4 метода (те, что описаны выше). Теперь мы может математически высчитать "оптимальные изменения".
Шаг 10. CROP
Если вам необходимо обрезать изображение, то придется дописать еще один маленький метод.
Шаг 11. Сохранение изображений.
Ну вот в принципе и все. Осталось только сохранить наше изображения. Для этого добавляем еще один метод:
Исходник кода можно скачать здесь:
Вы всегда можете почитать статью QR-коды с помощью PHP
Оригинал статьи на английском находится здесь.
Введение
Для начала мы должны сформулировать главные требования, предъявляемые к нашему классу:
1. Класс должен быть легок в использовании
2. Не зависеть от формата (то есть открывать, изменять и сохранять разные форматы изображений)
3. Необходимо реализовать "умный" алгоритм изменения изображений. (При котором искажения изображения будет минимальным.)
Замечание: Данная статья это не прямое руководство, а всего лишь советы и подсказки к созданию класса для редактирования изображений.
Давайте закончим Введение и наконец приступим.
Шаг 1. Подготовка
Начнем с простого. Создаем в нашей рабочей папке два файла, один из которых называем index.php, а другой - resize-class.php.
Шаг 2. Подготовка
Для того, чтобы увидеть как на практике мы будем изменять изображения давайте откроем файл index.php и добавим туда сл. строки кода.
Между строк: спонсором данного поста является техцентр "Van Auto", который находиться по адресу Москва, ул. Сосинская, д. 43, (м. Волгоградский проспект), там я и нашел лобовое стекло на audi 100, в тот момент когда мне это было нужно больше всего.
Как вы видите, данный код - простейшее использование нашего класса. Мы открываем исходное изображение, затем указываем необходимые параметры (ширину, высоту, тип выходного изображения). Затем сохраняем изображение в нужном нам формате с указанным качеством. Сохраняем данный код в index.php и закрываем файл.
// *** Подключение класса
include("resize-class.php");
// *** 1) Инициализация\загрузка изображения
$resizeObj = new resize('sample.jpg');
// *** 2) Изменение размера изображения (параметры: exact, portrait, landscape, auto, crop)
$resizeObj -> resizeImage(150, 100, 'crop');
// *** 3) Сохранение изображения
$resizeObj -> saveImage('sample-resized.gif', 100);
Шаг 3. Создаем основу для нашего класса
Суть Объектно-Ориентированного программирования (ООП) заключается в том, что один и тот же класс мы можем использовать несколько раз. В случае если необходимо дополнить класс новым функционалом, мы можем запросто его расширить, дописав необходимые строчки кода.
Давайте приступим к непосредственному созданию нашего класса. Откроем файл resize-class.php. Ниже показан пример основы для нашего класса, который мы назовем "resize". Обратите внимание на строку "// *** Class variables" где в дальнейшем будут располагаться переменные, необходимые нашему классу.
Метод _construct, называемый конструктором, это специальный метод класса который вызывается при создании объекта данного класса.
Class resize
{
// *** Class variables
public function __construct()
{
}
}
При описании данного метода очень важно не упустить двойное подчеркивание.
Шаг 4. Конструктор
Давайте немного изменим наш класс, добавив в него несколько переменных: $image, $width и $height. При открытии изображения мы автоматически задаем эти переменные.
Class resize
{
// *** Переменные класса
private $image;
private $width;
private $height;
function __construct($fileName)
{
// *** Открываем файл
$this->image = $this->openImage($fileName);
// *** Устанавливаем исходные параметры: ширину и высоту.
$this->width = imagesx($this->image);
$this->height = imagesy($this->image);
}
}
Методы imagesx и imagesy будут использовать часть стандартной библиотеки в PHP - GD. Они возвращают ширину и высоту изображения.
Шаг 5. Открытие изображения
На предыдущем шаге мы вызывали метод openImage, а на этом шаге мы опишем этот метод. В зависимости от типа изображения скрипт должен определять какую функцию библиотеки GD вызвать. Это легко реализовать с помощью конструкции switch.
private function openImage($file)
{
// *** Определяем extension
$extension = strtolower(strrchr($file, '.'));
switch($extension)
{
case '.jpg':
case '.jpeg':
$img = @imagecreatefromjpeg($file);
break;
case '.gif':
$img = @imagecreatefromgif($file);
break;
case '.png':
$img = @imagecreatefrompng($file);
break;
default:
$img = false;
break;
}
return $img;
}
Шаг 6. Как изменять изображения
Теперь самое интересное... В этом шаге я всего-лишь объясню то, что мы будем делать в дальнейшем - поэтому НИКАКИХ домашних заданий здесь не будет ;) В следующем шаге мы создадим public-метод который и будет изменять пропорции наших изображений. Нам необходимо сохранять передаваемую высоту и ширину (чтобы потом использовать). На этом моменте давайте остановимся и немного поразмышляем. Но если в нашем распоряжении десятки-сотни не похожих друг на друга изображений по размерам? Если мы хотим изменять размер всех и сразу? Задавая каждому из них строгий размер, мы будем очень сильно их искажать.
In real life существует несколько методом решения данной проблемы:
1. Сохранять пропорции наших изображений
2. Сохранять приближенный размер изображения, удаляя (обрезая) все лишнее
Вы можете использовать любой из этих методов, в зависимости от того, что нужно именно вам.
Шаг 7. Ресайз изображений. Сделаем это!
Так. У нас есть 2-а способа, чтобы изменять изображения. Первый получает оптимальную высоту и ширину для нашего нового изображения. Высота и ширина возвращается как массив со значениями. Второй использует реальный размер нашего изображения.
Мы так же сохраним результат работы функции imagecreatetruecolor в переменной класса. Поэтому добавляем в наш класс строку ‘private $imageResized;’.
Все изменения с изображениями производятся с помощью GD Library. Многие реализуемые нами методы используют функции данной библиотеки.
// *** Добавляем переменную
private $imageResized;
public function resizeImage($newWidth, $newHeight, $option="auto")
{
// *** Получаем оптимальную высоту и ширину - базируясь на $option
$optionArray = $this->getDimensions($newWidth, $newHeight, strtolower($option));
$optimalWidth = $optionArray['optimalWidth'];
$optimalHeight = $optionArray['optimalHeight'];
// *** Resample - create image canvas of x, y size
$this->imageResized = imagecreatetruecolor($optimalWidth, $optimalHeight);
imagecopyresampled($this->imageResized, $this->image, 0, 0, 0, 0, $optimalWidth, $optimalHeight, $this->width, $this->height);
// *** Если опция включена 'crop'
if ($option == 'crop') {
$this->crop($optimalWidth, $optimalHeight, $newWidth, $newHeight);
}
}
Шаг 8. "Работа над ошибками"
Пока вы читали предыдущие 7 шагов, я быстренько набросал method-роутер для нашего класса. Вот он:
private function getDimensions($newWidth, $newHeight, $option)
{
switch ($option)
{
case 'exact':
$optimalWidth = $newWidth;
$optimalHeight= $newHeight;
break;
case 'portrait':
$optimalWidth = $this->getSizeByFixedHeight($newHeight);
$optimalHeight= $newHeight;
break;
case 'landscape':
$optimalWidth = $newWidth;
$optimalHeight= $this->getSizeByFixedWidth($newWidth);
break;
case 'auto':
$optionArray = $this->getSizeByAuto($newWidth, $newHeight);
$optimalWidth = $optionArray['optimalWidth'];
$optimalHeight = $optionArray['optimalHeight'];
break;
case 'crop':
$optionArray = $this->getOptimalCrop($newWidth, $newHeight);
$optimalWidth = $optionArray['optimalWidth'];
$optimalHeight = $optionArray['optimalHeight'];
break;
}
return array('optimalWidth' => $optimalWidth, 'optimalHeight' => $optimalHeight);
}
Шаг 9. Оптимальные изменения
Мы уже обсудили что делаю эти 4 метода (те, что описаны выше). Теперь мы может математически высчитать "оптимальные изменения".
private function getSizeByFixedHeight($newHeight)
{
$ratio = $this->width / $this->height;
$newWidth = $newHeight * $ratio;
return $newWidth;
}
private function getSizeByFixedWidth($newWidth)
{
$ratio = $this->height / $this->width;
$newHeight = $newWidth * $ratio;
return $newHeight;
}
private function getSizeByAuto($newWidth, $newHeight)
{
if ($this->height < $this->width)
// *** Изображения изменяется по ширине (landscape)
{
$optimalWidth = $newWidth;
$optimalHeight= $this->getSizeByFixedWidth($newWidth);
}
elseif ($this->height > $this->width)
// *** Изображение изменяется по высоте (portrait)
{
$optimalWidth = $this->getSizeByFixedHeight($newHeight);
$optimalHeight= $newHeight;
}
else
// *** Изображение изменяется в соответствии с указанными значениями
{
if ($newHeight < $newWidth) {
$optimalWidth = $newWidth;
$optimalHeight= $this->getSizeByFixedWidth($newWidth);
} else if ($newHeight > $newWidth) {
$optimalWidth = $this->getSizeByFixedHeight($newHeight);
$optimalHeight= $newHeight;
} else {
// *** Sqaure being resized to a square
$optimalWidth = $newWidth;
$optimalHeight= $newHeight;
}
}
return array('optimalWidth' => $optimalWidth, 'optimalHeight' => $optimalHeight);
}
private function getOptimalCrop($newWidth, $newHeight)
{
$heightRatio = $this->height / $newHeight;
$widthRatio = $this->width / $newWidth;
if ($heightRatio < $widthRatio) {
$optimalRatio = $heightRatio;
} else {
$optimalRatio = $widthRatio;
}
$optimalHeight = $this->height / $optimalRatio;
$optimalWidth = $this->width / $optimalRatio;
return array('optimalWidth' => $optimalWidth, 'optimalHeight' => $optimalHeight);
}
Шаг 10. CROP
Если вам необходимо обрезать изображение, то придется дописать еще один маленький метод.
private function crop($optimalWidth, $optimalHeight, $newWidth, $newHeight)
{
// *** Поиск центра изображения - используется для резайза
$cropStartX = ( $optimalWidth / 2) - ( $newWidth /2 );
$cropStartY = ( $optimalHeight/ 2) - ( $newHeight/2 );
$crop = $this->imageResized;
//imagedestroy($this->imageResized);
// *** Вырезаем указанный кусочек изображения
$this->imageResized = imagecreatetruecolor($newWidth , $newHeight);
imagecopyresampled($this->imageResized, $crop , 0, 0, $cropStartX, $cropStartY, $newWidth, $newHeight , $newWidth, $newHeight);
}
Шаг 11. Сохранение изображений.
Ну вот в принципе и все. Осталось только сохранить наше изображения. Для этого добавляем еще один метод:
public function saveImage($savePath, $imageQuality="100")
{
// *** Get extension
$extension = strrchr($savePath, '.');
$extension = strtolower($extension);
switch($extension)
{
case '.jpg':
case '.jpeg':
if (imagetypes() & IMG_JPG) {
imagejpeg($this->imageResized, $savePath, $imageQuality);
}
break;
case '.gif':
if (imagetypes() & IMG_GIF) {
imagegif($this->imageResized, $savePath);
}
break;
case '.png':
// *** Приводим качество из диапазона 0-100 к 0-9
$scaleQuality = round(($imageQuality/100) * 9);
// *** Инвертируем качество (0 - наилучшее)
$invertScaleQuality = 9 - $scaleQuality;
if (imagetypes() & IMG_PNG) {
imagepng($this->imageResized, $savePath, $invertScaleQuality);
}
break;
// ... etc
default:
// *** Не указано - не сохраняем
break;
}
imagedestroy($this->imageResized);
}
Исходник кода можно скачать здесь:
Вы всегда можете почитать статью QR-коды с помощью PHP
Оригинал статьи на английском находится здесь.
Для объединения компьютеров Вашего офиса в локальную сеть возьмите сервер для аренды с супербыстрой доставкой - ее осуществление начнется уже через 5 минут после поступления оплаты!