multithreading - ImageMagickidentify.exe在并行Apache Ant项目中不返回任何内容

标签 multithreading apache ant imagemagick ant-contrib

我使用Apache Ant项目来收集有关纹理的一些信息。在这里,您可以看到一个测试项目,该项目仅读取而无需任何进一步的操作。这是一个最小的集,它再现了一个讨厌的错误。我发现有时ImageMagick的identify.exe不返回任何内容–我添加了一个代码,如果这样做,它会强制构建失败。如果我多次运行该项目,我将获得不稳定的行为。有时项目构建成功,有时失败,并带有多个失败消息。 ImageMagick的开发人员说,他们的工具是线程安全的。但是,如果不是identify.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>

最佳答案

好的,我将在这里写下如何设法解决我的问题。希望有一天能对某人有所帮助。

我发现的第一件事是PHP方法“getimagesize”要快得多,所以我决定切换到该方法,从而解决了主要问题。我写了以下macrodef来获取图像的宽度和高度:

<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=
                "&quot;$size=getimagesize('@{file}');
                echo($size[0].' '.$size[1]);&quot;"
            />
        </exec>
        <propertyregex 
            property="@{propertywidth}" 
            input="${output}" 
            regexp="(\d*) (\d*)" 
            replace="\1"
        />
        <propertyregex 
            property="@{propertyheight}" 
            input="${output}" 
            regexp="(\d*) (\d*)" 
            replace="\2"
        />
    </sequential>
</macrodef>

不幸的是,这个macrodef确实有同样的错误。有时在并行运行期间,某些exec任务在输出中未返回任何内容。我非常沮丧,所以我决定编写另一个我现在使用的macrodef,最后效果很好。我所做的是避免从exec-task的'stdout'中读取任何内容,而改用tempfile-task。这是最终的macrodef:
<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="&quot;$size=getimagesize('@{file}');
                file_put_contents('${file_temp}', $size[0].' '.$size[1]);&quot;"/>
        </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>

关于multithreading - ImageMagickidentify.exe在并行Apache Ant项目中不返回任何内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23897919/

相关文章:

使用多线程时计算执行时间

c - pthread_create 启动例程未执行

html - 使用 C CGI 提供 HTML 模板/表单

spring - 使用 Spring MVC 将 JRebel 与自定义 Ant/Ivy/Tomcat Web 应用程序集成

ant - 如何使javac编译器将输出写入文件和控制台?

iphone - 原子属性在什么情况下有用?

multithreading - 线程同步原语

performance - 服务器达到 MaxClients 设置,请考虑提高 MaxClients 设置。装甲运兵车

linux - 如何在 Perl 中检查已安装的 Apache 模块?

svn - 如何让 svnant/svnkit 提示输入用户名/密码