Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug]: Cropper does not display base64 image sources #5321

Closed
Brutiquzz opened this issue Feb 18, 2024 · 1 comment
Closed

[Bug]: Cropper does not display base64 image sources #5321

Brutiquzz opened this issue Feb 18, 2024 · 1 comment
Assignees
Labels
Type: Bug 🐞 Something isn't working
Milestone

Comments

@Brutiquzz
Copy link

Blazorise Version

1.4.2

What Blazorise provider are you running on?

Bootstrap5

Link to minimal reproduction, or a simple code snippet

@using System.IO

 <Column>
     <FieldLabel>
        <FileEdit Changed="@OnChanged" />
     </FieldLabel>
     <FieldBody>
         <Cropper @ref="cropper" Source="ImageSource" SelectionChanged="@OnSelectionChanged" Style="aspect-ratio: 16 / 9; height: 100%;" />
     </FieldBody>
 </Column>
 <Column>
     <Div Margin="Margin.Is2.FromBottom">
         <Button Color="Color.Primary" Clicked="@GetCroppedImage" Disabled="@cropButtonDisabled">Get Cropped Image</Button>
         <Button Color="Color.Secondary" Clicked="@ResetSelection" Disabled="@cropButtonDisabled">Reset Selection</Button>
     </Div>
     <Image Source="@ImageSource" Border="Border.Is1" />
 </Column>

@code {

    public string ImageSource { get; set; } = string.Empty;
    private Cropper cropper = new();
    private string result = string.Empty;
    private bool cropButtonDisabled = true;

    async Task OnChanged(FileChangedEventArgs e)
    {
        byte[] bytes;
        using (MemoryStream result = new MemoryStream())
        {
            await e.Files.First().OpenReadStream(long.MaxValue).CopyToAsync(result);
            bytes = result.ToArray();
        }
        ImageSource = $"data:{e.Files.First().Type};base64, {Convert.ToBase64String(bytes)}";

        StateHasChanged();
    }

    private Task OnSelectionChanged(CropperSelectionChangedEventArgs eventArgs)
    {
        if (eventArgs.Width != 0)
        {
            cropButtonDisabled = false;

            return InvokeAsync(StateHasChanged);
        }

        return Task.CompletedTask;
    }

    private async Task GetCroppedImage()
    {
        result = await cropper.CropAsBase64ImageAsync(new() { Width = 250, Height = 250 });
    }

    private async Task ResetSelection()
    {
        cropButtonDisabled = true;

        await cropper.ResetSelection();
    }
}

Steps to reproduce

Upload an image using the FileEdit component

What is expected?

I expect the Cropper component to display the image I upload through the FileEdit component.

What is actually happening?

Nothing is happening to the cropper component. But the Image component also present in the code updates correctly and displays the uploaded image.

What browsers are you seeing the problem on?

Chrome, Microsoft Edge

Any additional comments?

It is not clear from the documentation if the Source of the cropper allows for base64 inputs or not.

If i use a static file from wwwroot then the cropper works.

@Brutiquzz Brutiquzz added the Type: Bug 🐞 Something isn't working label Feb 18, 2024
@stsrki stsrki self-assigned this Feb 18, 2024
@stsrki stsrki added this to the 1.4 support milestone Feb 18, 2024
@stsrki stsrki added this to Support Aug 3, 2024
@stsrki stsrki moved this to 🔙 Backlog in Support Aug 3, 2024
@stsrki stsrki modified the milestones: 1.4 support, 1.6 support Oct 24, 2024
@tesar-tech
Copy link
Collaborator

Yes, base64 images are supported. The docs will be updated accordingly.

This is not a bug. Your code just needs few adjustments.

  • Source="ImageSource" has to have the at sign, otherwise it's perceived as a string
  • the <Image Source="@ImageSource" Border="Border.Is1" /> has to have the result <Image Source="@result" Border="Border.Is1" /> . That's the reason why it showed the full image.
  • using (MemoryStream result = new MemoryStream()) should not be named result as you already have one.
  • the string empty check @if (!string.IsNullOrEmpty(ImageSource)) is there as a workaround for [Bug]: ImageCropper doesn't like Source change #5809

full working code:

@using System.IO
@using Blazorise.Cropper
@rendermode @(new InteractiveServerRenderMode(false))

<Row>

    <Column>
        <FieldLabel>
            <FileEdit Changed="@OnChanged" />
        </FieldLabel>
        <FieldBody>
            @if (!string.IsNullOrEmpty(ImageSource))
            {
            <Cropper @ref="cropper" Source="@ImageSource" SelectionChanged="@OnSelectionChanged" Style="aspect-ratio: 16 / 9; height: 100%;"/>
            }
        </FieldBody>
    </Column>
    <Column>
        <Div Margin="Margin.Is2.FromBottom">
            <Button Color="Color.Primary" Clicked="@GetCroppedImage" Disabled="@cropButtonDisabled">Get Cropped Image</Button>
            <Button Color="Color.Secondary" Clicked="@ResetSelection" Disabled="@cropButtonDisabled">Reset Selection</Button>
        </Div>
        <Image Source="@result" Border="Border.Is1" />
    </Column>
</Row>

@code {

    public string ImageSource { get; set; } = string.Empty;
    private Cropper cropper = new();
    private string result = string.Empty;
    private bool cropButtonDisabled = true;

    async Task OnChanged(FileChangedEventArgs e)
    {
        byte[] bytes;
        using (MemoryStream ms = new MemoryStream())
        {
            await e.Files.First().OpenReadStream(long.MaxValue).CopyToAsync(ms);
            bytes = ms.ToArray();
        }
        ImageSource = $"data:{e.Files.First().Type};base64, {Convert.ToBase64String(bytes)}";

        StateHasChanged();
    }

    private Task OnSelectionChanged(CropperSelectionChangedEventArgs eventArgs)
    {
        if (eventArgs.Width != 0)
        {
            cropButtonDisabled = false;

            return InvokeAsync(StateHasChanged);
        }

        return Task.CompletedTask;
    }

    private async Task GetCroppedImage()
    {
        result = await cropper.CropAsBase64ImageAsync(new() { Width = 250, Height = 250 });
    }

    private async Task ResetSelection()
    {
        cropButtonDisabled = true;

        await cropper.ResetSelection();
    }
}

Also don't forget to increase the singalR message size to make it work

builder.Services.AddSignalR(o =>
{
    o.MaximumReceiveMessageSize =  1024 * 1024 * 100;
});

@github-project-automation github-project-automation bot moved this from 🔙 Backlog to ✔ Done in Support Oct 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Type: Bug 🐞 Something isn't working
Projects
Status: ✔ Done
Development

No branches or pull requests

3 participants