我一直在尝试使用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标签分别显示每一行,但仍然需要以某种方式拆分它!
答案 0 :(得分:2)
包装文字肯定不是单行;-)不幸的是,你不能简单地计算字符数,因为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 />
结果: (使用默认字体/自动缩放)