Skip to content

Commit

Permalink
1.3.0
Browse files Browse the repository at this point in the history
- [R] Latest PHP7.4 version. It will not work on PHP8, 'cause in PHP8 Image is `GdImage`, not an abstract `resource`.
- [+] `GdImageInfo::clone()` - "клонирует" Gd-ресурс
- [*] исправлен механизм логгера
- [*] `psr/log` теперь нужен любой версии
- [*] минорные фиксы.
  • Loading branch information
Karel Wintersky committed Aug 27, 2024
1 parent f3a6c14 commit d911e11
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 91 deletions.
19 changes: 19 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,22 @@
# 1.3.0

- Latest PHP7.4 version. It will not work on PHP8, 'cause in PHP8 Image is `GdImage`, not an abstract `resource`.

# 1.2.1

- [+] isValid/isError helper methods

# 1.2.0

- [+] метод `GDImageInfo::setFilename()`
- [+] метод `GDImageInfo::getWH()`
- [+] метод `GDImageInfo::getError()`
- [*] BMP всегда сохраняется с RLE-сжатием

# 1.1

Теперь PNG всегда сохраняется с дефолтным качеством для библиотеки zlib (= -1)

# 1.0

* Работа с файлами (как контейнерами данных) ведется теперь через служебный класс GDImageInfo
Expand Down
7 changes: 5 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
"platform-check": false
},
"require": {
"php": "^7.3|>=8",
"psr/log": "^1.1",
"php": "^7.4",
"psr/log": "*",
"ext-gd": "*"
},
"autoload": {
Expand All @@ -29,5 +29,8 @@
"support": {
"source": "https://github.com/ajur-media/PHP_GDWrapper",
"issues": "https://github.com/ajur-media/PHP_GDWrapper/issues"
},
"require-dev": {
"rector/rector": "^1.2"
}
}
26 changes: 25 additions & 1 deletion sources/GDImageInfo.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,28 @@ public function __construct($filename = '', $error_message = '')
$this->extension = pathinfo($this->filename, PATHINFO_EXTENSION);
}

/**
* "Клонирует" GD-ресурс
*
* Дело в том, что простое присвоение `$target->data = $source->data;` не создает дубликат ресурса, а копирует ссылку
* на объект. И уничтожение одного объекта (например $source) уничтожает и второй.
*
* Клонировать GD-объект нельзя. В сети советуют делать это через imagecopy или imagecrop с сохранением альфаканала,
* но в нашем случае проще считать файл повторно, а потом поменять ему целевое имя (для сохранения).
*
* @param string $fn_source
* @param string $fn_target
* @return void
*/
public static function clone(string $fn_source, string $fn_target):GDImageInfo
{
$target = new GDImageInfo($fn_source);
$target->load();
$target->setFilename($fn_target);

return $target;
}

