1

我正在跑步coldfusion8/MySQL5.0.88,我有一个产品搜索,我需要在显示它们之前从各种外部来源中提取并调整图像大小。

虽然我主要可以在创建产品时执行此操作(相对于被搜索),但我无法确保所有图像都可以从我的服务器以调整大小的格式提供,因此我需要在产品搜索中进行某种回退。

现在,我正在检查图像在服务器上是否可用,如果没有,我会启动一个例程来抓取并调整图像大小,如下所示:

// check if image is available
<cfif results.typ NEQ "img" AND results.typ NEQ "alt">
    <cfif results.bildpfad neq "" AND results.bilddateiname neq "">
    <cfset imgSuccess = form_img_handler.upload
        ( command   = "upload_search"
        , imgPath   = results.bildpfad
        , imgFile   = results.bilddateiname
        , sellerILN = results.iln
        , cookie    = variables.screenWidth
        )/>
    <cfif imgSuccess EQ "false">
        <cfset variables.imgFail = "true">
    </cfif>
 </cfelse>
     <cfset variables.imgFail = "true">
 </cfif>

// missing img
<cfif variables.imgFail EQ "true">
    <cfoutput><div class="resultsImgWrap noImgFound"></div></cfoutput> 
    <cfset variables.imgFail = "false">
<cfelse>
// show image
    <cfoutput><div class="resultsImgWrap"><img src="#variables.imageSrc#" /></div></cfoutput>
</cfif>

upload函数处理cfhttp请求和调整大小并返回true/false

我想知道是否可以cfthread在这种情况下使用,因此当用户进行搜索时,我会输出包含正确 URL 链接的标记,但图像拉取/调整大小/保存到目标将在 acfthread中完成,以便加快向用户显示结果。

问题
图像会在处理完成后显示,还是在尝试加载尚未创建的图像时(可能)cfthread会产生错误?404是否有任何其他方式可以向用户显示某些内容并让用户在上传和处理图像时继续?

感谢您的投入!

编辑:
好的。根据答案,我想出了以下内容。虽然还没有工作,但我认为它朝着正确的方向发展。

// check media log, if image is logged (already created), if so, load it, if not pull it from external
<cfif results.typ NEQ "img" AND results.typ NEQ "alt">
    // check path and filename
    <cfif results.bildpfad neq "" AND results.bilddateiname neq "">
        // pull in
        // arguments: 
        // cm = form
        // pt = path to image
        // fl = filename
        // se = seller id  
        // ck = screen width (I'm using adaptive image sizes
        // ax = origin
        // gb = which image size to return
        <cfset variables.imgSrc = expandPath("../services/img_handler.cfc") & "?method=up&cm=results&pt=" & results.bildpfad & "&fl=" & results.bilddateiname & "&se=" & results.id & "&ck=" & variables.screenWidth & "&ax=rm&gb=s">
    <cfelse>
        cfset variables.imgFail = "true">
    </cfif>
</cfif>

<cfif variables.imgFail EQ "true">
    <cfoutput><div class="resultsImgWrap noImgFound"><img src="../images/not_found.png"></div></cfoutput>
    <cfset variables.imgFail = "false">
 <cfelse>
    <cfoutput><div class="resultsImgWrap"><a class="swipeMe" rel="external" href="#variables.zoomSrc#">
                <img src="#variables.imageSrc#" class="adaptImg ui-li-thumb" /></a>
              </div></cfoutput>
</cfif>

因此,这将检查我正在查询的媒体日志中的图像以及结果(避免对现有图像进行不必要的 s3 检查)。如果日志中没有图像,我将检查路径/文件名是否为空并触发我的intelligent图像加载器,它执行以下操作:

