当使用PHP和ImageMagick递归地调整图像大小和命名时,如何基于现有的文件名和扩展名最好地编写新文件



我有一个'源'图像目录,我保存了多个调整大小的文件。我希望所有的jpg和png文件在给定的目录被调整大小和保存新的名称基于他们的原始文件名(一个la filename-small.jpg, filename-medium.jpg等),我使用ImageMagick

在SO的另一个问题中找到了获取所有文件的regex内容,并且有所帮助-但我不完全明白这里发生了什么。

我当前所拥有的是将原始文件扩展名放在文件名的中间。虽然我理解为什么会发生这种情况,但我不确定解决这个问题的最佳方法。

我怎么能把这个变成filename-large.jpg而不是filename.jpg-large.jpg

?这是我目前的内容:

<?php
$directory = new RecursiveDirectoryIterator('source/assets/uploads/test');
$iterator = new RecursiveIteratorIterator($directory);
$images = new RegexIterator($iterator, '/^.+(.jpe?g|.png)$/i', RecursiveRegexIterator::GET_MATCH);
$widths = [
'small' => 400,
'medium' => 800,
'large' => 1000,
'xlarge' => 1600,
];

foreach($images as $image => $value) {
// Set the original filename w/o the extension
$originalFilename = $image;
// set the extension based on the original
// ideally conform the extension jpeg to jpg
$originalExtension = '.jpg';

// create a new Imagick instance
$newImage = new Imagick($image);
// strip out some junk
$newImage->stripImage();
// write a new file for each width 
// and name it based on the original filename
foreach ($widths as $key => $value) {
// using 0 in the second $arg will keep the same image ratio
$newImage->resizeImage($value,0, imagick::FILTER_LANCZOS, 0.9);
$newImage->writeImage($originalFilename . '-' . $key . $originalExtension);
}
}

Nathan,

您正在使用父元素捕获该扩展。您希望捕获文件名,而不仅仅是扩展名。您可以使用非捕获父((?:))对扩展变量进行分组。

$images = new RegexIterator($iterator, '/^(.+).(?:jpe?g|png)$/i', RecursiveRegexIterator::GET_MATCH);

我还转义了扩展名前面的文字点(.)。

或者,您可以从$image变量中拆分扩展名和文件名:

preg_match('/^(.+).([^.]+)$/', $image, $matches);
// Set the original filename w/o the extension
$originalFilename = $matches[1];
// Set the original extension
$originalExtension = $matches[2];

最后,fww,如果我这样做,我不会使用RegexIterator,而是只迭代目录,只在每个文件名上使用preg_match

$directory = dir('source/assets/uploads/test');
while(false !== ($entry = $directory->read())) {
$result = preg_match('/^(.+).(jpe?g|png)$/i', $entry, $matches);
if($result === false) {
die('ERROR: `preg_match` failed on '.$entry);
} else if($result === 0) {
// not an image file
continue;
}
// Set the original filename w/o the extension
$originalFilename = $matches[1];
// Set the original extension
$originalExtension = $matches[2];
// ... do the other things on the file
}

参:

  • https://www.php.net/manual/en/function.dir
  • https://www.php.net/manual/en/function.preg-match.php

编辑:

对于$matches内部的命名引用,可以使用修改后的regexp:

preg_match('/^(?P<filename>.+).(?P<extension>jpe?g|png)$/i', $entry, $matches);

?P<key>是一个"占位符"将key赋值为捕获到的匹配项的引用。

你仍然会得到$matches作为一个数组,而不是一个对象,但是你可以用占位符作为索引访问这些值。

// Set the original filename w/o the extension
$originalFilename = $matches['filename'];
// Set the original extension
$originalExtension = $matches['extension'];

哎呀,数字索引也还在。

相关内容

最新更新