如何在coldfusion中将图像写入浏览器作为二进制流?

时间:2011-04-12 14:29:23

标签: coldfusion coldfusion-9

我在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#" />

有什么想法吗?或者我应该只使用临时文件?

5 个答案:

答案 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)