elixir-image / image

Image processing for Elixir

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Image.Text.text sometimes fails with error

tielur opened this issue · comments

I'm not sure exactly what is going on but sometimes this code will fail:

Image.Text.text!("test")

with:

** (MatchError) no match of right hand side value: {:error, "Could not normalize box with {{39, 13}, 39, 13, 0, 0}"}
    (image 0.31.1) lib/image/text.ex:383: Image.Text.simple_text/2
    (image 0.31.1) lib/image/text.ex:138: Image.Text.text/2
    (image 0.31.1) lib/image/text.ex:268: Image.Text.text!/2
    iex:15: (file)

I'm running this on an alpine container, here's the example of a few runs in iex on the container:

iex(hello_world@295dd226a123)17> Image.Text.text!("test")
** (MatchError) no match of right hand side value: {:error, "Could not normalize box with {{39, 13}, 39, 13, 0, 0}"}
    (image 0.31.1) lib/image/text.ex:383: Image.Text.simple_text/2
    (image 0.31.1) lib/image/text.ex:138: Image.Text.text/2
    (image 0.31.1) lib/image/text.ex:268: Image.Text.text!/2
    iex:17: (file)
iex(hello_world@295dd226a123)17> Image.Text.text!("test")
%Vix.Vips.Image{ref: #Reference<0.3618102734.1357512722.58557>}
iex(hello_world@295dd226a123)18> Image.Text.text!("test")
** (MatchError) no match of right hand side value: {:error, "Could not normalize box with {{39, 13}, 39, 13, 0, 0}"}
    (image 0.31.1) lib/image/text.ex:383: Image.Text.simple_text/2
    (image 0.31.1) lib/image/text.ex:138: Image.Text.text/2
    (image 0.31.1) lib/image/text.ex:268: Image.Text.text!/2
    iex:18: (file)
iex(hello_world@295dd226a123)18> Image.Text.text!("test")
** (MatchError) no match of right hand side value: {:error, "Could not normalize box with {{39, 13}, 39, 13, 0, 0}"}
    (image 0.31.1) lib/image/text.ex:383: Image.Text.simple_text/2
    (image 0.31.1) lib/image/text.ex:138: Image.Text.text/2
    (image 0.31.1) lib/image/text.ex:268: Image.Text.text!/2
    iex:18: (file)
iex(hello_world@295dd226a123)18> Image.Text.text!("test")
%Vix.Vips.Image{ref: #Reference<0.3618102734.1357512722.58566>}
iex(hello_world@295dd226a123)19> Image.Text.text!("test")
%Vix.Vips.Image{ref: #Reference<0.3618102734.1357512722.58573>}
iex(hello_world@295dd226a123)20>

It looks like the non-bang version of Image.Text.text does the same thing

Yeah, that's not good. I'm travelling today but should be able to dig into it in a few hours. Very troubling that its intermittent. The bang version delegates to the non-bang version so I would expect the symptoms would be the same.

I've not seen this before but I test only on Mac and Ubuntu 20.04 for now.

If it helps as well I'm using the default PRECOMPILED_NIF_AND_LIBVIPS, I haven't tried installing LIBVIPS yet

I'll see if I can throw together a quick mix application with a Dockerfile to reproduce

That's an interesting point - I build and test with the system provided libvips (the precompiled version doesn't have all of the plugins configured that image can use).

Ok so here's something that's good but interesting haha. I threw together a quick mix application with a dockerfile and when I use Image version 0.31.1 I get the same results, but when I upgrade to 0.32.0 it doesn't fail

{:ok, %Vix.Vips.Image{ref: #Reference<0.2699864616.1896742930.138885>}}
iex(text_failure_example@4fc7c58d553b)3> Image.Text.text("test")
{:ok, %Vix.Vips.Image{ref: #Reference<0.2699864616.1896742930.138892>}}
iex(text_failure_example@4fc7c58d553b)4> Image.Text.text("test")
{:ok, %Vix.Vips.Image{ref: #Reference<0.2699864616.1896742930.138899>}}
iex(text_failure_example@4fc7c58d553b)5> Image.Text.text("test")
{:ok, %Vix.Vips.Image{ref: #Reference<0.2699864616.1896742930.138906>}}
iex(text_failure_example@4fc7c58d553b)6> Image.Text.text("test")
{:ok, %Vix.Vips.Image{ref: #Reference<0.2699864616.1896742930.138913>}}
iex(text_failure_example@4fc7c58d553b)7> Image.Text.text("test")
{:ok, %Vix.Vips.Image{ref: #Reference<0.2699864616.1896742930.138919>}}
iex(text_failure_example@4fc7c58d553b)8> Image.Text.text("test")
{:ok, %Vix.Vips.Image{ref: #Reference<0.2699864616.1896742930.138925>}}
iex(text_failure_example@4fc7c58d553b)9> Image.Text.text("test")
{:ok, %Vix.Vips.Image{ref: #Reference<0.2699864616.1896742930.138931>}}
iex(text_failure_example@4fc7c58d553b)10> Image.Text.text("test")
{:ok, %Vix.Vips.Image{ref: #Reference<0.2699864616.1896742930.138937>}}
iex(text_failure_example@4fc7c58d553b)11> Image.Text.text("test")
{:ok, %Vix.Vips.Image{ref: #Reference<0.2699864616.1896742930.138943>}}
iex(text_failure_example@4fc7c58d553b)12> Image.Text.text("test")
{:ok, %Vix.Vips.Image{ref: #Reference<0.2699864616.1896742930.138949>}}
iex(text_failure_example@4fc7c58d553b)13> Image.Text.text("test")
{:ok, %Vix.Vips.Image{ref: #Reference<0.2699864616.1896742930.138955>}}

I'll upgrade to 0.32.0 and hopefully that error just goes away 🙏

I'm happy to hear that!

I'm still seeing this issue on 0.33.0. I was happy to find I wasn't the only one and interesting to find out it has to do with setting it to black. I've played a little bit and he blackest I can make it without an error is #00000b.

I'm on MacOS 13.1.

@sodapopcan yes, that's a bug for sure. I know the source of it but haven't found a fool-proof avoidance yet that passes all tests.

The reason for the #00000b relates to the tolerance (around #000000) on trimming the background after generating the text image. I'll keep working on this - I know its a pain. Turns out image processing is .. challenging.

Turns out image processing is .. challenging.

Lol, oh yes, I know :) No worries, just saw the issue was closed so I wanted to pass on it was still happening. I think it's ok for my use case to use a slightly darker black (I'm unsure as this is for print) but I'll see. I figure anything out I'll of course let you know.

I believe this is now corrected on main branch. I've added a test for when the text stroke and fill are black to test for correctness. I've also reduced the background threshold when trimming to 0 which should also improve the predictability of the resulting text image.

Let me know if works for your use case? If so, I'll publish a new release.

Thanks so much for looking into this!

I can now get the color as black as #000001 but full black still gives me the error.

Sorry, I responded way too quickly.

It's a bit odd but here's what I've tried:

# works
Image.Text.text("Hello", text_fill_color: :black, text_stroke_color: :black)

# error
Image.Text.text("Hello", text_fill_color: :black, text_stroke_color: "#000000")

# error
Image.Text.text("Hello", text_fill_color: "#000000", text_stroke_color: "#000000")

# error
Image.Text.text("Hello", text_fill_color: :black)

# error
Image.Text.text("Hello", text_fill_color: "#000000")

# works
Image.Text.text("Hello", text_fill_color: "#000001")

I've push another commit that test all of those cases which now pass. Sorry this has taken way longer than it should have. Hopefully done now.

☕️ ☕️ ☕️

Hey, no apologies necessary, I'm sorry I didn't look into it further myself. I really appreciate you and this library—it's making me look really good at work, lol. Reading your code has also been a massive aid in my understanding of VIPS and image processing in general.

Thanks for fixing this! I'll likely be bugging you with a few more PRs/discussions/feedback in the next week or so as I finish up this part of the project. It's going so smoothly thanks to Image/Vix/VIPS. We're a print shop so image processing is an integral piece of our business.

PS, can confirm all those cases work on my end now.

I'll likely be bugging you with a few more PRs/discussions/feedback

Cool, I look forward to that. I'm learning a lot working on this too :-)

In the scholar branch I'm working on color clustering, top-k colours and a few other things to come. That will get me a long way towards finally getting a color library done properly and extracted from image. Feel free to add suggestions to that topic as well.

Interesting, I will take a look. I'm just diving into colour profiles and whatnot this past week. A current problem we have people complaining that the colours in their images look way off from how they look on screen after printing. I'm still pretty in the dark there but have to learn for work so hopefully I'll learn some stuff I can share. Of course, everything appears to be just working so far...

I finally got to see a printed result of my little "image server" the other day. The current running implementation is a Ruby daemon that sends scripts to PhotoShop to assemble the print files, so I was thinking I was going to have all sorts of problems with colour-matching. But without doing anything in that regard, the first test looked perfect! Also, ImageMagick is currently used for product mockups, and it's built with a whole bunch of flags. Using libvips as-is produces great results so ya, this has all been a very good experience so that is to say: I'm not sure how far into colour I'm going to have to dive 😅

That's actually an area I know something about!!!! (I'm a passionate photographer).

Most of these screen-to-print issues come from (in my experience):

  1. Uncalibrated screen (very common)
  2. Screen too bright. Screens are emissive, prints are reflective. With high brightness screens all the vogue, people are editing their photos in an environment that is far too bright. I use an i1 spectrophotometer but your average iPhone user isn't going to do that.
  3. Mismatched color profiles. Can happen, but I suppose most images you get are in sRGB so gamut and profile shouldn't be an issue as often. Photoshop needs to be printed with perceptual rendering too in most cases.
  4. Double profiling. Sometimes this can happen if the printer is set up to use a profile and photoshop is set up to use a profile. Bad things happen (a print shop would never do that so I'm sure that's not the issue).

I'm not a color expert, but I am a practitioner so if you have any questions I might have some idea.

Closing (again!)

I believe mismatched colour profiles is the big one. It may be as simple as converting it to sRBG once they upload (though that may cause other problems, I don't know). We have a customizer on our site which is where the problems lie. We certainly will help our customers figure out mismatched colours but most people are ordering one-off phone cases and it's not viable for us to be working with people to figure out their monitors. Thank you for the offer of help—I may pick you brain when I get into it if that's ok :)