2011-04-12 16 views
7

Tengo un servicio en un servidor Coldfusion 9 que crea banners de imágenes sobre la marcha para nosotros. Una máquina separada tiene que guardar estos archivos con algo como:¿Cómo se escribe una imagen en el navegador como una secuencia binaria en coldfusion?

wget http://myserver.com/services/local/bannerCreator/250x250-v3.cfm?prodID=3&percentSaving=19 

El problema es que no puedo pensar en cómo conseguir ColdFusion para escribir datos binarios sin necesidad de utilizar un archivo temporal. En el momento en que la imagen se muestra como una etiqueta de imagen como esta:

<cfimage action = "writeToBrowser" source="#banner#" width="#banner.width#" height="#banner.height#" /> 

¿Alguna idea? ¿O debería usar un archivo temporal?

Respuesta

12

No puedo realizar la prueba porque no está dando ningún código de ejemplo sobre cómo se generan sus imágenes, pero ¿ha intentado algo en esta línea?

<cfcontent reset="true" variable="#imageData#" type="image/jpg" /> 

Actualización: Así que siguió adelante y creó mi propia imagen; Asumiré que estás haciendo algo similar. Esto funciona perfectamente para mí:

<cfset img = imageNew("",200,200,"rgb","red") /> 
<cfcontent variable="#toBinary(toBase64(img))#" type="image/png" reset="true" /> 

Esto funciona sin necesidad de escribir en un archivo, y sin necesidad de utilizar un sistema de archivos virtual ("ramdisk")

+0

FYI: no hay necesidad de establecer explícitamente el atributo de reinicio a 'verdadera ', porque' true' es el valor predeterminado. –

3

Sacar los atributos de altura y anchura y añadir el atributo de formato:

<cfimage action = "writeToBrowser" source="#banner#" format="png" /> 

wget deberían reconocer la redirección al archivo CF física crea en la carpeta CFFileServlet pero si no lo hace hay una bandera puede configurar para que sea --max-redirect=10.

Y como sugiere, un archivo temporal también funcionaría. Simplemente escriba el archivo y use cfheader y cfcontent para escribirlo. Solo asegúrate de hacer que el nombre del archivo temporal sea más único.

<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

Si usted tiene los bytes binarios de un archivo/imagen, se puede reemplazar el búfer de salida con su contenido, así:

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

bastante más de lo <cfcontent> hace cuando se utiliza reset="true"

La ventaja de este método sobre <cfcontent> es que podemos escribirlo dentro de nuestros cfcs basados ​​en cfscript.

4

he encontrado la solución anterior

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

al trabajo no es para mí.

Tipo de configuración = "image/png" simplemente configura el tipo de mime de la respuesta. No creo que necesariamente esté codificando la imagen como PNG. Como tal, la generación de un png transparente (tipo de imagen "argb") me daba colores extraños, en comparación con el método <cfimage action = "writeToBrowser"...>.

Pensé que de alguna manera tenía que codificar explícitamente los datos de imagen como PNG y enviar los datos binarios directamente.

Con un poco de excavación en el java subyacente, se me ocurrió esto, que hasta ahora parece funcionar para mí.

Este ejemplo dibuja un png transparente con un círculo negro.

<!--- 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())> 

Espero que ayude a alguien!

+0

A la derecha, 'cfcontent' solo establece el encabezado' Content-Type' (y opcionalmente devuelve el contenido de un archivo o variable). No se supone que debe modificar el contenido. ¿Qué código le dio "colores extraños en comparación con' writeToBrowser' "? – Leigh

+0

Tengo los colores extraños con este código, Leigh: Gracias Ross! – jessieloo

0

Hago una cosa similar, y necesita combinar el uso de etiquetas y cfscript. Hay funciones de imagen que se requieren. Hay muchas funciones de imagen disponibles, una vez que tiene una imagen en la memoria como una variable. Puede obtener la imagen en la memoria usando CFFILE o CFHTTP o una serie de otras formas.

En mi caso, leo un archivo de imagen en la memoria usando la etiqueta CFIMAGE, luego lo manipulo con funciones de imagen CFSCRIPT agregando texto en la parte inferior, y luego obtengo la imagen resultante como .png (o a .jpg si lo prefiere) al navegador. El único archivo almacenado en el servidor es el archivo de imagen original. En su caso, en lugar de leer una imagen, la llamaría usando una etiqueta cfhttp como ya lo hace. Aquí está mi código:

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

Se puede ver en acción en http://hawkesburyradio.com.au/index.cfm?pid=111538

(estoy usando CF9 con Windows Server)

Cuestiones relacionadas