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,559 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,579 questions
{count} votes

Accepted answer
  1. Ping Ni-MSFT 4,335 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) 65,231 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.


Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.