我一直在尝试使用 CF10 中的 imageDrawText 标签在图像上添加文本水印。
这是一些测试代码
<cfset img = imageNew("",500,500,"rgb","blue")>
<cfset text = "This is just another test! See if text fits the imgage...">
<cfset buffered = ImageGetBufferedImage(img)>
<cfset context = buffered.getGraphics().getFontRenderContext()>
<cfset Font = createObject("java", "java.awt.Font")>
<cfset textFont = Font.init( "Arial", Font.BOLD, javacast("int", 40))>
<cfset textLayout = createObject("java", "java.awt.font.TextLayout").init( text, textFont, context)>
<cfset textBounds = textLayout.getBounds()>
<cfset textWidth = textBounds.getWidth()>
<cfset textHeight = textBounds.getHeight()>
<cfset attr = { font="Arial", size="40", style="bold" }>
<cfset x = (ImageGetWidth(img) / 2 - textWidth / 2)>
<cfset y = (ImageGetHeight(img) / 2 + textHeight / 2)>
<cfset imageSetDrawingColor(img,"black")>
<cfset imageDrawText(img,text, x, y, attr)>
<cfimage action="writeToBrowser" source="#img#">
问题是我不知道如何换行并使文本居中......
左边是代码生成的内容,右边是我想要得到的内容
需要注意的是,每张图像的字体大小和字符数都会有所不同,这是我不知道如何正确计算的主要原因。
我最初的想法是计算字符数并查看有多少字符适合图像宽度,尽管由于上述原因这是不可能的。那么是否有一个单行代码或者需要某种数学函数来手动分割文本宽度和换行?也许我应该使用额外的或 x imageDrawText 标签来单独显示每一行,但仍然需要以某种方式分割它!
最佳答案
换行文本绝对不是一行行;-) 不幸的是,您不能简单地计算字符数,因为 the sizes of the individual glyphs can vary ,除非您使用的是等宽字体。
本质上,准确换行文本的唯一方法是迭代字符串,测量每个单词的大小(以当前字体)并查看它是否适合当前行。如果没有,请另起一行。还有更多内容,但底线涉及两个步骤:1)测量文本并将其分割成行2)然后将文本行绘制到图像上
您可以使用不同的方法来测量文本并将其分割成行。我的偏好是使用 LineBreakMeasurer因为它完成了大部分艰苦的工作。你只需给它包裹区域的宽度,它就会 auto-magically calculates how much of the text can fit on the current line .
许多个月前,我整理了一个small library for wrapping and scaling image text (旧博客,未维护)。试一试。它有点旧,但我认为它应该可以解决问题。
更新:
我刚刚记得图书馆不会将文本垂直居中,而是水平居中。但是,由于它返回包装文本的尺寸,因此您可以轻松计算它。这是一个非常快速但肮脏的例子:
代码:
<cfset text = "If you're going through hell, keep going" />
<!--- overall image dimensions --->
<cfset imageWidth = 500 />
<cfset imageHeight = 500 />
<!--- desired wrapping area --->
<cfset textMargin = 25 />
<cfset wrapWidth = imageWidth - (textMargin*2) />
<cfset wrapHeight = 100 />
<!--- create a blank image with background --->
<cfset img = ImageNew("", imageWidth, imageHeight, "rgb") />
<cfset imageSetDrawingColor( img, "d9d9ff" ) />
<cfset imageDrawRect(img, 0, 0, imageWidth, imageHeight, true) />
<!--- measure dimensions of wrapped text --->
<cfset util = createObject("java", "org.cfsearching.image.WrapImageText") />
<cfset util.init( text, wrapWidth, wrapHeight ) />
<cfset util.setAlignment( util.CENTER_ALIGN ) />
<cfset util.setColor( "0000ff" ) />
<cfset util.setDrawText( false ) />
<cfset util.setX( textMargin ) />
<cfset util.setFont( "Arial", util.BOLD, 40) />
<!--- note: when disabled, text may overflow established wrap height
<cfset util.setAutoScale( false ) />
--->
<!--- use dimensions to center text VERTICALLY --->
<cfset dimen = util.wrapText( ImageGetBufferedImage(img) ) />
<cfset y = (imageHeight - dimen.height) / 2 />
<cfset util.setY( y ) />
<!--- draw the wrapped text --->
<cfset util.setDrawText( true ) />
<cfset dimen = util.wrapText( ImageGetBufferedImage(img) ) />
<!--- display results --->
<cfimage action="writeToBrowser" source="#img#" /> <br />
结果: (使用默认字体/自动缩放)
关于coldfusion - imageDrawText中心文字水印(断线),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21063126/