<cfcomponent output="false" hint="image handler">
    <cffunction name="Init" access="public" returntype="any" output="false" hint="Initialize">
        <cfreturn true />
    </cffunction>       

    <cffunction name="upload" access="remote" output="false" hint="creates images and stores them to S3">
        <cfargument name="cm" type="string" required="true" hint="" /> 
        <cfargument name="pt" type="string" required="true" hint="" /> 
        <cfargument name="fl" type="string" required="true" hint="" />
        <cfargument name="se" type="string" required="true" hint="" />
        <cfargument name="ck" type="string" required="true" hint="" />
        <cfargument name="gb" type="string" required="false" hint="" />
        <cfargument name="ax" type="string" required="false" hint="" />

        <cfscript>  
           var LOCAL = {};  
           // arguments
           LOCAL.command = cm;
           LOCAL.imgPath = pt;
           LOCAL.imgFile = fl;
           LOCAL.sellerILN = se;
           LOCAL.cookie = LSParseNumber(ck);
           LOCAL.getBack = gb;
           LOCAL.access = ax;
           // s3
           // commander
           if ( LOCAL.command NEQ "" ) {
                LOCAL.action = LOCAL.command;
           } else {
                LOCAL.action = "upload";
                }
           // s3 misc
           LOCAL.bucketPath = Session.bucketPath;
           LOCAL.bucketName = Session.bucketName;
           LOCAL.acl = "public-read";
           LOCAL.storage = "";
           LOCAL.tempDirectory = expandPath( "../members/img/secure/" );
           LOCAL.allow = "png,jpg,jpeg";
           LOCAL.failedLoads = "";
           LOCAL.altFailedLoads = "";
           LOCAL.createBucket = "false";
           LOCAL.errorCount = 0;
           LOCAL.altErrorCount = 0;
           LOCAL.cacheControl = 1;
           LOCAL.contentType = "image";
           LOCAL.httptimeout = "300";
           LOCAL.cacheDays = "30";
           LOCAL.storageClass = "REDUCED_REDUNDANCY";
           LOCAL.keyName = "";
           LOCAL.baseUrl = "http://www.baseurl.com";
           LOCAL.imageSrc = "";
           LOCAL.testFilePath = LOCAL.imgPath & LOCAL.imgFile;
           LOCAL.fileExt = ListLast(LOCAL.testFilePath, ".");
           LOCAL.runner = "s,m,l,xl";
           LOCAL.worked = "true";
      </cfscript>   
      // runner is the file size setter, in results I only create two sizes, during imports I create all four
      <cftry>
        <cfhttp timeout="45" 
            throwonerror="no" 
            url="#LOCAL.testFilePath#" 
            method="get" 
            useragent="Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.8.1.12) Gecko/20080201 Firefox/2.0.0.12" 
            getasbinary="yes" 
            result="objGet">
        <cfscript>
            // set file sizes to create
            if ( LOCAL.command EQ "upload_search" ){
                if ( LOCAL.cookie LT 320 ) {
                    LOCAL.runner = "l,s";
                    }
                else if ( LOCAL.cookie GTE 320 AND LOCAL.cookie LTE 767 ) {
                    LOCAL.runner = "l,m";
                    }
                else if ( LOCAL.cookie GT 768 ) {
                    LOCAL.runner = "xl,m";
                    }
                else if ( LOCAL.cookie GT 1280 ){
                    LOCAL.runner = "xl,l";
                    }
                } else if ( LOCAL.command EQ "upload_import") {
                    LOCAL.runner = "xl,l,m,s";
                    }
            // validate
            if ( len(objGet.Filecontent) EQ 0 OR objGet.Mimetype EQ "text/html"  ){
                LOCAL.worked = "false length or mime";
                } else if ( NOT listfindnocase(LOCAL.allow, LOCAL.fileExt ) ){
                LOCAL.worked = "false wrong extension";
                } else {
                // create temp
                LOCAL.objImage = ImageNew(objGet.FileContent);
                LOCAL.basePath = LOCAL.tempDirectory & "_base_" & LOCAL.imgFile;
                imageWrite( LOCAL.objImage, LOCAL.basePath, ".99");
                LOCAL.base = imageRead( LOCAL.basePath );
                LOCAL.imageSrc = LOCAL.tempDirectory;

                // formats
                // S = 100x127, 
                // M = 180x230, 
                // L = 290x370, 
                // XL = 870x1110 

                // portrait
                if ( ImageGetWidth( LOCAL.base ) LT ImageGetHeight( LOCAL.base ) ){
                    for (LOCAL.i = 1; LOCAL.i LTE ListLen(LOCAL.runner,","); LOCAL.i = LOCAL.i+1){
                        LOCAL.lt = ListGetAt(LOCAL.runner, LOCAL.i, ",");
                        LOCAL.base = imageRead( LOCAL.basePath );
                        ImageSetAntialiasing(LOCAL.base,"on");
                        // default image width/height
                        LOCAL.height = Application.strConfig.respH[LOCAL.lt];
                        LOCAL.width = "";
                        ImageScaleToFit(LOCAL.base, LOCAL.width, LOCAL.height, "highestQuality");

                        LOCAL.filekey = LOCAL.lt & "_" & LOCAL.imgFile;
                        LOCAL.keyName = LOCAL.sellerILN & "/" & LOCAL.filekey;
                        LOCAL.filename = LOCAL.tempDirectory & LOCAL.filekey;
                        imageWrite( LOCAL.base, LOCAL.filename, ".99" );

                        // s3
                        Application.strObjs.s3.putObject(LOCAL.bucketName, LOCAL.filekey, LOCAL.contentType, LOCAL.httptimeout, LOCAL.cacheControl, LOCAL.cacheDays, LOCAL.acl, LOCAL.storageClass, LOCAL.keyName, LOCAL.imageSrc, "false" );
                        fileDelete( LOCAL.tempDirectory & LOCAL.lt & "_" & LOCAL.imgFile );
                        }
                    } else {
                    // same for landscape
                    ...
                    }
                }
                // cleanup
                fileDelete( LOCAL.tempDirectory & "_base_" & LOCAL.imgFile );
            } 
        </cfscript>
    // update media log
        ...
        <cfcatch>
        // dump errror message
        </cfcatch>
        </cftry>

    // return image 
        <cfif LOCAL.access EQ "rm">
            <cftry>
            <cfscript>
            if ( LOCAL.getBack EQ "s" ){
                LOCAL.passPath = Session.bucketPath & Session.bucketName & "/" & LOCAL.sellerILN & "/" & ListGetAt(LOCAL.runner, Listlen(LOCAL.runner), ",") & "_" & LOCAL.imgFile;
            } else if( LOCAL.getBack EQ "l" ) {
                LOCAL.passPath = Session.bucketPath & Session.bucketName & "/" & LOCAL.sellerILN & "/" & ListGetAt(LOCAL.runner, 1, ",") & "_" & LOCAL.imgFile;
            }
            LOCAL.mime = "image/" & LOCAL.fileExt;
            </cfscript>

            <cfcontent type="#LOCAL.mime#" file="#LOCAL.passPath#" />
            <cfcatch>
            // dump errors
            </cfcatch>                              
        </cftry>
    <cfelse>
        <cfreturn LOCAL.worked>
    </cfif>
    </cffunction>
</cfcomponent>

因此,我正在设置要创建的文件大小LOCAL.runner并查看此列表,将基础图像的大小调整为我预设的图像尺寸并将创建的图像存储在 s3 上。

问题cfcontent试图在创建之前返回图像。The file specified in contentTag does not exist运行上面的代码时出现错误。如果我检查 S3,图像就在那里,所以我假设这是一个时间问题。

感谢您提供有关如何强制“cfcontent”等到创建图像的任何指示!

4

1 回答 1

1

将链接输出到将加载 img 的本地 CFM 怎么样?我的意思是 - 对于您服务器上存在的图像,您输出<img>指向它的标签。对于您需要加载的图像,您会输出如下内容:

<img src="imagegetter.cfm?p=#urlofimagetoload#">

imagegetter.cfm将负责执行 http 以在本地获取和调整图像大小。然后它可以通过 cfcontent 提供这些位。

于 2012-08-25T22:20:14.207 回答