我在Coldfusion 9服务器上有一项服务,可以为我们动态创建图像横幅。一台单独的机器必须保存这些文件,例如:
wget http://myserver.com/services/local/bannerCreator/250x250-v3.cfm?prodID=3&percentSaving=19
问题在于我无法想到如何在不使用临时文件的情况下让coldfusion写出二进制数据。在这一刻,图像只显示为这样的图像标记:
<cfimage action = "writeToBrowser" source="#banner#" width="#banner.width#" height="#banner.height#" />
有什么想法吗?或者我应该只使用临时文件?
答案 0 :(得分:12)
我无法测试,因为您没有提供有关图像生成方式的任何示例代码,但您是否尝试过这一行?
<cfcontent reset="true" variable="#imageData#" type="image/jpg" />
更新:所以我继续创造了自己的形象;我假设你正在做类似的事情。这对我很有用:
<cfset img = imageNew("",200,200,"rgb","red") />
<cfcontent variable="#toBinary(toBase64(img))#" type="image/png" reset="true" />
无需写入文件,也无需使用虚拟文件系统(“ramdisk”)
答案 1 :(得分:5)
如果你有文件/图像的二进制字节,你可以用它的内容替换输出缓冲区,如下所示:
<cfscript>
// eg. this is how you get a file as a binary stream
// var fileBytes = fileReadBinary( '/path/to/your/file.jpg' );
// get the http response
var response = getPageContext().getFusionContext().getResponse();
// set the appropriate mime type
response.setHeader( 'Content-Type', 'image/jpg' );
// replace the output stream contents with the binary
response.getOutputStream().writeThrough( fileBytes );
// leave immediately to ensure no whitespace is added
abort;
</cfscript>
使用<cfcontent>
reset="true"
的作用
这种方法优于<cfcontent>
的优点是我们可以在基于cfscript的cfcs中编写它。
答案 2 :(得分:4)
我找到了上面的解决方案
<cfcontent variable="#toBinary(toBase64(img))#" type="image/png" reset="true" />
不适合我。
设置类型=&#34; image / png&#34;只是设置响应的mime类型。我不认为它必须将图像编码为PNG。因此,与<cfimage action = "writeToBrowser"...>
方法相比,生成透明png(图像类型&#34; argb&#34;)给我奇怪的颜色。
我认为我需要以某种方式将图像数据显式编码为PNG并直接输出二进制数据。
随着对底层java的一些挖掘,我想出了这个,到目前为止似乎对我有用。
此示例绘制一个带黑色圆圈的透明png。
<!--- create the image and draw it --->
<cfset img = ImageNew("", 23, 23, "argb")>
<cfset ImageSetDrawingColor(img, "black")>
<cfset ImageDrawOval(img, 0, 0, 21, 21, true)>
<!--- get the response object --->
<cfset response = getPageContext().getFusionContext().getResponse()>
<!--- set the response mime type --->
<cfset response.setHeader('Content-Type', 'image/png')>
<!--- get the underlying image data --->
<cfset bImage = ImageGetBufferedImage(img)>
<!--- get the magical object to do the png encoding --->
<cfset ImageIO = createObject("java", "javax.imageio.ImageIO")>
<!--- encode the image data as png and write it directly to the response stream --->
<cfset ImageIO.write(bImage, "png", response.getResponse().getOutputStream())>
我希望能帮助别人!
答案 3 :(得分:3)
取出height和width属性并添加format属性:
<cfimage action = "writeToBrowser" source="#banner#" format="png" />
wget应该遵循CF在CFFileServlet文件夹中创建的物理文件的重定向,但如果没有,则可以设置一个标记使其成为--max-redirect=10
。
正如您所说,临时文件也可以。只需编写文件并使用cfheader和cfcontent将其写出来。只需确保使临时文件名更加独特。
<cfimage action="write" destination="tempfile.png" source="#banner#" format="png" />
<cfheader name="content-disposition" value="attachment; filename=banner.png" />
<cfcontent file="tempfile.png" deletefile="true" type="image/png" />
答案 4 :(得分:0)
我做了类似的事情,你需要使用标签和cfscript进行组合。有必要的图像功能。一旦将内存中的图像作为变量,就有很多可用的图像功能。您可以使用CFFILE或CFHTTP或其他许多方式将图像存入内存。
在我的情况下,我使用CFIMAGE标签将图像文件读入内存,然后通过向底部添加文本使用CFSCRIPT图像功能对其进行操作,然后将结果图像输出为.png(如果您愿意,则输出.jpg)到浏览器。存储在服务器上的唯一文件是原始图像文件。在您的情况下,而不是阅读图像,您可以使用cfhttp标记来调用它。这是我的代码:
<!---Get the image for processing ...--->
<cfimage action="read" source="#application.approotABS#\webcam\webcam.jpg" name="CamImage" />
<!--- prepare the text for overlay --->
<cfscript>
attr=structNew();
attr.font = "Arial";
attr.size = 15;
ImageSetDrawingColor(CamImage, "white");
ImageDrawText(CamImage, 'LIVE FROM STUDIO 1', 18,(ImageGetHeight(CamImage)-54), attr);
ImageDrawText(CamImage, '#ShowOnNow.showname#', 18,(ImageGetHeight(CamImage)-36), attr);
ImageDrawText(CamImage, datestring,18,(ImageGetHeight(CamImage)-18), attr);
</cfscript>
<!--- further down the page, output the manipulated image: ---->
<div class="webcam">
<cfimage action="writeToBrowser" source="#Camimage#" >
</div>
您可以在http://hawkesburyradio.com.au/index.cfm?pid=111538
看到它的实际效果(我在Windows Server中使用CF9)