/**
* Обновляет информацию, используя данные файла
*/
Expand Down Expand Up @@ -142,7 +164,9 @@ public function load():GDImageInfo
*/
public function destroyImage():GDImageInfo
{
if ($this->data !== null && get_resource_type($this->data) === 'gd') {
$data_type = get_resource_type($this->data);

if ($this->data !== null && ($data_type === 'gd' || $data_type =='resource')) {
imagedestroy($this->data);
}

Expand Down
113 changes: 25 additions & 88 deletions sources/GDWrapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,11 @@ public static function init(array $options = [], LoggerInterface $logger = null)
: 0;

self::$logger
= $logger instanceof LoggerInterface
= !is_null($logger)
? $logger
: new NullLogger();

self::$invalid_file = new GDImageInfo();

}

public static function cropImage(string $fn_source, string $fn_target, array $xy_source, array $wh_dest, array $wh_source, $quality = null):GDImageInfo
Expand Down Expand Up @@ -98,34 +97,29 @@ public static function cropImage(string $fn_source, string $fn_target, array $xy
return $target;
}

/**
* Создает новый файл, залитый цветом
*
* @param string $fn_target
* @param int $width
* @param int $height
* @param array $color массив из 4 int R+G+B+A; alpha (0 - opaque, 127 transparent), если указано меньше 4 значений, остальные считаются по умолчанию = 0
* @param null $quality
* @return GDImageInfo
*/

public static function imageFillColor(string $fn_target, int $width, int $height, array $color, $quality = null):GDImageInfo
{
$target = new GDImageInfo($fn_target);

if (count($color) < 4) {
$color = array_merge( $color, array_fill(0, 3-count($color), 0)); // colors
$color = array_merge( $color, array_fill(0, 3 - count($color), 0)); // colors
$color[] = 0; // alpha
}

list($red, $green, $blue, $alpha) = $color;
[$red, $green, $blue, $alpha] = $color;

if ($target->extension == 'png') {
imagesavealpha($target->data, true);
}

$color = $alpha == 0 ? imagecolorallocate($target->data, $red, $green, $blue) : imagecolorallocatealpha($target->data, $red, $green, $blue, $alpha);

$target->data = imagecreatetruecolor($width, $height);

$color
= $alpha == 0
? imagecolorallocate($target->data, $red, $green, $blue)
: imagecolorallocatealpha($target->data, $red, $green, $blue, $alpha);

imagefill($target->data, 0, 0, $color);

$target->setCompressionQuality($quality);
Expand Down Expand Up @@ -351,12 +345,13 @@ public static function getFixedPicture(string $fn_source, string $fn_target, int

public static function addWaterMark(string $fn_source, array $params, int $pos_index, $quality = null, string $fn_target = ''):GDImageInfo
{
$positions = array(
$positions = [
1 => "left-top",
2 => "right-top",
3 => "right-bottom",
4 => "left-bottom",
);
4 => "left-bottom"
];

if (!array_key_exists( $pos_index, $positions )) {
return new GDImageInfo();
}
Expand All @@ -370,8 +365,7 @@ public static function addWaterMark(string $fn_source, array $params, int $pos_i
}

if (!empty($fn_target)) {
$target = new GDImageInfo($fn_target);
$target->data = $source->data;
$target = GDImageInfo::clone($fn_source, $fn_target);
} else {
$target = $source;
}
Expand Down Expand Up @@ -466,8 +460,7 @@ public static function rotate(string $fn_source, $roll_direction = "", $quality
}

if (!empty($fn_target)) {
$target = new GDImageInfo($fn_target);
$target->data = $source->data;
$target = GDImageInfo::clone($fn_source, $fn_target);
} else {
$target = new GDImageInfo($fn_source);
}
Expand All @@ -494,62 +487,6 @@ public static function rotate(string $fn_source, $roll_direction = "", $quality
return $source;
}

public static function rotate_legacy(string $fn_source, string $roll_direction = "", $quality = null):GDImageInfo
{
$source = new GDImageInfo($fn_source);
$source->load();

if ($source->valid === false) {
self::$logger->error($source->error_message, [ $fn_source ]);
return $source;
}

$degrees = 0;
if ($roll_direction == "left") {
$degrees = 270;
}
if ($roll_direction == "right") {
$degrees = 90;
}

if ($degrees !== 0) {
$newimg = @imagecreatetruecolor($source->width, $source->height);

try {
for ($i = 0; $i < $source->width; $i++) {
for ($j = 0; $j < $source->height; $j++) {
$reference = imagecolorat($source->data, $i, $j);
switch ($degrees) {
case 90: {
if (!@imagesetpixel($newimg, ($source->height - 1) - $j, $i, $reference)) {
throw new RuntimeException();
}
break;
}
case 180: {
if (!@imagesetpixel($newimg, $source->width - $i, ($source->height - 1) - $j, $reference)) {
throw new RuntimeException();
}
break;
}
case 270: {
if (!@imagesetpixel($newimg, $j, $source->width - $i - 1, $reference)) {
throw new RuntimeException();
}
break;
}
}
}
}
} catch (RuntimeException $e) {
}
$source->data = $newimg;
$source->setCompressionQuality($quality);
$source->store();
}
return $source;
}

/**
*
* @param $value
Expand Down Expand Up @@ -578,27 +515,27 @@ public static function toRangeMin($value, $min, $max)
/**
* @param $width
* @param $height
* @param $maxwidth
* @param $maxheight
* @param $max_width
* @param $max_height
* @return array
*/
private static function getNewSizes($width, $height, $maxwidth, $maxheight)
private static function getNewSizes($width, $height, $max_width, $max_height): array
{

if ($width > $height) {
// горизонтальная
if ($maxwidth < $width) {
$new_width = $maxwidth;
$new_height = ceil($height * $maxwidth / $width);
if ($max_width < $width) {
$new_width = $max_width;
$new_height = ceil($height * $max_width / $width);
} else {
$new_height = $height;
$new_width = $width;
}
} else {
// вертикальная
if ($maxheight < $height) {
$new_height = $maxheight;
$new_width = ceil($width * $maxheight / $height);
if ($max_height < $height) {
$new_height = $max_height;
$new_width = ceil($width * $max_height / $height);
} else {
$new_height = $height;
$new_width = $width;
Expand Down
10 changes: 10 additions & 0 deletions sources/GDWrapperInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,16 @@ public static function rotate2(string $fn_source, string $roll_direction = "", $
*/
public static function flip(string $fn_source, int $mode, $quality = null, string $fn_target = ''):GDImageInfo;

/**
* Создает новый файл, залитый цветом
*
* @param string $fn_target
* @param int $width
* @param int $height
* @param array $color массив из 4 int R+G+B+A; alpha (0 - opaque, 127 transparent), если указано меньше 4 значений, остальные считаются по умолчанию = 0
* @param null $quality
* @return GDImageInfo
*/
public static function imageFillColor(string $fn_target, int $width, int $height, array $color, $quality = null):GDImageInfo;

}

0 comments on commit d911e11

Please sign in to comment.