imageDrawText текстовый водяной знак по центру (линии разрыва)

Я пытался добавить текстовый водяной знак на изображения, используя тег imageDrawText в CF10.

вот код тестирования

<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 для отображения каждой строки отдельно, хотя все же нужно как-то разделить ее!


person user2595617    schedule 11.01.2014    source источник


Ответы (1)


Обтекание текста определенно не является однострочным ;-) К ​​сожалению, вы не можете просто считать символы, потому что размеры отдельных глифов могут различаться, если, возможно, вы не используете моноширинный шрифт.

По сути, единственный способ точно перенести текст — это перебрать строку, измерить размер каждого слова (в текущем шрифте) и посмотреть, помещается ли оно в текущей строке. Если нет, начните новую строку. Это еще немного, но суть состоит из двух шагов: 1) измерить и разбить текст на строки 2) затем нарисовать строки текста на изображении

Существуют разные способы измерения и разделения текста на строки. Я предпочитаю использовать LineBreakMeasurer. потому что он делает большую часть тяжелой работы. Вы просто указываете ему ширину области переноса, и он автоматически вычисляет, какая часть текста может поместиться в текущей строке.

Много лун назад я собрал небольшая библиотека для обтекания и масштабирования текста изображения (старый блог, не поддерживается). Дайте ему вихрь. Это немного старо, но я думаю, что это должно сработать.

ОБНОВЛЕНИЕ:

Я только что вспомнил, что библиотека не центрирует текст по вертикали, а только по горизонтали. Однако, поскольку он возвращает размеры обернутого текста, вы можете легко его вычислить. Вот очень быстрый и грязный пример:

Код:

    <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 />

Результат: (используется шрифт по умолчанию/автоматическое масштабирование)

Текст с центрированием по горизонтали и вертикали

person Leigh    schedule 11.01.2014