Как вы записываете изображение в браузер в виде двоичного потока в coldfusion?

У меня есть служба на сервере 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#" />

Есть идеи? Или я должен просто использовать временный файл?


person boodle    schedule 12.04.2011    source источник


Ответы (5)


Я не могу протестировать, потому что вы не даете никакого примера кода для создания ваших изображений, но пробовали ли вы что-то в этом роде?

<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").

person Adam Tuttle    schedule 12.04.2011
comment
К вашему сведению: нет необходимости явно устанавливать для атрибута сброса значение true, поскольку true является значением по умолчанию. - person Jacob van Lingen; 29.08.2016

Если у вас есть двоичные байты файла/изображения, вы можете заменить выходной буфер его содержимым следующим образом:

<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> заключается в том, что мы можем написать его внутри нашего cfc, основанного на cfscript.

person Mike Causer    schedule 15.12.2011

Я нашел решение выше

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

не совсем работать для меня.

Установка type="image/png" - это просто установка типа mime ответа. Я не думаю, что это обязательно кодирование изображения как PNG. Таким образом, создание прозрачного png (тип изображения «argb») давало мне странные цвета по сравнению с методом <cfimage action = "writeToBrowser"...>.

Я подумал, что каким-то образом мне нужно явно кодировать данные изображения как 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())>

Я надеюсь, что это поможет кому-то!

person Ross Taylor    schedule 29.05.2012
comment
Верно, cfcontent устанавливает только заголовок Content-Type (и необязательно возвращает содержимое файла или переменной). Не предполагается изменять содержимое. Какой код дал вам странные цвета по сравнению с writeToBrowser? - person Leigh; 29.05.2012
comment
Я получил странные цвета с помощью этого кода, Ли: ‹cfset img = imageNew(,1,1,argb,) /› ‹cfcontent variable=#toBinary(toBase64(img))# type=image/png reset=true /› Спасибо, Росс! - person jessieloo; 08.02.2013

Уберите атрибуты высоты и ширины и добавьте атрибут формата:

<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" />
person Matt Shooks    schedule 12.04.2011

Я делаю подобное, и вам нужно совместить использование тегов и 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

(Я использую CF9 с Windows Server)

person user3001950    schedule 06.08.2014