In the CFML function imageDrawText()
and tag <cfimage action="captcha">
, you can enter a font to be used for the text output. Unfortunately, this font must first be available to the JVM (eg. Tomcat) to be able to use it.
I did have the TrueType font file available, But I did not want to manually add the font file to every Lucee instance. That's not portable code...
Luckily, I found a workaround by programmatically adding the font file to the java.awt.GraphicsEnvironment:
<cfset oFont = createObject('java', 'java.awt.Font') /> <cfset stream = createObject('java', 'java.io.FileInputStream').init(expandPath('./SoftwareFont.ttf')) /> <cfset sFont = oFont.createFont(oFont.TRUETYPE_FONT, stream) /> <cfset createObject('java', 'java.awt.GraphicsEnvironment').getLocalGraphicsEnvironment().registerFont(sFont) />
These 4 lines only have to be executed once during the JVM lifecycle, but it does not throw an error if you execute it multiple times. My suggestion is, to wrap the 4 lines in a conditional statement:
<cfif not structKeyExists(application, "__fontAdded")> <cfset oFont = createObject...... [....] <cfset application.__fontAdded = 1 /> </cfif>
To make the example complete, here is a working example implementation:
<!--- download a ttf file ---> <cfset filePath = getTempDirectory() & "Balthazar-Regular.ttf" /> <cfhttp url="https://github.com/google/fonts/blob/master/ofl/balthazar/Balthazar-Regular.ttf?raw=true" getasbinary="true" file="#filePath#"/> <!--- add the font to java.awt.GraphicsEnvironment ---> <cfif not structKeyExists(application, "__fontAdded")> <cfset oFont = createObject('java', 'java.awt.Font') /> <cfset stream = createObject('java', 'java.io.FileInputStream').init(filePath) /> <cfset sFont = oFont.createFont(oFont.TRUETYPE_FONT, stream) /> <cfset createObject('java', 'java.awt.GraphicsEnvironment').getLocalGraphicsEnvironment().registerFont(sFont) /> <cfset application.__fontAdded = 1 /> </cfif> <!--- create an image and write text to it ---> <cfset text = "This IS a custom Font Test with imageDrawText()" /> <cfset myImg = imageNew("", 800, 50) /> <cfset imageSetAntialiasing(myImg, true) /> <cfset imageDrawText(myImg, text, 10, 35, { size="40.0" , font="Balthazar"// <<<------ this is what it was all about! }) /> <cfimage action="write" source="#myImg#" destination="#expandPath('./test1.png')#" quality="1" overwrite="true" /> <!--- output test1 ---> <img src="test1.png" /> <hr/> <!--- create a captcha file ---> <cfimage action="captcha" text="Captcha test" width="600" height="150" fonts="Balthazar" fontSize="50" destination="test2.png" overwrite="true" /> <!--- output test2 ---> <img src="test2.png" />| Viewed 6707 times
#1 by Ben Nadel - November 10, 2022 at 12:48 PM
Not sure if it's the version of ACF or Java or what, but no luck on my end.