elixir-image/image

Add support for autofit text to line up flush to a containing boxes left and right margins

Closed this issue · 8 comments

I have a simple autofit text with width and height.

awayblock =
"WP: #{(100 * awaywp / (awaywp + homewp)) |> Decimal.from_float() |> Decimal.round(2)}%\nOdds: #{odds.awayml |> Decimal.from_float() |> Decimal.round(2)}\nEdge: #{fixture.awayscore}\nScore: #{fixture.awayscore}"
|> Image.Text.text!(
font_weight: :bold,
font_size: 0,
font: "Imperial",
align: :left,
width: 220,
height: 150,
autofit: true,
background_fill_color: :green,
x: :left
)

Autofit works great, but I really need the text to be flush with the left most margin. I look at Image.Text.Options, and I see x: as an option and I want to set it to left so it begins the fit at the leftmost margin, but my text ends up being centered w.r.t the largest width newline, which I do not want.

image

@severian1778 thanks for the report. I'll look into this as soon as I can but I can't get to it for about 12 hours or so. Sorry for the inconvenience.

@kipcole9 no worries, I love your library, its kicks Mogrify's ass. I am paitient for such great work.

Thanks for the feedback, its much appreciated and definitely helps with motivation.

What is happening that causes this issue

  • When rendering text with autofit: true there is no guarantee that the resulting image is of the dimensions specified.
  • Therefore after rendering, the text image is centred in an image of the exact dimensions specified.

Options to improve

  • One option is to accept a text image that is not exactly of the dimensions required. This will ensure the text is abutted to the left but any assumptions about layout will be invalid since the size of the text image won't be what is expected. This could be something like an option: size: :exact or size: :approx or some such.
  • Another option is to specify a :gravity that maintains the exact size of the text image as specified but rather than being centred, the text is placed according to :gravity which would be :center, :top, :bottom:, :right, :left.

I think I prefer option (1) above but would welcome your comments and suggestions.

Hey @kipcole9 I am cool with your choice whatever you think is best, I like "gravity" the best because its just super simple, here is my block of text rendered as an image, here is my containing image. Because I cannot be sure of the size of the rendered text image, I would like to push it to the margin that best makes sense for my application with the default being center. This is user friendly to me and fully completes text as a module imho as align works wonderfully in terms of newline alignment.

Sorry for the delay in getting this done. I have gone with the idea of specifying :x and :y as per my original (but never implemented) approach. The relevant part of the changelog entry is:

  • Adds :x and :y options to Image.Text.text/2 which allows placing the text on its background in the specified location. :x can be specified as a non-negative integer or one of :left, :right or :center with the default being :center. :y can be specified as a non-negative integer or one of :top, :bottom or :middle with the default being :middle. Thanks to @severian1778 for the issue and collaboration. Closes #44.

Would you consider giving this a spin (configuring {:image, github: "elixir-image/image"} in mix.exs) and letting me know? Your example with x: :left should work now as expected.

Of course please reopen the issue if its not properly solved.

Hi @kipcole9 yup im back in the saddle tomorrow and I will give it a spin. Thank you so much for the speedy response!

@kipcole9 clean and mean. Thank you!
image