ststeiger / PdfSharpCore

Port of the PdfSharp library to .NET Core - largely removed GDI+ (only missing GetFontData - which can be replaced with freetype2)
Other
1.08k stars 237 forks source link

Dependency issue with new version of the ImageSharp #426

Open dejanmauer opened 9 months ago

dejanmauer commented 9 months ago

Let say, I would like to load image (png) from file: XImage image = XImage.FromFile("d:\\temp\\qrcode.png");

In case I have reference in my project to ImageSharp > 2.1.6 I get this error:

System.MissingMethodException: 'Method not found: 'SixLabors.ImageSharp.Image`1<!!0> SixLabors.ImageSharp.Image.LoadPixelData(Byte[], Int32, Int32)'.'

Can this be fixed to keep compatibiliry with new versions of ImageSharp (3.X)?

TonyValenti commented 9 months ago

@dejanmauer - lots of folks are running into this issue. I am really hopeful that @ststeiger will enable us to use the latest version of ImageSharp easily.

I've created this branch: https://github.com/TonyValenti/PdfSharpCore

That enables the latest version of ImageSharp for modern .NET versions and uses the older version for legacy .NET versions.

Here's to hoping @ststeiger incorporates it!

svenso commented 8 months ago

There is now a security issue on latest working version of image sharp (2.1.6): https://github.com/advisories/GHSA-65x7-c272-7g7r

Edit: In the mean time, there is a fixed 2.1.7 version available from ImageSharp: https://github.com/SixLabors/ImageSharp/releases/tag/v2.1.7

johnwc commented 8 months ago

@ststeiger Can you please comment on all these requests on updating for ImageSharp. This is becoming an issue.

TonyValenti commented 8 months ago

Later today I'll be submitting a PR that contains everything necessary to resolve this security issue.

johnwc commented 8 months ago

Will it include being able to use v3 of ImageSharp. And the bigger question, will @ststeiger respond and approve the PR.

TonyValenti commented 8 months ago

Yes. V3 for modern .NET and V2 for framework.

We'll have to wait and see if the maintainer of this package accepts it.

TonyValenti commented 8 months ago

Hi @ststeiger - I just created this PR: https://github.com/ststeiger/PdfSharpCore/compare/master...TonyValenti:PdfSharpCore:master?expand=1

Which upgrades various packages, including ImageSharp, to their latest stable, secure versions.

TonyValenti commented 8 months ago

@johnwc - my PR is here if you want to take a look.

johnwc commented 8 months ago

What are the main differences between the two versions of ImageSharpImageSource? The two look almost exactly the same, minus a few method call differences. If that is the case, wouldn't it be better to just make the compile time directives within the few minor differences, rather than duplicate the code for each? I think it would be easier to maintain that way.

TonyValenti commented 8 months ago

@johnwc - Here is a screen shot showing the compare: image

In my experience, when you're dealing with subtle variances like this, you can easily get yourself in trouble by having a single file where you #if things in and out. It is much safer and easier to maintain to branch the file.

johnwc commented 8 months ago

It would be better to maintain one file with a few compile time directives, than two files with almost same code. Think of someone else coming in and only changing one file for a security flaw. If it was in the same file, it would be seen and updated at the same time. Also, visual studio makes it very clear on what directive is currently being worked on and debugged with its coloring of the enabled directive. In my 25 years of development, I have never come across an issue of compile time directives being in a file in relation to this version vs that version compiling. The directives make it very clear what is going on.

TonyValenti commented 8 months ago

That's not a big deal to me either way as long as we can get the maintainer to merge and publish an update.

Thomas-HG commented 8 months ago

Is there any news on this subject ? We are using this great library but this issue starts to be a big pain on our side :(

Thanks !

vebaspect commented 8 months ago

Bump. :)

mtarlac commented 7 months ago

same problem here ;(

tossnet commented 7 months ago

421

balkarov commented 7 months ago

+1

robbaman commented 6 months ago

It turns out it's actually pretty easy to work around this by providing a new, ImageSharp 2/3 compatible ImageSource to the ImageSource.ImageSourceImpl static function.

Just create the class:

public class ImageSharp3CompatibleImageSource<TPixel> : ImageSource where TPixel : unmanaged, IPixel<TPixel> {
    public static IImageSource FromImageSharpImage(
        Image<TPixel> image,
        IImageFormat imgFormat,
        int? quality = 75) =>
        new ImageSharpImageSourceImpl<TPixel>("*" + Guid.NewGuid().ToString("B"), image, quality ?? 75, imgFormat is PngFormat);

    protected override IImageSource FromBinaryImpl(
        string name,
        Func<byte[]> imageSource,
        int? quality = 75) {
        Image<TPixel> image = Image.Load<TPixel>(imageSource());
        return new ImageSharpImageSourceImpl<TPixel>(name, image, quality ?? 75, image.Metadata.DecodedImageFormat is PngFormat);
    }

    protected override IImageSource FromFileImpl(string path, int? quality = 75) {
        Image<TPixel> image = Image.Load<TPixel>(path);
        return new ImageSharpImageSourceImpl<TPixel>(path, image, quality ?? 75, image.Metadata.DecodedImageFormat is PngFormat);
    }

    protected override IImageSource FromStreamImpl(
        string name,
        Func<Stream> imageStream,
        int? quality = 75) {
        using (Stream stream = imageStream()) {
            Image<TPixel> image = Image.Load<TPixel>(stream);
            return new ImageSharpImageSourceImpl<TPixel>(name, image, quality ?? 75, image.Metadata.DecodedImageFormat is PngFormat);
        }
    }

    private class ImageSharpImageSourceImpl<TPixel2>(
        string name,
        Image<TPixel2> image,
        int quality,
        bool isTransparent)
        : IImageSource
        where TPixel2 : unmanaged, IPixel<TPixel2> {
        private Image<TPixel2> Image { get; } = image;

        public int Width => Image.Width;

        public int Height => Image.Height;

        public string Name { get; } = name;

        public bool Transparent { get; internal set; } = isTransparent;

        public void SaveAsJpeg(MemoryStream ms) =>
            Image.SaveAsJpeg(ms, new JpegEncoder() {
                Quality = quality
            });

        public void SaveAsPdfBitmap(MemoryStream ms) {
            BmpEncoder encoder = new BmpEncoder() {
                BitsPerPixel = BmpBitsPerPixel.Pixel32
            };
            Image.Save(ms, encoder);
        }
    }
}

And provide it to the static property at application startup (in the Program.cs for instance):

ImageSource.ImageSourceImpl = new ImageSharp3CompatibleImageSource<Rgba32>();
johnwc commented 3 months ago

Did anyone else notice that someone just merged an update for dependencies, but did not include any dependency updates for ImageSharp?

TonyValenti commented 3 months ago

It did not go unnoticed.

Get Outlook for iOShttps://aka.ms/o0ukef


From: John Carew @.> Sent: Sunday, July 28, 2024 2:42:33 PM To: ststeiger/PdfSharpCore @.> Cc: Tony Valenti @.>; Comment @.> Subject: Re: [ststeiger/PdfSharpCore] Dependency issue with new version of the ImageSharp (Issue #426)

Did anyone else notice that someone just merged an update for dependencies, but did not include any dependency updates for ImageSharp?

— Reply to this email directly, view it on GitHubhttps://github.com/ststeiger/PdfSharpCore/issues/426#issuecomment-2254623895, or unsubscribehttps://github.com/notifications/unsubscribe-auth/ADH2UVVACONF7MYR7PPYVJ3ZOVCSTAVCNFSM6AAAAABDVVUSK2VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDENJUGYZDGOBZGU. You are receiving this because you commented.Message ID: @.***>

robbaman commented 3 months ago

Did anyone else notice that someone just merged an update for dependencies, but did not include any dependency updates for ImageSharp?

I assumed it had to do with the new licensing model for ImageSharp and thus wasn't expecting an update... ever.

johnwc commented 3 months ago

@robbaman @ststeiger @TonyValenti ImageSharp supposedly already gave the green light to this project for using it under the new license without issue.

TonyValenti commented 3 months ago

Yes they did but I believe that does not matter to @ststeiger

johnwc commented 3 months ago

Yes they did but I believe that does not matter to @ststeiger

Can you point us to where they did?

TonyValenti commented 3 months ago

https://github.com/ststeiger/PdfSharpCore/issues/399#issuecomment-1903171059

IngoManthey commented 2 months ago

@robbaman That works great. Unfortunately I have to insert a background image. Is there a way to use your code here?

var background = XImage.FromStream(() => File.OpenRead(Invoice.BackgroundImage));
for (var i = 1; i <= pages; ++i)
{
    var pageInfo = renderer.DocumentRenderer.FormattedDocument.GetPageInfo(i);

    var page = renderer.PdfDocument.AddPage();
    var gfx = XGraphics.FromPdfPage(page, XPageDirection.Downwards);
    gfx.DrawImage(background, 0, 0, pageInfo.Width, pageInfo.Height);
    renderer.DocumentRenderer.RenderPage(gfx, i);
}
robbaman commented 2 months ago

Hi @IngoManthey

Yes it should. The code I mentioned sets a delegate in a static property. This delegate is used by the XImage.FromStream call on the first line of your code sample.

IngoManthey commented 2 months ago

Hallo@IngoManthey

Ja, das sollte es. Der von mir erwähnte Code setzt einen Delegaten in einer statischen Eigenschaft. Dieser Delegate wird vom XImage.FromStreamAufruf in der ersten Zeile Ihres Codebeispiels verwendet.

Yes it was my mistake, now everything works. Thanks for the answer