Closed zogbi closed 6 years ago
I don't seem to be able to reproduce your error. 😞
Can you write a minimal test case that reproduces your issues? Please also let me know what versions of libraries your using.
I've just realised that my current alpha was a little out of date, can you try upgrading your SixLabors.Fonts package to version 0.1.0-alpha0003 and see if that fixes it for you.
This is our code:
` var fontFamily = FontCollection.SystemFonts.Find(textOverlay.FontFamily.ToString());
var style = FontStyle.Regular;
if (textOverlay.IsBold)
style = FontStyle.Bold;
if (textOverlay.IsItalic)
style = FontStyle.Italic;
if (textOverlay.IsBold && textOverlay.IsItalic)
style = FontStyle.BoldItalic;
var font = new Font(fontFamily, textOverlay.FontSize, style);
var location = new HalfVector2(textOverlay.X, textOverlay.Y);
var color = new Color(textOverlay.FontColorRed, textOverlay.FontColorGreen, textOverlay.FontColorBlue, textOverlay.FontColorAlpha);
image.DrawText(textOverlay?.Content ?? "", font, color, location.ToVector2());`
This is our packages:
Include="SixLabors.Fonts" Version="0.1.0-ci0050"
`
<PackageReference Include="CoreCompat.System.Drawing" Version="1.0.0-beta006" />
<PackageReference Include="ImageSharp" Version="1.0.0-alpha5-00059" />
<PackageReference Include="ImageSharp.Drawing" Version="1.0.0-alpha5-00053" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="1.1.1" />
<PackageReference Include="Microsoft.NETCore.App" Version="1.1.1" />
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="1.1.2" />
<PackageReference Include="Microsoft.AspNetCore.Routing" Version="1.1.1" />
<PackageReference Include="Microsoft.AspNetCore.Server.IISIntegration" Version="1.1.1" />
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" Version="1.1.1" />
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="1.1.1" />
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="1.1.1" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="1.1.1" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="1.1.1" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="1.1.1" />
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="1.1.1" />
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="1.1.1" />
<PackageReference Include="NLog" Version="5.0.0-beta06" />
**<PackageReference Include="SixLabors.Fonts" Version="0.1.0-ci0050" />**
<PackageReference Include="System.Text.Encoding" Version="4.3.0" />
`
Looks like you updated ImageSharp and SixLabors.Fonts half way through me accidentally breaking the public API there (the break shouldn't effect the null reference but might effect the position of the rendering).
So first can you update all three, ImageSharp, ImageSharp.Drawing and SixLabors.Fonts, to their latest versions for me, sorry about that.
And secondly can you refactor your code sample into a simple, self contained, test case for me? at the moment I can't grab your code and just run it to reproduce the exception. (something I can copy and paste into a console app and causes the error would be wonderful)
Also if you can give me the the details from the exception, stacktrace etc, that would also help me track down the null value.
Sorry to delay answer.
We have updated all three packages before do a new test and the problem still happen.
Follow below our code.
'using ImageSharp; using System.IO; using ImageSharp.Formats; using System.Collections.Generic; using System.Linq; using ImageSharp.Drawing; using SixLabors.Fonts; using ImageSharp.Drawing.Pens; using System; using System.Diagnostics; using System.Globalization; using System.Text;
namespace ImageTest { static class Program { static void Main(string[] args) { ProcessImage("success text");
try
{
ProcessImage("error téxt");
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
private static void AddText(this Image image, string text)
{
var fontFamily = FontCollection.SystemFonts.Find("Arial");
var style = FontStyle.Regular;
var font = new Font(fontFamily, 30, style);
var location = new HalfVector2(20, 20);
var color = new Color(0, 0, 0, 90);
image.DrawText(text, font, color, location.ToVector2());
}
private static void AddBg(this Image image)
{
var size = new ImageSharp.Size(800, 600);
var imageOv = Image.Load($"{Directory.GetCurrentDirectory()}\\bg.jpg");
imageOv.Resize(new ImageSharp.Processing.ResizeOptions()
{
Size = size,
Mode = ImageSharp.Processing.ResizeMode.Crop
});
var location = new HalfVector2(0, 0);
var point = new Point(location.ToVector2());
image.DrawImage(imageOv, 100, size, point);
}
public static void ProcessImage(string text)
{
var config = new Configuration();
config.AddImageFormat(new JpegFormat());
config.AddImageFormat(new PngFormat());
using (var image = new Image(800, 600, config))
{
image.AddBg();
image.AddText(text);
image.Save($"{Directory.GetCurrentDirectory()}\\{text}.jpg");
}
}
}
}'
nope sorry that code works perfectly on my machine... 😞
I'm going to need the stack traces & messages of the exception, (including any inner-exceptions).
On a side note you don't want to be using the HalfVector2
type for locations just use System.Numerics.Vector2
directly.
I tested the code in the azure app and this error happened:
System.NullReferenceException: Object reference not set to an instance of an object. at SixLabors.Fonts.Tables.General.Glyphs.CompositeGlyphLoader.CreateGlyph(GlyphTable table) at SixLabors.Fonts.Tables.General.GlyphTable.GetGlyph(Int32 index) at SixLabors.Fonts.FontInstance.GetGlyph(Char character) at SixLabors.Fonts.FileFontInstance.GetGlyph(Char character) at SixLabors.Fonts.TextLayout.GenerateLayout(String text, FontSpan style) at SixLabors.Fonts.TextRenderer.RenderText(String text, FontSpan style, Vector2 location) at ImageSharp.ImageExtensions.DrawText[TPixel](Image
1 source, String text, Font font, IBrush1 brush, IPen
1 pen, Vector2 location, TextGraphicsOptions options) at ImageSharp.ImageExtensions.DrawText[TPixel](Image1 source, String text, Font font, TPixel color, Vector2 location) at MSE.Business.Image.ImageProccessBusiness.AddText(Image image, OverlayText textOverlay) in D:\Desenvolvimento\MK\mobile-service\MSE\MSE.Business\Image\ImageProccessBusiness.cs:line 60 at MSE.Business.Image.ImageProccessBusiness.ProcessImage(Int32 width, Int32 height, OverlayText[] textOverlays, OverlayImage[] imageOverlays) in D:\Desenvolvimento\MK\mobile-service\MSE\MSE.Business\Image\ImageProccessBusiness.cs:line 113 at MSE.Business.Notifications.NotificationConsultantBusiness.<GenerateSkinAsync>d__10.MoveNext() in D:\Desenvolvimento\MK\mobile-service\MSE\MSE.Business\Notifications\NotificationConsultantBusiness.cs:line 320 --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter
1.GetResult() at MSE.Service.Controllers.NotificationController.1.<Invoke>d__18.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware
1.1.<RequestProcessingAsync>d__2.MoveNext()
That's really strange, I can't see how the code anywhere around there could throw null reference exceptions... Could you please provide the actual font file that the your using... seems there is some differences between the version of Arial I've got on my machine and the one causing you issues.
My code is the same as Zogbi is using. The weirdest part is that on my machine it works but on azurewebapp it does not. I think it should be something with regard to installing windows server that runs on azurewebapp. I stress that the installed version is the server core that has no GUI and support of some windows APIs. I have backends with libs to generate PDFs that do not work in this environment because most libs use GDI + for example.
I have already tried doing the same work with Comic Sans and the same error occurs.
And sorry for my bad English ...
Ok can you try using the local your local version of the font (just copy out of your local fonts directory) and load it into a custom FontCollection
instead of using the the FontCollection.SystemFonts
property.
instead of using
var fontFamily = FontCollection.SystemFonts.Find("Arial");
do
// the next 2 lines should be done in some global location
// and passed as a singleton as loading fonts is expensive.
var collection = new FontCollection();
collection.Install("path/to/copy/of/Arial.ttf");
// now you can use `collection` instead of `FontCollection.SystemFonts`
var fontFamily = collection.Find("Arial");
Personally I would never use copies of fonts that come installed on a server, for exactly these reasons, the fonts used are state that your application depends on so ship that dependency with your app so your not dependent on some OS update breaking you in unexpected ways.
Good night, I may have found the problem. I made a gitclone of your code and everything worked as it should. I updated your lib to version xxxx and tried to execute the following code:
font.GetGlyph('á');
This code fires for the exception:
System.NullReferenceException: Object reference not set to an instance of an object. at SixLabors.Fonts.Tables.General.Glyphs.CompositeGlyphLoader.CreateGlyph(GlyphTable table) at SixLabors.Fonts.Tables.General.GlyphTable.GetGlyph(Int32 index) at SixLabors.Fonts.FontInstance.GetGlyph(Char character) at SixLabors.Fonts.Font.GetGlyph(Char character) at MSE.Business.Image.ImageProccessBusiness.AddText(Image
1 image, OverlayText textOverlay) in D:\Desenvolvimento\MK\mobile-service\MSE\MSE.Business\Image\ImageProccessBusiness.cs:line 71
If it is used:
font.GetGlyph('a')`
Run normally.
I'm going to design the project as a reference instead of installing via nuget for now, because this way it worked normally.
Here is the complete exception when you run image.DrawText ():
System.NullReferenceException: Object reference not set to an instance of an object. at SixLabors.Fonts.Tables.General.Glyphs.CompositeGlyphLoader.CreateGlyph(GlyphTable table) at SixLabors.Fonts.Tables.General.GlyphTable.GetGlyph(Int32 index) at SixLabors.Fonts.FontInstance.GetGlyph(Char character) at SixLabors.Fonts.TextLayout.GenerateLayout(String text, FontSpan style) at SixLabors.Fonts.TextRenderer.RenderText(String text, FontSpan style, Vector2 location) at ImageSharp.ImageExtensions.DrawText[TPixel](Image
1 source, String text, Font font, IBrush1 brush, IPen
1 pen, Vector2 location, TextGraphicsOptions options) at ImageSharp.ImageExtensions.DrawText[TPixel](Image1 source, String text, Font font, TPixel color, Vector2 location, TextGraphicsOptions options) at MSE.Business.Image.ImageProccessBusiness.AddText(Image
1 image, OverlayText textOverlay) in D:\Desenvolvimento\MK\mobile-service\MSE\MSE.Business\Image\ImageProccessBusiness.cs:line 103 at MSE.Business.Image.ImageProccessBusiness.ProcessImage(Int32 width, Int32 height, OverlayText[] textOverlays, OverlayImage[] imageOverlays) in D:\Desenvolvimento\MK\mobile-service\MSE\MSE.Business\Image\ImageProccessBusiness.cs:line 158 at MSE.Business.Notifications.NotificationConsultantBusiness.1.GetResult() at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeActionMethodAsync>d__27.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter.GetResult() at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeNextActionFilterAsync>d__25.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow(ActionExecutedContext context) at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted) at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeNextResourceFilter>d__22.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow(ResourceExecutedContext context) at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted) at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeAsync>d__20.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter.GetResult() at Microsoft.AspNetCore.Builder.RouterMiddleware.<Invoke>d__4.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter.GetResult() at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware
1.
Closing this, as without being given the problematic font file I can't do much to fix this.
I'm experiencing the same problem with German umlauts ('ä' for example). It works fine on my Windows 10 development machine, but on some other machine (Windows 7) I get a similar exception.
I created a minimal test program (with an embedded font) which reproduces the problem. The test program basically just tries to measure the size of a string containing umlauts. You can find the sources of that test program here.
I noticed some problems with character encoding, that's why the program accepts a command line parameter which determines how to handle encoding.
Here is the output of the program on my development machine:
>dotnet LocalizedFontTest.dll none
The output encoding of the console is Unicode (UTF-8)
This tool measures the size of 'Mobilitätsanalyse'
Size of text 'Mobilitätsanalyse' is 132.5078x17.11719
Press Enter to exit...
>dotnet LocalizedFontTest.dll utf8
The output encoding of the console is Unicode (UTF-8)
This tool measures the size of 'Mobilitätsanalyse'
Size of text 'Mobilitätsanalyse' is 132.5078x17.11719
Press Enter to exit...
>dotnet LocalizedFontTest.dll cpep
The output encoding of the console is Unicode (UTF-8)
This tool measures the size of 'Mobilitätsanalyse'
Size of text 'Mobilitätsanalyse' is 132.5078x17.11719
Press Enter to exit...
On the other machine, the output is this:
>dotnet LocalizedFontTest.dll none
The output encoding of the console is Unicode (UTF-8)
This tool measures the size of 'Mobilitätsanalyse'
TextMeasurer.Measure failed with
System.NullReferenceException: Object reference not set to an instance of an obj
ect.
at SixLabors.Fonts.Tables.General.Glyphs.CompositeGlyphLoader.CreateGlyph(Gly
phTable table)
at SixLabors.Fonts.Tables.General.GlyphTable.GetGlyph(Int32 index)
at SixLabors.Fonts.FontInstance.GetGlyph(Char character)
at SixLabors.Fonts.TextLayout.GenerateLayout(String text, RendererOptions opt
ions)
at SixLabors.Fonts.TextMeasurer.TextMeasurerInt.Measure(String text, Renderer
Options options)
at LocalizedFontTest.Program.Main(String[] args) in C:\Robert\CCMCMService\Te
stProjects\LocalizedFontTest\Program.cs:line 37
>dotnet LocalizedFontTest.dll utf8
The output encoding of the console is Unicode (UTF-8)
This tool measures the size of 'Mobilitätsanalyse'
TextMeasurer.Measure failed with
System.NullReferenceException: Object reference not set to an instance of an obj
ect.
at SixLabors.Fonts.Tables.General.Glyphs.CompositeGlyphLoader.CreateGlyph(Gly
phTable table)
at SixLabors.Fonts.Tables.General.GlyphTable.GetGlyph(Int32 index)
at SixLabors.Fonts.FontInstance.GetGlyph(Char character)
at SixLabors.Fonts.TextLayout.GenerateLayout(String text, RendererOptions opt
ions)
at SixLabors.Fonts.TextMeasurer.TextMeasurerInt.Measure(String text, Renderer
Options options)
at LocalizedFontTest.Program.Main(String[] args) in C:\Robert\CCMCMService\Te
stProjects\LocalizedFontTest\Program.cs:line 37
>dotnet LocalizedFontTest.dll cpep
The output encoding of the console is Unicode (UTF-8)
This tool measures the size of 'Mobilitätsanalyse'
TextMeasurer.Measure failed with
System.NullReferenceException: Object reference not set to an instance of an obj
ect.
at SixLabors.Fonts.Tables.General.Glyphs.CompositeGlyphLoader.CreateGlyph(Gly
phTable table)
at SixLabors.Fonts.Tables.General.GlyphTable.GetGlyph(Int32 index)
at SixLabors.Fonts.FontInstance.GetGlyph(Char character)
at SixLabors.Fonts.TextLayout.GenerateLayout(String text, RendererOptions opt
ions)
at SixLabors.Fonts.TextMeasurer.TextMeasurerInt.Measure(String text, Renderer
Options options)
at LocalizedFontTest.Program.Main(String[] args) in C:\Robert\CCMCMService\Te
stProjects\LocalizedFontTest\Program.cs:line 37
Note that on this second machine, with none of the 3 options for encoding, the word 'Mobilitätsanalyse' is printed correctly. I think this is only a problem of the console output. But I'm not sure. It might also give a hint of what goes wrong in the fonts library.
@rhegner 👍 thanks for the reproduction.
I'll try and get a chance to look over it soon... can't think what could cause the issue seeing as your using a local font file.
Yeah I already spent quite some time trying to debug this... The behavior really doesn't make much sense to me...
I solved the problem as follows: 1 - I downloaded the project on github 2 - I removed the nuget package from my application 3 - I added the project as reference 4 - and published my api in debug mode
While I do not have a solution to this problem, I'm using it this way. A test you can do to find the error in the code is to run on your machine in release mode.
I had the same Issue with German umlauts. The Problem occures only in ReleaseMode. The System.NullReferenceException is thrown in the foreach-loop in CompositeGlyphLoader.CreateGlyph
foreach (Composite composite in this.result)
{...
I changed it to foreach (Composite composite in this.result.ToArray()) {... and all works fine, also it doesn't make sense to me
thanks for that ... i'm guessing there must be some bug somewhere in the .net jitter that I must be hitting. I'll see what impacts the just adding the ToArray
will cause but hopefully we should be able to get a fix out soon.
I have another possible fix: This morning i changed Composite from class to struct --> this seems to work too
I tried to reproduce this issue on a Windows 7, Windows 10 and Linux machine but I was unable to reproduce the issue. I really wonder what kind of machine setup we need to reproduce this issue.
I've added a commit to master that that converts the result to an array to see if that sorts it... will sort out a fresh release soon
I updated my project to use SixLabors.ImageSharp.Drawing v1.0.0-beta0001 and we can't reproduce the problem anymore.
awesome 👍
I have an issue when i use words with accents on azure app service.
When i use word with accent, like á é í ó ú ç ã õ, i receive an error: Object reference not set to an instance of an object
i try to use font family like Arial and Comic Sans, and problem still happen.
if i remove all accents, all error desapear.