【问题标题】:How do you write a image to browser as a binary stream in coldfusion?你如何在coldfusion中将图像作为二进制流写入浏览器?
【发布时间】:2011-04-12 14:29:22
【问题描述】:

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

有什么想法吗?还是我应该只使用一个临时文件?

【问题讨论】:

    标签: coldfusion coldfusion-9


    【解决方案1】:

    我无法测试,因为您没有提供任何有关如何生成图像的示例代码,但是您是否尝试过类似的方法?

    <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”)即可工作

    【讨论】:

    • 仅供参考:无需将reset属性显式设置为true,因为true是默认值。
    【解决方案2】:

    如果你有文件/图像的二进制字节,你可以用它的内容替换输出缓冲区,如下所示:

    <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>
    

    当您使用reset="true" 时,&lt;cfcontent&gt; 的作用差不多

    这种方法相对于&lt;cfcontent&gt; 的优势在于我们可以将它写在基于 cfscript 的 cfcs 中。

    【讨论】:

      【解决方案3】:

      我找到了上面的解决方案

      <cfcontent variable="#toBinary(toBase64(img))#" type="image/png" reset="true" />
      

      不太适合我。

      设置 type="image/png" 只是设置响应的 mime 类型。我认为它不一定将图像编码为PNG。因此,与 &lt;cfimage action = "writeToBrowser"...&gt; 方法相比,生成透明 png(图像类型“argb”)给了我奇怪的颜色。

      我想我需要以某种方式将图像数据显式编码为 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())>
      

      希望对大家有所帮助!

      【讨论】:

      • 对,cfcontent 只设置Content-Type 标头(并且可以选择返回文件或变量的内容)。不应该修改内容。什么代码给了你“与writeToBrowser相比奇怪的颜色”?
      • 我用这段代码得到了奇怪的颜色,Leigh: 谢谢罗斯!
      【解决方案4】:

      去掉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" />
      

      【讨论】:

        【解决方案5】:

        我做类似的事情,你需要结合使用标签和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)

        【讨论】:

          猜你喜欢
          • 2011-02-17
          • 2020-08-02
          • 2010-09-10
          • 1970-01-01
          • 2020-10-23
          • 2014-06-07
          • 1970-01-01
          • 2012-08-20
          相关资源
          最近更新 更多