I'm creating Excel files using ColdFusion and the SpreadsheetNew, SpreadsheetAddRows, SpreadsheetFormatRows, etc. functions. According to the docs that I have read located here their is a propery for color, and fgcolor. I'm a bit confused as to what the difference between the two are. Is one the text color and the other the background color? I've been using fgcolor to set the background color of rows.
// HEADER ROW FORMAT
formatHeaderRow = StructNew();
formatHeaderRow.fgcolor="royal_blue";
My main question is, according to the docs I can supply any value in the org.apache.poi.hssf.util.HSSFColor color class as my color. However, I REALLY need to supply either a HEX value or RGB. I know Excel can handle it as you can enter either within excel's colorpicker. Is there ANY way to enter a HEX or RGB value for my row colors?
thank you!
UPDATE
<cfscript>
// create XLSX workbook with a few cells
// and grab underlying POI objects
cfSheet = Spreadsheetnew("Sheet1", true);
poiWorkbook = cfSheet.getWorkBook();
poiSheet = poiWorkbook.getSheet("Sheet1");
// Create reusuable style objects
// NOTE: Excel limits the maximum number of styles allowed. So do not create a new
// style for every cell. Create distinct styles once, and apply to multiple cells/rows.
Color = createObject("java", "java.awt.Color");
// Style 1: Cell with background color (only)
backgroundOnlyStyle = poiWorkbook.createCellStyle();
backgroundOnlyStyle.setFillPattern( backgroundOnlyStyle.SOLID_FOREGROUND );
XSSFColor = createObject("java", "org.apache.poi.xssf.usermodel.XSSFColor");
backgroundOnlyStyle.setFillForegroundColor( XSSFColor.init(Color.decode("##055910")) );
// Apply styles to cell A1. Note: POI indexes are 0-based
SpreadSheetSetCellValue(cfSheet, "background color only", 1, 1);
poiSheet.getRow( 0 ).setRowStyle( backgroundOnlyStyle );
</cfscript>
<!--- stream it to the browser --->
<cfheader name="Content-Disposition" value="inline; filename=reportName.xlsx">
<cfcontent type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" variable="#SpreadSheetReadBinary(cfSheet)#">
I'm a bit confused as to what the difference between the two are.
Understandably. The property names were modeled after the conventions used in POI (underlying java library) which are a bit confusing to begin with IMO. Since ColdFusion only implements a subset of the POI features, the names are taken out of context, making it even more confusing. To answer your question, in POI there are actually three (3) relevant color properties here:
Font Color - ie Font.setColor()
The color of the cell text. In CF, this is controlled by the dataFormat.color property.
Cell Pattern Foreground Color - ie CellStyle.setFillForegroundColor
Despite the name, this is what most people think of as the cell background color (yellow in the image below). In CF this is controlled by the dataFormat.fgColor property.
Cell Pattern Background Color - CellStyle.setFillBackgroundColor
(Optional) Secondary color used in multi-color cell patterns (red in the image below). There is no ColdFusion equivalent.
Is there ANY way to enter a HEX or RGB value for my row colors?
Last I checked it is not supported by the core CF functions. However, you could tap into the underlying POI library which does support it. Assuming you are using the newer .XLSX format, it can be done by creating a CellStyle and applying the desired XSSFColor.
Here is an example (tested with CF11) of how to set the font and/or cell background colors via POI. Though in the real code, I would recommend wrapping up the basic logic in a reusable function.
Example:
// create XLSX workbook with a few cells
// and grab underlying POI objects
cfSheet = Spreadsheetnew("Sheet1", true);
poiWorkbook = cfSheet.getWorkBook();
poiSheet = poiWorkbook.getSheet("Sheet1");
// Create reusuable style objects
// NOTE: Excel limits the maximum number of styles allowed. So do not create a new
// style for every cell. Create distinct styles once, and apply to multiple cells/rows.
Color = createObject("java", "java.awt.Color");
// Style 1: Cell with background color (only)
backgroundOnlyStyle = poiWorkbook.createCellStyle();
backgroundOnlyStyle.setFillPattern( backgroundOnlyStyle.SOLID_FOREGROUND );
XSSFColor = createObject("java", "org.apache.poi.xssf.usermodel.XSSFColor");
backgroundOnlyStyle.setFillForegroundColor( XSSFColor.init(Color.decode("##055910")) );
// Style 2: Cell with font color (only)
textOnlyStyle = poiWorkbook.createCellStyle();
textFont = poiWorkbook.createFont();
XSSFColor = createObject("java", "org.apache.poi.xssf.usermodel.XSSFColor");
textFont.setColor( XSSFColor.init(Color.decode("##bd13be")) );
textOnlyStyle.setFont( textFont );
// Style 3: Cell with both backgound and Text color
backgroundAndTextStyle = poiWorkbook.createCellStyle();
textFont = poiWorkbook.createFont();
XSSFColor = createObject("java", "org.apache.poi.xssf.usermodel.XSSFColor");
textFont.setColor( XSSFColor.init(Color.decode("##a20932")) );
backgroundAndTextStyle.setFont( textFont );
XSSFColor = createObject("java", "org.apache.poi.xssf.usermodel.XSSFColor");
backgroundAndTextStyle.setFillPattern( backgroundAndTextStyle.SOLID_FOREGROUND );
backgroundAndTextStyle.setFillForegroundColor( XSSFColor.init(Color.decode("##192fda")) );
// Apply styles to cell A1. Note: POI indexes are 0-based
SpreadSheetSetCellValue(cfSheet, "background color only", 1, 1);
poiSheet.getRow( 0 ).getCell( 0 ).setCellStyle( backgroundOnlyStyle );
// Apply styles to cell A2
SpreadSheetSetCellValue(cfSheet, "text color only", 2, 1);
poiSheet.getRow( 1 ).getCell( 0 ).setCellStyle( textOnlyStyle );
// Apply styles to cell A3
SpreadSheetSetCellValue(cfSheet, "background AND text color", 3, 1);
poiSheet.getRow( 2 ).getCell( 0 ).setCellStyle( backgroundAndTextStyle );
// Save to file
SpreadSheetWrite(cfSheet, "c:/path/to/yourFile.xlsx", true);
Over the weekend, our organization upgraded from ACF11 to ACF2018 and I found that the accepted answer given no longer works because the code has been deprecated and is no longer functional. ACF2018 uses an updated version of the Apache POI Utility from ACF11. Apparently the SOLID_FOREGROUND property has been removed from the CellStyleobject and moved to the FillPatternType object. I just wanted to provide an update to the accepted answer given by #Leigh back in 2016. BTW, many thanks to #Leigh for providing a great code sample that worked for several years. Hopefully this answer will save someone from future grief when updating to newer versions of ACF.
According to the docs from version 3.17 that field was removed.
Use FillPatternType.SOLID_FOREGROUND instead.
From source code of apache-poi 3.15 I can see:
/**
* Fill Pattern: Solidly filled
* #deprecated 3.15 beta 3. Use {#link FillPatternType#SOLID_FOREGROUND} instead.
*/
#Removal(version="3.17")
static final short SOLID_FOREGROUND = 1; //FillPatternType.SOLID_FOREGROUND;
I modified #Leigh's code above and added the following line
FillPatternType = createObject("java", "org.apache.poi.ss.usermodel.FillPatternType");
I then modifed the following 2 lines
backgroundOnlyStyle.setFillPattern( backgroundOnlyStyle.SOLID_FOREGROUND );
...
backgroundAndTextStyle.setFillPattern( backgroundAndTextStyle.SOLID_FOREGROUND );
and changed them to
backgroundOnlyStyle.setFillPattern( FillPatternType.SOLID_FOREGROUND );
...
backgroundAndTextStyle.setFillPattern( FillPatternType.SOLID_FOREGROUND );
I created a working example and gist of #Leigh's code and verified it works in all versions of ACF from ACF10 up to ACF2018.
https://trycf.com/gist/cb4edf103a75b60e0d62259b0f9941ff/acf2018?theme=monokai
<cfscript>
// create XLSX workbook with a few cells
// and grab underlying POI objects
cfSheet = Spreadsheetnew("Sheet1", true);
poiWorkbook = cfSheet.getWorkBook();
poiSheet = poiWorkbook.getSheet("Sheet1");
// Create reusuable style objects
// NOTE: Excel limits the maximum number of styles allowed. So do not create a new
// style for every cell. Create distinct styles once, and apply to multiple cells/rows.
Color = createObject("java", "java.awt.Color");
FillPatternType = createObject("java", "org.apache.poi.ss.usermodel.FillPatternType");
// Style 1: Cell with background color (only)
backgroundOnlyStyle = poiWorkbook.createCellStyle();
backgroundOnlyStyle.setFillPattern( FillPatternType.SOLID_FOREGROUND );
XSSFColor = createObject("java", "org.apache.poi.xssf.usermodel.XSSFColor");
backgroundOnlyStyle.setFillForegroundColor( XSSFColor.init(Color.decode("##055910")) );
// Style 2: Cell with font color (only)
textOnlyStyle = poiWorkbook.createCellStyle();
textFont = poiWorkbook.createFont();
XSSFColor = createObject("java", "org.apache.poi.xssf.usermodel.XSSFColor");
textFont.setColor( XSSFColor.init(Color.decode("##bd13be")) );
textOnlyStyle.setFont( textFont );
// Style 3: Cell with both backgound and Text color
backgroundAndTextStyle = poiWorkbook.createCellStyle();
textFont = poiWorkbook.createFont();
XSSFColor = createObject("java", "org.apache.poi.xssf.usermodel.XSSFColor");
textFont.setColor( XSSFColor.init(Color.decode("##a20932")) );
backgroundAndTextStyle.setFont( textFont );
XSSFColor = createObject("java", "org.apache.poi.xssf.usermodel.XSSFColor");
backgroundAndTextStyle.setFillPattern( FillPatternType.SOLID_FOREGROUND );
backgroundAndTextStyle.setFillForegroundColor( XSSFColor.init(Color.decode("##192fda")) );
// Apply styles to cell A1. Note: POI indexes are 0-based
SpreadSheetSetCellValue(cfSheet, "background color only", 1, 1);
poiSheet.getRow( 0 ).getCell( 0 ).setCellStyle( backgroundOnlyStyle );
// Apply styles to cell A2
SpreadSheetSetCellValue(cfSheet, "text color only", 2, 1);
poiSheet.getRow( 1 ).getCell( 0 ).setCellStyle( textOnlyStyle );
// Apply styles to cell A3
SpreadSheetSetCellValue(cfSheet, "background AND text color", 3, 1);
poiSheet.getRow( 2 ).getCell( 0 ).setCellStyle( backgroundAndTextStyle );
</cfscript>
<!--- Now that spreadsheet is prepared, initiate download --->
<cfheader name="Content-Disposition" value="attachment;filename=yourfile.xlsx">
<cfcontent variable="#spreadsheetReadBinary(cfSheet)#" type="application/vnd.ms-excel">
Related
I am painting a block of text on a widget with QTextDocument::drawContents. My current goal is to intercept mouse events and emulate text selection. It's pretty clear how to handle the mouse, but displaying the result puzzles me a lot.
Just before we start: I can not use QLabel and let it handle selection on it's own (it has no idea how to draw unusual characters and messes up line height (https://git.macaw.me/blue/squawk/issues/59)), nor I can not use QTextBrowser there - it's just a message bubble, I'm not ready to sacrifice performance there.
There is a very rich framework around QTextDocument, but I can not find any way to make it color the background of some fragment of text that I would consider selected. Found a way to make a frame around a text, found a way to draw under-over-lined text, but it looks like there is simply just no way this framework can draw a background behind text.
I have tried doing this, to see if I can take selected fragment under some QTextFrame and set it's style:
QTextDocument* bodyRenderer = new QTextDocument();
bodyRenderer->setHtml("some text");
bodyRenderer->setTextWidth(50);
painter->setBackgroundMode(Qt::BGMode::OpaqueMode); //this at least makes it color background under all text
QTextFrameFormat format = bodyRenderer->rootFrame()->frameFormat();
format.setBackground(option.palette.brush(QPalette::Active, QPalette::Highlight));
bodyRenderer->rootFrame()->setFrameFormat(format);
bodyRenderer->drawContents(painter);
Nothing of this works too:
QTextBlock b = bodyRenderer->begin();
QTextBlockFormat format = b.blockFormat();
format.setBackground(option.palette.brush(QPalette::Active, QPalette::Highlight));
format.setProperty(QTextFormat::BackgroundBrush, option.palette.brush(QPalette::Active, QPalette::Highlight));
QTextCursor cursor(bodyRenderer);
cursor.setBlockFormat(format);
b = bodyRenderer->begin();
while (b.isValid() > 0) {
QTextLayout* lay = b.layout();
QTextLayout::FormatRange range;
range.format = b.charFormat();
range.start = 0;
range.length = 2;
lay->draw(painter, option.rect.topLeft(), {range});
b = b.next();
}
Is there any way I can make this framework do a simple thing - draw a selection background behind some text? If not - is there a way I can unproject cursor position into coordinate translation, like can I do reverse operation from QAbstractTextDocumentLayout::hitTest just to understand where to draw that selection rectangle myself?
You can use QTextCursor to change the background of the selected text. You only need to select one character at a time to keep the formatting. Here is an example of highlighting in blue (the color of the text is highlighted in white for contrast):
void MainWindow::paintEvent(QPaintEvent *event) {
QPainter painter(this);
painter.fillRect(contentsRect(), QBrush(QColor("white")));
QTextDocument document;
document.setHtml(QString("Hello <font size='20'>world</font> with Qt!"));
int selectionStart = 3;
int selectionEnd = selectionStart + 10;
QTextCursor cursor(&document);
cursor.setPosition(selectionStart);
while (cursor.position() < selectionEnd) {
cursor.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor); // select one symbol
QTextCharFormat selectFormat = cursor.charFormat();
selectFormat.setBackground(Qt::blue);
selectFormat.setForeground(Qt::white);
cursor.setCharFormat(selectFormat); // set format for selection
cursor.movePosition(QTextCursor::Right, QTextCursor::MoveAnchor, 1);
}
document.drawContents(&painter, contentsRect());
QMainWindow::paintEvent(event);
}
I've looked here:
https://www.amcharts.com/docs/v4/reference/xycursor/
and tried this
chart.cursor.fontSize = "14";
chart.cursor.fill = am4core.color("#ff0000");
chart.cursor.fontFamily = "verdana";
To style the (default white on black) element when the xycursor touches the X/Y axis (don't know what the correct name for this element is, hope you know which one I mean)
I would like to set the font size and family. Tried to set the color to red to see if it has to be set via the fill property, but also that doesn't work.
Created the cursor like this:
chart.cursor = new am4charts.XYCursor();
chart.cursor.xAxis = axis;
You have to set the tooltip properties inside the axis objects directly, as mentioned in the documentation. For example, to change the font, size and color in the category axis tooltip, modify the tooltip's label object:
categoryAxis.tooltip.getFillFromObject = false;
categoryAxis.tooltip.label.fill = "#ff0000"
categoryAxis.tooltip.label.fontFamily = "Courier New"
categoryAxis.tooltip.label.fontSize = 15;
Demo
I am trying to insert few rows in a QtableWidget and setting the cell background color as follows:
int rowcount = tableWidget->rowCount();
tableWidget->insertRow(rowcount);
QTableWidgetItem *coloItem = new QTableWidgetItem("");
tableWidget->setItem(rowcount, 0, coloItem);
coloItem->setBackground(Qt::GlobalColor(i)); //Qt::GlobalColor(fColor)
Now I want to set opacity of the cell , how can i do it.
I couldnot find anything related to QtableWidget.
I have a CSS container that is 500px x 200px in size.
What I need to do is scale my images so that they fill the container but I want to use a ColdFusion image function to reduce/expand until it fills the dimensions.
For example, if I have a large image that's 1920px x 1080px, then I want ColdFusion to reduce it in size (while maintaining the aspect ratio) until it its just big enough to fill the container dimensions of 500px x 200px. Equally, a small image should be scaled up until it is both at least 500px wide and 200px wide. The key word is at least, because it doesn't matter if goes beyond these dimensions by much.
I could use ImageScaleToFit(), but it will reduce the image until one of the dimensions (either 500px or 200px) is met. So ImageScaleToFit will reduce the image until its 500px wide, but there is a very high chance that the height maybe just 100px. Rather than this, I want ColdFusion to reduce the image until it is at leastboth 500px wide and 200px in height.
I have also tried to use ImageCrop() to simply take a 500px x 200px slice out of an image thats bigger than these dimensions but its not working out very well because on a large image you haven't got a clue what the cropped image was originally meant to be.
How can I solve this? The best analogy I can use to explain what I want is if you create a canvas in Photoshop that is 500px x 200px, and then you place an image on that canvas and use the transform tool to expand/reduce it until that canvas is filled. Obviously not all of the image will appear on the canvas, but that's ok because most of it is there.
You can do the math yourself, I loop over some sample data, but only as a demonstration.
<cfset dimlist="1000|800,1000|1000,800|1000,1000|200,500|1000,600|1000,230|40,400|300,300|500,499|200,500|199,499|199">
<cfloop list="#dimlist#" index="dims">
<Cfset dheight = listfirst(dims,"|")>
<cfset dwidth = listlast(dims,"|")>
<cfset hratio = dheight / 500>
<cfset wratio = dwidth / 200>
<cfif dwidth / hratio gte 200>
<cfset finalh = int(dheight / hratio)>
<cfset finalw = int(dwidth / hratio)>
<cfelse>
<cfset finalh = int(dheight / wratio)>
<cfset finalw = int(dwidth / wratio)>
</cfif>
<cfoutput> #dheight# x #dwidth# converts to #finalh# x #finalw#<br /></cfoutput>
</cfloop>
In truth, you could turn this into a function easily
<cfscript>
function CalcSz(numeric ih, numeric iw, numeric dh = 500, numeric dw = 200) {
var hratio = arguments.ih / arguments.dh;
var wratio = arguments.iw / arguments.dw;
if(arguments.iw / hratio > arguments.dw) {
var finalh = int(arguments.ih / hratio);
var finalw = int(arguments.iw / hratio);
} else {
var finalh = int(arguments.ih / wratio);
var finalw = int(arguments.iw / wratio);
}
return {height = finalh, width = finalw};
}
</cfscript>
<cfset dimlist="1000|800,1000|1000,800|1000,1000|200,500|1000,600|1000,230|40,400|300,300|500,499|200,500|199,499|199">
<cfloop list="#dimlist#" index="dims">
<Cfset dheight = listfirst(dims,"|")>
<cfset dwidth = listlast(dims,"|")>
<cfset dimstruct = CalcSz(dheight,dwidth)>
<cfoutput> #dheight# x #dwidth# converts to #dimstruct.height# x #dimstruct.width#<br /></cfoutput>
</cfloop>
This returns a struct containing .height and .width, as you can see.
As you can also see, it has no problem with conversions downsizing, upsizing, or when either is very close (499 or 199).
Needless to say, don't pass a 0 as any argument :).
Has anyone an example of implementing a JFreechart Dial chart on Coldfusion?
Thanks
(This probably should not be a separate answer, but the other was already pretty long. So I am posting it separately to keep things organized and easy to find.)
In case you are looking for what jFreeChart calls a MeterChart, here is a quick and dirty example of that chart type.
MeterChart Code:
<cfscript>
// my chart settings
chartTitle = "My Meter Chart";
arrowValue = 55;
arrowUnits = "widgets";
chartWidth = 500;
chartHeight = 500;
// initialize meter ranges (LOW, MEDIUM, HIGH)
// note: quick and ugly code in dire need of improvement ...
low = createSolidMeterInterval("Low", 0, 40, createAwtColor(0, 255, 0, 120));
med = createSolidMeterInterval("Med", 40, 60, createAwtColor(255, 255, 0, 120));
high = createSolidMeterInterval("High", 60, 100, createAwtColor(255, 0, 0, 120));
// initialize arrow value
DefaultValueDataset = createObject("java", "org.jfree.data.general.DefaultValueDataset");
meterPointer = DefaultValueDataset.init(arrowValue);
//initialize plot and apply settings
plot = createObject("java", "org.jfree.chart.plot.MeterPlot").init();
plot.setDataset(meterPointer);
plot.setTickLabelsVisible(true);
plot.addInterval(low);
plot.addInterval(med);
plot.addInterval(high);
plot.setUnits(arrowUnits);
// create chart and convert it to an image
chart = createObject("java", "org.jfree.chart.JFreeChart").init(chartTitle, plot);
ChartUtilities = createObject("java", "org.jfree.chart.ChartUtilities");
ChartUtilities.applyCurrentTheme(chart);
// applyCurrentTheme seems to overwrite some settings, so we must reapply them
Color = createObject("java", "java.awt.Color");
plot.setBackgroundPaint(Color.GRAY);
plot.setNeedlePaint(Color.BLACK);
chartImage = chart.createBufferedImage(chartWidth, chartHeight);
ImageFormat = createObject("java", "org.jfree.chart.encoders.ImageFormat");
EncoderUtil = createObject("java", "org.jfree.chart.encoders.EncoderUtil");
bytes = EncoderUtil.encode( chartImage, ImageFormat.PNG);
</cfscript>
<!--- display in browser --->
<cfcontent type="image/png" variable="#bytes#">
Auxiliary functions:
<cfscript>
// quick and ugly functions. could be improved ...
function createSolidMeterInterval(Title, fromValue, toValue, BgColor) {
var Range = createObject("java", "org.jfree.data.Range").init(arguments.fromValue, arguments.toValue);
var MeterInterval = createObject("java", "org.jfree.chart.plot.MeterInterval");
return MeterInterval.init(arguments.Title, Range // interval from / to range
, javacast("null", "") // outline color
, javacast("null", "") // outline stroke
, arguments.BgColor // background color
);
}
// using java.awt.Color is a pain due to all the javacasts ...
function createAwtColor(r, g, b, alpha) {
var color = createObject("java", "java.awt.Color");
return color.init( javacast("int", arguments.r)
, javacast("int", arguments.g)
, javacast("int", arguments.b)
, javacast("int", arguments.alpha) // transparency
);
}
</cfscript>
The package org.jfree.chart.demo has examples of how to construct a few basic charts; click on the class name to see the source. The methods of org.jfree.chart.ChartFactory show how to construct still more. The class org.jfree.chart.ChartUtilities includes methods to stream charts in several formats. A corresponding response.setContentType() works from any servlet container.
If this is terra incognita, I'd recommend The JFreeChart Developer Guide†.
†Disclaimer: Not affiliated with Object Refinery Limited; just a satisfied customer and very minor contributor.
Using trashgod's suggestions, I created a very rudimentary example for CF7. You can obviously do much more with it. Just review the api and/or purchase the developer guide.
Install:
Download latest jfreeChart. Copy the following jars into {cf_root}\WEB-INF\lib and restart CF. Note, jar version numbers may vary.
jfreechart-1.0.13.jar
jcommon-1.0.16.jar
Sample:
<cfscript>
// my chart settings
chartTitle = "My Dial Chart";
arrowValue = 55;
dialMinimum = 0;
dialMaximum = 100;
chartWidth = 500;
chartHeight = 500;
// initialize basic components of the chart
// see jFreeChart API on how to customize the components settings further
DefaultValueDataset = createObject("java", "org.jfree.data.general.DefaultValueDataset");
pointerValue = DefaultValueDataset.init(arrowValue);
dialPointer = createObject("java", "org.jfree.chart.plot.dial.DialPointer$Pointer").init();
dialFrame = createObject("java", "org.jfree.chart.plot.dial.StandardDialFrame").init();
dialBackground = createObject("java", "org.jfree.chart.plot.dial.DialBackground").init();
// tweak the default range to make it more appealing.
// see angle/extent: http://java.sun.com/developer/technicalArticles/GUI/java2d/java2dpart1.html
dialScale = createObject("java", "org.jfree.chart.plot.dial.StandardDialScale").init();
dialScale.setLowerBound(dialMinimum);
dialScale.setUpperBound(dialMaximum);
dialScale.setStartAngle(-150);
dialScale.setExtent(-240);
//initialize plot and apply settings
plot = createObject("java", "org.jfree.chart.plot.dial.DialPlot").init();
plot.setDialFrame(dialFrame);
plot.setBackground(dialBackground);
plot.setDataset(pointerValue);
plot.addScale(0, dialScale);
plot.addPointer(dialPointer);
// create chart and convert it to an image
chart = createObject("java", "org.jfree.chart.JFreeChart").init(chartTitle, plot);
chartImage = chart.createBufferedImage(chartWidth, chartHeight);
ImageFormat = createObject("java", "org.jfree.chart.encoders.ImageFormat");
EncoderUtil = createObject("java", "org.jfree.chart.encoders.EncoderUtil");
bytes = EncoderUtil.encode( chartImage, ImageFormat.PNG);
</cfscript>
<!--- display in browser --->
<cfcontent type="image/png" variable="#bytes#">