1

我正在使用Coldfusion8并且需要从远程服务器获取图像,我正在这样做:

 <cfhttp timeout="45" throwonerror="no" url="#variables.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="variables.objGet">
 <cfset variables.objImage = ImageNew(variables.objGet.FileContent)>

我现在需要将图像保存到 Amazon S3,但我想使用的功能:

 <cfset result = s3.putObject(url.b,file.serverFile,file.contentType,'300',form.cacheControl,'30',form.acl,form.storageClass,form.keyName,GetTempDirectory())>

需要可以在其中找到我生成的图像的目录。

问题:
有没有办法获取一个图像文件的目录cfhttp并使用它转换为图像imageNew?还是我需要先将文件保存到磁盘?我还需要在存储之前调整大小,所以如果不先保存到磁盘,我可能无法通过。

感谢指点!

编辑
我让它像这样工作:

<!--- getAsBinary --->
<cfhttp timeout="45" 
    throwonerror="no" 
    url="#variables.testFilePath#" 
    method="get" 
    useragent="..."         
    getasbinary="yes" 
    result="objGet">

<!--- validate --->
<cfif len(variables.testFilePath) EQ 0>
    <cfset variables.errorCount = variables.errorCount+1>
    <cfset variables.failedLoads = "FILE NOT FOUND" >
<cfelse>
    <cfif len(objGet.Filecontent) EQ 0>
        <cfset variables.errorCount = variables.errorCount+1>
        <cfset variables.failedLoads = "COULD NOT LOAD IMAGE">
    <cfelseif NOT listfindnocase(variables.allow, variables.fileExt) >
        <cfset variables.errorCount = variables.errorCount+1>
        <cfset variables.failedLoads = "WRONG FILE TYPE">
    <cfelse>
        <cftry>
            <cfscript>
                objImage = ImageNew(objGet.FileContent);
                ImageSetAntialiasing(objImage,"on");
                <!--- resize/crop --->
                variables.keyName = Session.loginid & "_S_";
            </cfscript>
            <!--- convert modified image back to binary --->
            <cfset variables.filekey = toBase64( objImage )>
            <!--- pass to s3.cfc --->
            <cfset result = s3.putObject(variables.bucketName, variables.filekey, variables.contentType, variables.httptimeout, variables.cacheControl, variables.cacheDays, variables.acl, variables.storageClass, variables.keyName, variables.imageSrc, "true" )>
            <cfcatch>
                <cfset variables.errorCount = variables.errorCount+1>
                <cfset variables.failedLoads = "NO IMAGE">
            </cfcatch>
        </cftry>
    </cfif>

我需要将裁剪后的图像重新转换为二进制文件,s3.putobject否则cffile action="readBinary"将在此处执行另一个操作并在尝试构建图像文件路径时中断(图像仍处于临时状态):

<cffile action="readBinary" file="#arguments.uploadDir##arguments.fileKey#" variable="binaryFileData">

虽然我可以使用这个技巧获取临时文件路径并设置uploadDir它并没有帮助,因为CF 文档说该路径必须是以驱动器号或斜杠开头的绝对路径,否则将采用 www-root 临时目录。

在我的情况下,临时 www-root 目录处于打开状态C:/,而临时文件 CFFile-Servlet 处于打开状态E:/,并且相对路径也不起作用(找不到文件)。因此,由于我找不到从 s3.cfc 重新读取图像的方法,我现在在调用 S3.cfc 之前转换回二进制文件。我传递了另一个参数 (1/0) 告诉 s3.cfc,我已经在发送二进制图像并且不需要重新读取它。

像这样:

<!--- if encoded is true, filekey already is the encoded image --->
<cfif arguments.encoded EQ "true">
    <!--- already sending binary image --->
    <cfset binaryFileData = arguments.fileKey>
<cfelse>
    <!--- Default --->
    <cffile action="readBinary" file="#arguments.uploadDir##arguments.fileKey#" variable="binaryFileData">
</cfif>

我不确定这是否是性能方面最聪明的方式,但它似乎工作得非常顺利。欢迎评论!

4

3 回答 3

2

我猜你可以使用pathandfile属性而不是result. GetTempDirectory()使用+生成一些临时路径CreateUUID(),获取然后删除它。另外,它可能比将内容获取到变量然后写入中间文件更节省内存。

于 2012-08-10T17:59:59.947 回答
1

cfhttp result 将数据存储在内存变量中。ImageNew 创建一个“ColdFusion”图像,这意味着它也仅驻留在内存中。您必须保存它以使其成为物理文件,以便在 cfhttp 或 imagewrite 等中发送。

如果不将其保存到物理文件,则必须使用 cffile action = "writetobrowser" 将其发送到浏览器,但最终会将其保存在临时位置以供浏览器访问,但在这里对您没有多大好处我不思考。

http://livedocs.adobe.com/coldfusion/8/htmldocs/functions_h-im_34.html http://livedocs.adobe.com/coldfusion/8/htmldocs/Images_19.html

于 2012-08-10T18:06:32.050 回答
0

AmazonS3Client 有一个接受 InputStream 的putObject 方法,因此您可以将二进制数据包装在 ByteArrayInputStream 中并将其传入,而无需担心支持文件。

像这样的东西:

<cfhttp method="get" url="#local.url#" result="local.httpResult" getAsBinary="true"/>
<cfif local.httpResult.statusCode eq "200 OK">
    <cfset var fileInputStream = createObject("java", "java.io.ByteArrayInputStream" ).init(local.httpResult.fileContent) />
    <cfset var objectMetadata = createObject("java", "com.amazonaws.services.s3.model.ObjectMetadata" ).init() />
    <cfset application.S3UTIL.s3Client.putObject("some.bucket", "folder/file.ext", local.fileInputStream, local.objectMetadata)/>
</cfif>
于 2015-12-16T17:43:36.303 回答