ImageMagick identif.exe ничего не возвращает в параллельном проекте Apache Ant
Я использую проект Apache Ant, чтобы собрать некоторую информацию о текстурах. Здесь вы можете увидеть тестовый проект, который выполняет только чтение без каких-либо дополнительных действий. Это минимальный набор, который воспроизводит одну неприятную ошибку. Я обнаружил, что иногда ImageMagick's attribute.exe ничего не возвращает - я добавил код, который приводит к сбою сборки, если это так. Если я буду запускать этот проект несколько раз, у меня будет нестабильное поведение. Иногда проект строится успешно, иногда происходит сбой с несколькими сообщениями об ошибках. Разработчики ImageMagick говорят, что их инструменты поточно-ориентированы. Но если identif.exe не так, то что может быть? Мне действительно нужна помощь кого-то с предварительными знаниями об Apache Ant и ImageMagick.
<project default="default">
<taskdef resource="net/sf/antcontrib/antlib.xml"/>
<property name="image_magick_path" location="c:\Program Files\ImageMagick-6.8.9-Q8\"/>
<property name="images_path" location="path\to\folder\with\png\images"/>
<target name="default">
<for param="item" parallel="true">
<path>
<fileset dir="${images_path}">
<patternset id="pattern_images">
<include name="**\*.png"/>
<include name="**\*.jpg"/>
<include name="**\*.gif"/>
<include name="**\*.bmp"/>
</patternset>
</fileset>
</path>
<sequential>
<local name="image_width"/>
<tex_width file="@{item}" property="image_width"/>
<local name="image_height"/>
<tex_width file="@{item}" property="image_height"/>
<if>
<or>
<equals arg1="${image_width}" arg2=""/>
<equals arg1="${image_height}" arg2=""/>
</or>
<then>
<fail message="Got nothing. But why? Image: @{item}"/>
</then>
</if>
</sequential>
</for>
</target>
<macrodef name="tex_width">
<attribute name="file"/>
<attribute name="property"/>
<sequential>
<exec executable="${image_magick_path}\identify.exe" outputproperty="@{property}">
<arg value="-format"/>
<arg value="%w"/>
<arg value="@{file}"/>
</exec>
</sequential>
</macrodef>
<macrodef name="tex_height">
<attribute name="file"/>
<attribute name="property"/>
<sequential>
<exec executable="${image_magick_path}\identify.exe" outputproperty="@{property}">
<arg value="-format"/>
<arg value="%h"/>
<arg value="@{file}"/>
</exec>
</sequential>
</macrodef>
</project>
1 ответ
Хорошо, я напишу здесь, как мне удалось решить мою проблему. Я надеюсь, что когда-нибудь это кому-нибудь поможет.
Первое, что я обнаружил, это то, что PHP-метод getimagesize намного быстрее, поэтому я решил переключиться на него, таким образом убив основную проблему. Я написал следующий макрос, чтобы получить ширину и высоту изображения:
<macrodef name="getimagesize">
<attribute name="file"/>
<attribute name="propertywidth"/>
<attribute name="propertyheight"/>
<sequential>
<local name="output"/>
<exec executable="php" outputproperty="output">
<arg value="-r"/>
<arg value=
""$size=getimagesize('@{file}');
echo($size[0].' '.$size[1]);""
/>
</exec>
<propertyregex
property="@{propertywidth}"
input="${output}"
regexp="(\d*) (\d*)"
replace="\1"
/>
<propertyregex
property="@{propertyheight}"
input="${output}"
regexp="(\d*) (\d*)"
replace="\2"
/>
</sequential>
</macrodef>
К сожалению, в этом макродефе точно такая же ошибка. Иногда во время параллельного запуска некоторые exec-задачи ничего не возвращали в вывод. Я был очень расстроен, поэтому я решил написать еще один макрос, который я сейчас использую, и, наконец, он работает нормально. Что я сделал, так это избежал чтения чего-либо из stdout exec-task и вместо этого использовал tempfile-task. Вот последний макрос:
<macrodef name="getimagesize">
<attribute name="file"/>
<attribute name="propertywidth"/>
<attribute name="propertyheight"/>
<sequential>
<local name="file_dirname"/>
<dirname property="file_dirname" file="@{file}"/>
<local name="file_temp"/>
<tempfile property="file_temp" destdir="${file_dirname}" createfile="true"/>
<exec executable="php">
<arg value="-r"/>
<arg value=""$size=getimagesize('@{file}');
file_put_contents('${file_temp}', $size[0].' '.$size[1]);""/>
</exec>
<local name="file_temp_content"/>
<loadfile property="file_temp_content" srcfile="${file_temp}"/>
<delete file="${file_temp}"/>
<propertyregex
property="@{propertywidth}"
input="${file_temp_content}"
regexp="(\d*) (\d*)"
replace="\1"
/>
<propertyregex
property="@{propertyheight}"
input="${file_temp_content}"
regexp="(\d*) (\d*)"
replace="\2"
/>
</sequential>
</macrodef>