Blazor Server (.NET 5) - Get the value of croppie's image src to Blazor Server Page - Javascript

802 Views Asked by At

We have created a Blazor Server application with .NET 5 framework, with a feature that uploads images and it crops it which part should be uploaded, what we use is croppie.js, I tried the code below when after the cropping of image then save, what approach I did use is getting the src of image using javascript, that is been called by my method inside of the Blazor Server Page, here's my code.

Javascript:

    function getImgSrc() {
debugger;
var GetValue = document.getElementById('my-img').src;
return GetValue;
}

My Blazor Server-side page codes (Index.razor.cs)

        public async Task SavePhoto()
    {
        string GetSRC = await jSRuntime.InvokeAsync<string>("getImgSrc");

        string path = _hostingEnvironment.WebRootPath + "/images/" + fileName;
        byte[] imageBytes = Convert.FromBase64String(GetSRC);
        File.WriteAllBytes(path, imageBytes);
        return;
    }

Then, when I run the application, crop the image and save it, it causes an error, the only error message show is this.

Error: Connection disconnected with error 'Error: Server returned an error on close: Connection closed with an error.'.

Has anyone tried to use croppie in Blazor Server? have you successfully gotten the image from image tag's src??

I hope someone can help me on this.

Thanks everyone

2

There are 2 best solutions below

0
On

I have solved this by not using code behind of the blazor component page, I used a javascript, json/ajax and webapi for saving the image, then used the code behind for getting the image to show, but I have to force reload the page for this. Our team is currently want to avoid blob on the code behind of the blazor, to make our app to be light weight as possible.

Thank you everyone.

0
On

For those who come after. Documentation cproppie.js https://foliotek.github.io/Croppie/

index.html

<link href="lib/croppie/croppie.min.css" rel="stylesheet" />

<script src="lib/croppie/croppie.min.js"></script>
<script src="js/app.js"></script>

app.js

var resize;
var base64data;

window.Crop = {
    image: function (component) {

        setTimeout(() => {

            var cor = document.getElementById('upload-demo');
            resize = new Croppie(cor, {
                enableExif: true,
                viewport: {
                    width: 150,
                    height: 150,
                    type: 'square'
                },
                boundary: {
                    width: 300,
                    height: 300
                }
            });

            var input = document.getElementById('upload').files[0];
            if (input) {
                var reader = new FileReader();
                reader.onload = function (e) {
                    //document.getElementsByClassName('upload-demo').classList.add('ready');
                    resize.bind({
                        url: e.target.result
                    });
                }
                reader.readAsDataURL(input);
            }
            else {
                alert("Sorry - you're browser doesn't support the FileReader API");
            }
        }, 150);

    },
    responses: function (component) {
        resize.result('blob').then(function (blob) {
            var reader = new FileReader();
            reader.readAsDataURL(blob);
            reader.onloadend = async function () {
                base64data = reader.result;
                var i = document.getElementById('result');
                var img = document.createElement('img');
                img.src = base64data;                
                i.appendChild(img);
                return component.invokeMethodAsync('ResponseMethod',base64data); 
            }
        });
        
    }
};

razor page

@page "/"
@inject IJSRuntime JS
@inject IHttpClientFactory ClientFactory
@using BlazorCroppieExample.Shared
<PageTitle>Index</PageTitle>

<div class="form-group">
    <div class="custom-file">
        <input id="upload" accept="image/*" type="file" class="custom-file-input" @onchange="Upload">            
    </div>
</div>

<div class="upload-demo">
    <div class="upload-msg">Croppie</div>
    <div class="upload-demo-wrap">
        <div id="upload-demo"></div>
    </div>
</div>

<button class="upload-result" @onclick="Up">Abr</button>
<div id="result"></div>
<img id="result-img" src="">


@code {

    FileUpload model { get; set; } = new();    
    HttpClient NoAuthenticationClient;

    async Task Upload()
    {
        await JS.InvokeVoidAsync("Crop.image", DotNetObjectReference.Create(this));
    }

    async Task Up()
    {
        await JS.InvokeVoidAsync("Crop.responses", DotNetObjectReference.Create(this));
    }

    [JSInvokable]
    public async void ResponseMethod(string data)
    {
        model.Avatar = data;
        await UploadServer();
        StateHasChanged();
    }

    async Task UploadServer()
    {
        NoAuthenticationClient = ClientFactory.CreateClient("BlazorCroppieExample.NoAuthenticationClient");
        await NoAuthenticationClient.PostAsJsonAsync<FileUpload>("WeatherForecast", model);
    }

}

FileUpload class

 public class FileUpload
    {
        public string Avatar { get; set; }
    }

Controller

[HttpPost]
public async Task<ActionResult> PostFile(FileUpload model)
{
    try
    {
        string name = Guid.NewGuid().ToString();
        string file = null;
        if (!string.IsNullOrEmpty(model.Avatar))
        {
            ProcessImage(model.Avatar, name);
            file = "Uploads/" + name + ".png";
        }
        return Ok();
    }
    catch
    {
        return Problem();
    }            
}

private string ProcessImage(string croppedImage, string name)
{
    string filePath = String.Empty;

    try
    {
        string base64 = croppedImage;
        byte[] bytes = Convert.FromBase64String(base64.Split(',')[1]);

        filePath = Path.Combine("Uploads/" + name + ".png");

        using (FileStream stream = new FileStream(Path.Combine(_environment.WebRootPath, filePath), FileMode.Create))
        {
            stream.Write(bytes, 0, bytes.Length);
            stream.Flush();
        }
    }
    catch (Exception ex)
    {
        string st = ex.Message;
    }
    return filePath;
}

Working example https://github.com/blakcat76/BlazorCroppieExample