当使用PHP和ImageMagick递归地调整图像大小和命名图像时,如何最好地基于现有文件名和扩展名编写新文件
我有一个“源”图像目录,我正在保存多个调整大小的文件。我希望给定目录中的所有jpg和png文件都能根据它们的原始文件名(la filename-small.jpg、filename-medium.jpg等)调整大小并使用新名称保存。我正在使用ImageMagick 在这里的另一个问题中发现了用于获取所有文件的regex文件,这对我很有帮助,但我并不完全了解这里到底发生了什么当使用PHP和ImageMagick递归地调整图像大小和命名图像时,如何最好地基于现有文件名和扩展名编写新文件,php,regex,imagemagick,imagick,Php,Regex,Imagemagick,Imagick,我有一个“源”图像目录,我正在保存多个调整大小的文件。我希望给定目录中的所有jpg和png文件都能根据它们的原始文件名(la filename-small.jpg、filename-medium.jpg等)调整大小并使用新名称保存。我正在使用ImageMagick 在这里的另一个问题中发现了用于获取所有文件的regex文件,这对我很有帮助,但我并不完全了解这里到底发生了什么 我目前在文件名中间使用原始文件扩展名。虽然我理解为什么会发生这种情况,但我不确定解决这一问题的最佳方法 如何将文件名改为f
我目前在文件名中间使用原始文件扩展名。虽然我理解为什么会发生这种情况,但我不确定解决这一问题的最佳方法
如何将文件名改为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);
}
}
内森
您正在使用parens捕获该扩展。您希望捕获文件名,而不仅仅是扩展名。您可以使用非caputring参数((?:)
)对扩展变量进行分组
$images=newregexiterator($iterator,'/^(+)\.(?:jpe?g|png)$/i',RecursiveRegexIterator::GET_MATCH);
我还转义了扩展之前的文字点(
)
或者,您可以从$image
变量中拆分扩展名和文件名:
preg\u match('/^(+)\.([^.]+)$/',$image,$matches);
//设置不带扩展名的原始文件名
$originalFilename=$matches[1];
//设置原始扩展名
$originalExtension=$matches[2];
最后,FWIW,如果我这样做,我不会使用RegexIterator
,但tather只是迭代目录,只对每个文件名使用preg_match
$directory=dir('source/assets/uploads/test');
while(false!==($entry=$directory->read()){
$result=preg_match('/^(+)\(jpe?g|png)$/i',$entry,$matches);
如果($result==false){
die('ERROR:'preg_match`在'.$entry'上失败);
}else if($result==0){
//不是图像文件
继续;
}
//设置不带扩展名的原始文件名
$originalFilename=$matches[1];
//设置原始扩展名
$originalExtension=$matches[2];
//…做文件上的其他事情
}
参考文献:
$matches
中的命名引用,可以使用此修改的regexp:
preg_match('/^(?P.+)\.(?Pjpe?g|png)$/i',$entry,$matches);
?p
是一个“占位符”,它指定键作为对该caputred匹配的引用
您仍然可以将$matches
作为数组而不是对象返回,但是您可以使用该占位符作为索引来访问这些值
//设置不带扩展名的原始文件名
$originalFilename=$matches['filename'];
//设置原始扩展名
$originalExtension=$matches['extension'];
FWIW,数字索引也仍然存在。尝试/^.+\(?模式,以排除所有带有$width
后缀的限定字符串。或者,/^(.+)(?:-(?:small | x?large | medium))。(?:jpe?g | png)$/i
@WiktorStribiżew我喜欢它的发展方向这可能有助于将来在repo中添加新图像时,我只想更新这些图像。但是,我也看到希望将“large”更新为1200。也许从长远来看,只根据图像大小值而不是抽象键命名文件会更好。如果我如果需要一个新的大小,添加它将不会有太大问题。这非常有帮助,谢谢!为了让我没有经验的编程大脑更清楚地了解这一点,是否有可能以更关键/值类型的方式捕获数组中的数据?因此,与$matches[2]不同,类似于$matches->extension?