elringus / bootsharp

Compile C# solution into single-file ES module with auto-generated JavaScript bindings and type definitions
https://bootsharp.com
MIT License
667 stars 36 forks source link

Error whili wrapping MozJpegSharp #12

Closed bojankostic81 closed 2 years ago

bojankostic81 commented 2 years ago

Hi, thanks for this great project! I am trying to implement MozJpegSharp image compression based on the HelloWorld example from the ReadMe you provided, and I'm getting an error. Here are the relevant files:

using System;
using DotNetJS;
using Microsoft.JSInterop;
using MozJpegSharp;

namespace ImageCompression;

public partial class Program
{
    // Entry point is invoked by the JavaScript runtime on boot.
    public static void Main()
    {
        var hostName = GetHostName();
        Console.WriteLine($"Hello {hostName}, DotNet here!");
    }

    [JSInvokable]
    public static string CompressBase64(string base64, int quality)
    {
        var bytes = Helpers.Base64ToByteArray(base64);
        var result = MozJpeg.Recompress(bytes.AsSpan(), quality, TJSubsamplingOption.Chrominance420, TJFlags.None);
        return Helpers.ByteArrayToBase64(result);
    }
}

ImageCommpression.csproj


<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">

    <PropertyGroup>
        <TargetFramework>net6.0</TargetFramework>
        <EmitSourceMap>true</EmitSourceMap>
        <EmitTypes>true</EmitTypes>
    </PropertyGroup>

    <ItemGroup>
        <PackageReference Include="DotNetJS" Version="0.3.12" />
        <PackageReference Include="MozJpegSharp" Version="2.1.12" />
        <PackageReference Include="MozJpegSharp.GdiPlus" Version="2.1.12" />
    </ItemGroup>

</Project>

JS function

<script src="bin/dotnet.js"></script>

<script>
    dotnet.ImageCompression.GetHostName = () => "Browser";

    window.onload = async function () {

        await dotnet.boot();
                var data = "<SOME BASE64 IMAGE>";
                const compressed = dotnet.ImageCompression.CompressBase64(data, 85);
        console.log(`Image: , ${compressed}!`);
    };
</script>

I ran dotnet publish to create the dotnet.js file and I am able to import the module, but I receive an error in console:

Uncaught (in promise) Error: System.DllNotFoundException: turbojpeg

When I run same program as a console application everything is working fine. Do you have any ideas what might be a problem?

elringus commented 2 years ago

Make sure you're explicitly using something from that DLL, otherwise it'll be trimmed. https://devblogs.microsoft.com/dotnet/app-trimming-in-net-5

bojankostic81 commented 2 years ago

I am calling the method MozJpeg.Recompress(inBytes.AsSpan(), quality, subsampling, flags) from MozJpegSharp, which is referenced as NuGet package in my project.

I have tried to add assembly-trimming, like:

<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">
    <PropertyGroup>
        <TargetFramework>net6.0</TargetFramework>
        <EmitSourceMap>true</EmitSourceMap>
        <EmitTypes>true</EmitTypes>
        <PublishTrimmed>true</PublishTrimmed>
        <TrimMode>CopyUsed</TrimMode>
    </PropertyGroup>

    <ItemGroup>
        <PackageReference Include="DotNetJS" Version="0.3.12" />
        <PackageReference Include="MozJpegSharp" Version="2.1.12" />
    </ItemGroup>
</Project>

but then I get the following error:

Uncaught (in promise) Error: System.TypeLoadException: Could not resolve type with token 0100001e from typeref (expected class 'System.Runtime.Serialization.ISerializable' in assembly 'System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e')

Any ideas what might be a problem and how to resolve it?

elringus commented 2 years ago

Something in that third party lib is probably trying to access System.Runtime.Serialization.ISerializable via reflection, while trimmer can't track that kind of dependencies. Try preserving the type via linker: https://docs.microsoft.com/en-us/aspnet/core/blazor/host-and-deploy/configure-linker

github-actions[bot] commented 2 years ago

This issue is stale because it has been open 14 days with no activity. It will be automatically closed in 7 days.