Problem in bitmap to vector image converter

Saeed Pooladzadeh 251 Reputation points
2024-05-27T14:06:14.7366667+00:00

Hi,

I want to make an app that converts a bitmap image to SVG format.

Below you can see my code:



@page "/"
@using Microsoft.JSInterop
@inject IJSRuntime JsRuntime

<h1>Convert Bitmap to Vector</h1>

<input type="file" 
    @oninput="ConvertImage" accept="image/*" />
<br />

@if (!string.IsNullOrEmpty(VectorSvg))
    {
    <h2>Vector Graphic:</h2>
    <div>
        <svg width="200" height="200" xmlns="http://www.w3.org/2000/svg">
            @* Display SVG content *@
            @((MarkupString)VectorSvg)
        </svg>
    </div>
    }


@code{

    private string? VectorSvg;



    private async Task ConvertImage ( InputFileChangeEventArgs e )
        {

        var file = e.GetMultipleFiles().FirstOrDefault();
        if (file != null)

            {
            
            byte[] imageBytes;
            using (var stream = file.OpenReadStream())
                {
                imageBytes = new byte[stream.Length];
                await stream.ReadAsync(imageBytes, 0, (int)stream.Length);
                }


            // Call JavaScript function to convert the image to vector using Potrace
            // VectorSvg = await JSRuntime.InvokeAsync<string>("convertToVector",imageBytes);

            try
                {
                VectorSvg = await JSRuntime.InvokeAsync<string>("convertToVector", imageBytes);
                }
            catch (Exception e)
                {
                Console.WriteLine($"Unexpected error: {e.Message}");
                
                }


            }

        }


    }




And here is js file:


// This section imports the necessary JavaScript interop capabilities for calling the Potrace library.
window.convertToVector = function (imageBytes) {
    return new Promise((resolve, reject) => {
        // Convert image bytes to base64 string
        var base64Image = arrayBufferToBase64(imageBytes);


        // Call Potrace library for vectorization
        potrace({ input: base64Image, format: 'image/svg+xml' }, function (err, svg) {
            if (err) {
                reject(err); // Failed to convert, reject with error
            } else {
                resolve(svg); // Conversion successful, resolve with SVG content
            }

        });
    });
};


function arrayBufferToBase64(buffer) {
    var binary = '';
    var bytes = new Uint8Array(buffer);
    var len = bytes.byteLength;
    for (var i = 0; i < len; i++) {
        binary += String.fromCharCode(bytes[i]);
    }

    return window.btoa(binary); // Encode binary data to base64
}


My errors are:

1.In index page in my input tage I see a red line under ConvertImage. 2. In the ConvertImage function in code section I see redline under imageBytes argument.

  1. When I want to run the code I encounter with this error:

VS_Error

Please guide me.

thanks,

ASP.NET Core
ASP.NET Core
A set of technologies in the .NET Framework for building web applications and XML web services.
4,307 questions
Blazor
Blazor
A free and open-source web framework that enables developers to create web apps using C# and HTML being developed by Microsoft.
1,458 questions
{count} votes

Accepted answer
  1. Ping Ni-MSFT 2,875 Reputation points Microsoft Vendor
    2024-05-29T07:43:21.3333333+00:00

    Hi @Saeed Pooladzadeh,

    CS1503 Argument 2: cannot convert from 'method group' to 'Microsoft.AspNetCore.Components.EventCallback' 10

    You need create the function with ChangeEventArgs when you use @oninput :

    private async Task ConvertImage(ChangeEventArgs e)
    

    But from your code, you need use InputFileChangeEventArgs to get the multiple file, so you need change your code like below:

    <InputFile OnChange="@ConvertImage" accept="image/*" />
    

    CS1503 Argument 2: cannot convert from 'byte[]' to 'object?[]?' 52

    Change to JSRuntime to JsRuntime . It should be JsRuntime which is the instance name(@inject IJSRuntime JsRuntime)

     VectorSvg = await JsRuntime.InvokeAsync<string>("convertToVector", imageBytes);
    

    CS0136 A local or parameter named 'e' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter 54

    You have declared InputFileChangeEventArgs e in this function, so change the name:

    catch (Exception ex)
    {
        Console.WriteLine($"Unexpected error: {ex.Message}");
    }
    

    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".
    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.
    Best regards,
    Rena

    0 comments No comments

1 additional answer

Sort by: Most helpful
  1. Bruce (SqlWork.com) 59,306 Reputation points
    2024-05-27T20:50:09.5033333+00:00

    Jsinterop uses json serialization (object to json string) to pass parameters. Json does not have a binary format. Your code could use base64 to pass the buffer.

    As you are using JavaScript to do the conversion, not sure why you jsinterop a buffer to Blazor than back to JavaScript. The JavaScript could just access file bytes directly.