Crop image

Here are examples of basic usage of the getting canvas drawn the cropped image.

Simple Usage

With the GetCroppedCanvasDataURLAsync method you can get canvas drawn the cropped image in URL format.

GetCroppedCanvasDataURLAsync method have following arguments:

GetCroppedCanvasOptions (required) - used to get a cropped canvas;

type (not required) - string indicating the image format. The default type is image/png; this image format will be also used if the specified type is not supported;

number (not required) - number between 0 and 1 indicating the image quality to be used when creating images using file formats that support lossy compression (such as image/jpeg or image/webp). Different browsers have different image encoder compression, usually it is 92 or 80 percent of the full image quality. The default value is 1 with maximum image quality.

CancellationToken (not required) - used to propagate notifications that the operation should be canceled.


Note: If you intend to get a JPEG image from the output canvas, you should set the fillColor option first, if not, the transparent part in the JPEG image will become black by default.
This method blocks the UI thread. Instead, use GetCroppedCanvasDataInBackgroundAsync to work in the background.

Get cropped image
@using Cropper.Blazor.Extensions;
@using Cropper.Blazor.Models;

<div class="img-container">
    <CropperComponent Class="big-img" Src="images/budir-church-bu-akirkja-iceland.jpg" @ref="cropperComponent" Options="new Blazor.Models.Options()" />
</div>

<div class="button" @onclick="GetCroppedCanvasDataURLAsync">
    Get cropped image
</div>

<img class="cropped-img-container" src="@croppedCanvasDataURL" />

@* Make sure the size of the image fits perfectly into the container *@
<style>
    .big-img {
        max-height: 400px;

        /* This rule is very important, please don't ignore this */
        max-width: 100%;
    }

    .img-container {
        max-height: 400px;
        width: 100%;
    }

    /* Means that the cropped image will take up 100% of the width of its containing element */
    .cropped-img-container {
        width: 100%;
    }

    /* These styles are just needed for a nice button and don't related with cropper component */
    .button {
        display: inline-block;
        padding: 10px 20px;
        background-color: #007bff;
        color: #fff;
        border: none;
        border-radius: 5px;
        text-align: center;
        text-decoration: none;
        font-size: 16px;
        cursor: pointer;
    }
</style>
@code {
    private CropperComponent? cropperComponent = null!;
    private string croppedCanvasDataURL;

    public async Task GetCroppedCanvasDataURLAsync()
    {
        GetCroppedCanvasOptions getCroppedCanvasOptions = new GetCroppedCanvasOptions
        {
            MaxHeight = 4096,
            MaxWidth = 4096,
            ImageSmoothingQuality = ImageSmoothingQuality.High.ToEnumString()
        };

        croppedCanvasDataURL = await cropperComponent!.GetCroppedCanvasDataURLAsync(getCroppedCanvasOptions);
    }
}
Advanced Usage

With the GetCroppedCanvasAsync method you can get a canvas drawn from the cropped image (lossy compression). If it is not cropped, then returns a canvas drawn the whole image.

GetCroppedCanvasAsync method have following argument:

GetCroppedCanvasOptions (required) - used to get a cropped canvas;

CancellationToken (not required) - used to propagate notifications that the operation should be canceled.

Note: If you intend to get a JPEG image from the output canvas, you should set the fillColor option first, if not, the transparent part in the JPEG image will become black by default.

This GetCroppedCanvasAsync method returns CroppedCanvas. Use JSRuntimeObjectRef in the CroppedCanvas which represents a reference to a JavaScript cropped canvas object for get a Data URL via HTMLCanvasElement.toDataURL:

CroppedCanvas.JSRuntimeObjectRef.InvokeAsync<string>("toDataURL", type, encoderOptions);

Note: Don't use InvokeAsync<string>("toDataURL") and InvokeAsync<string>("toDataURL", type) methods due to image quality was little lost through default value encoderOptions. In addition, different browsers have different image encoder compression, usually it is 92 or 80 percent of the full image quality.
This method blocks the UI thread. Instead, use GetCroppedCanvasInBackgroundAsync to work in the background. See related usages for round or polygon cropping.

Get cropped image
@using Cropper.Blazor.Extensions;
@using Cropper.Blazor.Models;

<div class="img-container">
    <CropperComponent Class="big-img" Src="images/budir-church-bu-akirkja-iceland.jpg" @ref="cropperComponent" Options="new Blazor.Models.Options()" />
</div>

<div class="button" @onclick="GetCroppedCanvasAsync">
    Get cropped image
</div>

<img class="cropped-img-container" src="@croppedCanvasDataURL" />

@* Make sure the size of the image fits perfectly into the container *@
<style>
    .big-img {
        max-height: 400px;
        /* This rule is very important, please don't ignore this */
        max-width: 100%;
    }

    .img-container {
        max-height: 400px;
        width: 100%;
    }

    /* Means that the cropped image will take up 100% of the width of its containing element */
    .cropped-img-container {
        width: 100%;
    }

    /* These styles are just needed for a nice button and don't related with cropper component */
    .button {
        display: inline-block;
        padding: 10px 20px;
        background-color: #007bff;
        color: #fff;
        border: none;
        border-radius: 5px;
        text-align: center;
        text-decoration: none;
        font-size: 16px;
        cursor: pointer;
    }
</style>
@code {
    private CropperComponent? cropperComponent = null!;
    private string croppedCanvasDataURL;

    public async Task GetCroppedCanvasAsync()
    {
        GetCroppedCanvasOptions getCroppedCanvasOptions = new GetCroppedCanvasOptions
        {
            MaxHeight = 4096,
            MaxWidth = 4096,
            ImageSmoothingQuality = ImageSmoothingQuality.High.ToEnumString()
        };

        // Get a reference to a JavaScript cropped canvas object.
        CroppedCanvas croppedCanvas = await cropperComponent!.GetCroppedCanvasAsync(getCroppedCanvasOptions);
        // Invoke toDataURL JavaScript function from the canvas object.
        croppedCanvasDataURL = await croppedCanvas!.JSRuntimeObjectRef.InvokeAsync<string>("toDataURL", "image/png", 1);
    }
}
Crop a round image
Get cropped image
@using Cropper.Blazor.Extensions;
@using Cropper.Blazor.Models;

<div class="img-container cropper-face-circle">
    <CropperComponent Class="big-img" Src="images/lone-tree.jpg" @ref="cropperComponent" Options="new Blazor.Models.Options()" />
</div>

<div class="button" @onclick="GetCroppedCanvasAsync">
    Get cropped image
</div>

<img class="cropped-img-container" src="@croppedCanvasDataURL" />

@* Make sure the size of the image fits perfectly into the container *@
<style>
    .cropper-face {
        opacity: 25%;
    }

    .img-container.cropper-face-circle .cropper-container .cropper-crop-box .cropper-face {
        border-radius: 50%;
    }

    .big-img {
        max-height: 400px;
        /* This rule is very important, please don't ignore this */
        max-width: 100%;
    }

    .img-container {
        max-height: 400px;
        width: 100%;
    }

    /* Means that the cropped image will take up 100% of the width of its containing element */
    .cropped-img-container {
        width: 100%;
    }

    /* These styles are just needed for a nice button and don't related with cropper component */
    .button {
        display: inline-block;
        padding: 10px 20px;
        background-color: #007bff;
        color: #fff;
        border: none;
        border-radius: 5px;
        text-align: center;
        text-decoration: none;
        font-size: 16px;
        cursor: pointer;
    }
</style>
@code {
    [Inject] private IJSRuntime? JSRuntime { get; set; }

    private CropperComponent? cropperComponent = null!;
    private string croppedCanvasDataURL;

    public async Task GetCroppedCanvasAsync()
    {
        GetCroppedCanvasOptions getCroppedCanvasOptions = new GetCroppedCanvasOptions
        {
            MaxHeight = 4096,
            MaxWidth = 4096,
            ImageSmoothingQuality = ImageSmoothingQuality.High.ToEnumString()
        };

        // Get a reference to a JavaScript cropped canvas object.
        CroppedCanvas croppedCanvas = await cropperComponent!.GetCroppedCanvasAsync(getCroppedCanvasOptions);
        // Invoke toDataURL JavaScript function from the canvas object.
        croppedCanvasDataURL = await JSRuntime!.InvokeAsync<string>("window.getEllipseImage", croppedCanvas!.JSRuntimeObjectRef);
    }
}
Crop a polygon image
Get cropped image
@using Cropper.Blazor.Extensions;
@using Cropper.Blazor.Models;

<div class="img-container cropper-face-pentagon">
    <CropperComponent Class="big-img" Src="images/Mushrooms.jpg" @ref="cropperComponent" Options="new Blazor.Models.Options()" />
</div>

<div class="button" @onclick="GetCroppedCanvasAsync">
    Get cropped image
</div>

<img class="cropped-img-container" src="@croppedCanvasDataURL" />

@* Make sure the size of the image fits perfectly into the container *@
<style>
    .cropper-face {
        opacity: 25%;
    }

    .img-container.cropper-face-pentagon .cropper-container .cropper-crop-box .cropper-face {
        clip-path: polygon(50% 0%, 100% 38%, 82% 100%, 18% 100%, 0% 38%);
    }

    .big-img {
        max-height: 400px;
        /* This rule is very important, please don't ignore this */
        max-width: 100%;
    }

    .img-container {
        max-height: 400px;
        width: 100%;
    }

    /* Means that the cropped image will take up 100% of the width of its containing element */
    .cropped-img-container {
        width: 100%;
    }

    /* These styles are just needed for a nice button and don't related with cropper component */
    .button {
        display: inline-block;
        padding: 10px 20px;
        background-color: #007bff;
        color: #fff;
        border: none;
        border-radius: 5px;
        text-align: center;
        text-decoration: none;
        font-size: 16px;
        cursor: pointer;
    }
</style>
@code {
    [Inject] private IJSRuntime? JSRuntime { get; set; }

    private CropperComponent? cropperComponent = null!;
    private string croppedCanvasDataURL;

    public async Task GetCroppedCanvasAsync()
    {
        GetCroppedCanvasOptions getCroppedCanvasOptions = new GetCroppedCanvasOptions
        {
            MaxHeight = 4096,
            MaxWidth = 4096,
            ImageSmoothingQuality = ImageSmoothingQuality.High.ToEnumString()
        };

        // Get a reference to a JavaScript cropped canvas object.
        CroppedCanvas croppedCanvas = await cropperComponent!.GetCroppedCanvasAsync(getCroppedCanvasOptions);
        // Invoke toDataURL JavaScript function from the canvas object.
        croppedCanvasDataURL = await JSRuntime!.InvokeAsync<string>(
            "window.getPolygonImage",
            croppedCanvas!.JSRuntimeObjectRef,
            // Defines a polygon using an SVG fill rule and a set of vertices previously defined in the following format styles:
            // .img-container.cropper-face-pentagon.cropper-container.cropper-crop-box.cropper-face {
            //     clip-path: polygon(50% 0%, 100% 38%, 82% 100%, 18% 100%, 0% 38%);
            // }
            // In our case, we need to pass the same data, but without the percent sign (%)
            new int[] { 50, 0, 100, 38, 82, 100, 18, 100, 0, 38 });
    }
}
Crop in Background

With the GetCroppedCanvasDataInBackgroundAsync method you can get a canvas drawn from the cropped image (lossy compression). If it is not cropped, then returns a canvas drawn the whole image.

GetCroppedCanvasDataInBackgroundAsync method have following argument:

GetCroppedCanvasOptions (required) - used to get a cropped canvas;

type (not required) - string indicating the image format. The default type is image/png; this image format will be also used if the specified type is not supported;

number (not required) - number between 0 and 1 indicating the image quality to be used when creating images using file formats that support lossy compression (such as image/jpeg or image/webp). Different browsers have different image encoder compression, usually it is 92 or 80 percent of the full image quality. The default value is 1 with maximum image quality.

maximumReceiveChunkSize (not required) - the maximum size of each image chunk to receive, in bytes. For example, 65536 equals 64 KB. If specified, incoming image data will be split into chunks of this size during transmission. If null, the chunk size will be handled automatically based on the stream's native chunking behavior. This helps control memory usage and ensures compatibility with interop limits.

CancellationToken (not required) - used to propagate notifications that the operation should be canceled.

Note: If you intend to get a JPEG image from the output canvas, you should set the fillColor option first, if not, the transparent part in the JPEG image will become black by default.

This GetCroppedCanvasDataInBackgroundAsync method returns ImageReceiver. Use GetImageChunkStreamAsync method in the ImageReceiver for reads the image chunks into a memory stream or to throw an ImageProcessingException when error occurs during image processin.
Note: Note: This is available with the release of version 1.4.1 of the Cropper.Blazor NuGet package.

Get cropped image in background
@using Cropper.Blazor.Extensions;
@using Cropper.Blazor.Models;
@using Cropper.Blazor.Exceptions;

<div class="img-container">
    <CropperComponent Class="big-img" Src="images/budir-church-bu-akirkja-iceland.jpg" @ref="cropperComponent" Options="new Blazor.Models.Options()" />
</div>

<div class="button" @onclick="GetCroppedCanvasDataInBackgroundAsync">
    Get cropped image in background
</div>

<img class="cropped-img-container" src="@croppedCanvasDataURL" />

@* Make sure the size of the image fits perfectly into the container *@
<style>
    .big-img {
        max-height: 400px;
        /* This rule is very important, please don't ignore this */
        max-width: 100%;
    }

    .img-container {
        max-height: 400px;
        width: 100%;
    }

    /* Means that the cropped image will take up 100% of the width of its containing element */
    .cropped-img-container {
        width: 100%;
    }

    /* These styles are just needed for a nice button and don't related with cropper component */
    .button {
        display: inline-block;
        padding: 10px 20px;
        background-color: #007bff;
        color: #fff;
        border: none;
        border-radius: 5px;
        text-align: center;
        text-decoration: none;
        font-size: 16px;
        cursor: pointer;
    }
</style>
@code {
    private CropperComponent? cropperComponent = null!;
    private string croppedCanvasDataURL;


    public async Task GetCroppedCanvasDataInBackgroundAsync()
    {
        // Define options for the cropped canvas, including size and image quality
        GetCroppedCanvasOptions getCroppedCanvasOptions = new GetCroppedCanvasOptions
        {
            MaxHeight = 4096,
            MaxWidth = 4096,
            ImageSmoothingQuality = ImageSmoothingQuality.High.ToEnumString()
        };

        // Call the cropper component to get the cropped canvas image
        ImageReceiver imageReceiver = await cropperComponent!.GetCroppedCanvasDataInBackgroundAsync(getCroppedCanvasOptions);

        try
        {
            // Retrieve the image stream from the receiver
            using MemoryStream croppedCanvasDataStream = await imageReceiver.GetImageChunkStreamAsync();

            // Convert the stream to a byte array
            byte[] croppedCanvasData = croppedCanvasDataStream.ToArray();

            // Encode the image data as a base64 data URL for use in HTML
            croppedCanvasDataURL = "data:image/png;base64," + Convert.ToBase64String(croppedCanvasData);
        }
        catch (ImageProcessingException ex)
        {
            // Handle any image processing errors (currently empty - consider logging or rethrowing)
        }
    }
}
Crop a round image in Background

Note: Note: This is available with the release of version 1.4.1 of the Cropper.Blazor NuGet package.

Get cropped image in background
@using Cropper.Blazor.Extensions;
@using Cropper.Blazor.Models;
@using Cropper.Blazor.Exceptions;

<div class="img-container cropper-face-circle">
    <CropperComponent Class="big-img" Src="images/lone-tree.jpg" @ref="cropperComponent" Options="new Blazor.Models.Options()" />
</div>

<div class="button" @onclick="GetCroppedCanvasDataInBackgroundAsync">
    Get cropped image  in background
</div>

<img class="cropped-img-container" src="@croppedCanvasDataURL" />

@* Make sure the size of the image fits perfectly into the container *@
<style>
    .cropper-face {
        opacity: 25%;
    }

    .img-container.cropper-face-circle .cropper-container .cropper-crop-box .cropper-face {
        border-radius: 50%;
    }

    .big-img {
        max-height: 400px;
        /* This rule is very important, please don't ignore this */
        max-width: 100%;
    }

    .img-container {
        max-height: 400px;
        width: 100%;
    }

    /* Means that the cropped image will take up 100% of the width of its containing element */
    .cropped-img-container {
        width: 100%;
    }

    /* These styles are just needed for a nice button and don't related with cropper component */
    .button {
        display: inline-block;
        padding: 10px 20px;
        background-color: #007bff;
        color: #fff;
        border: none;
        border-radius: 5px;
        text-align: center;
        text-decoration: none;
        font-size: 16px;
        cursor: pointer;
    }
</style>
@code {
    [Inject] private IJSRuntime? JSRuntime { get; set; }

    private CropperComponent? cropperComponent = null!;
    private string croppedCanvasDataURL;

    public async Task GetCroppedCanvasDataInBackgroundAsync()
    {
        GetCroppedCanvasOptions getCroppedCanvasOptions = new GetCroppedCanvasOptions
        {
            MaxHeight = 4096,
            MaxWidth = 4096,
            ImageSmoothingQuality = ImageSmoothingQuality.High.ToEnumString()
        };

        CroppedCanvasReceiver croppedCanvasReceiver = await cropperComponent!.GetCroppedCanvasInBackgroundAsync(
            getCroppedCanvasOptions,
            async (croppedCanvas, ct) =>
            {
                // Create an image receiver to receive the processed image data
                ImageReceiver imageReceiver = new ImageReceiver();

                try
                {
                    // Invoke a JavaScript function to apply elliptical background processing to the canvas,
                    // passing in the cropped canvas object and a .NET object reference for callback
                    await JSRuntime!.InvokeVoidAsync(
                        "window.getEllipseImageInBackground",
                        croppedCanvas!.JSRuntimeObjectRef,
                        DotNetObjectReference.Create(imageReceiver));

                    // Retrieve the image stream from the receiver
                    using MemoryStream croppedCanvasDataStream = await imageReceiver.GetImageChunkStreamAsync();

                    // Convert the stream to a byte array
                    byte[] croppedCanvasData = croppedCanvasDataStream.ToArray();

                    // Encode the image data as a base64 data URL for use in HTML
                    croppedCanvasDataURL = "data:image/png;base64," + Convert.ToBase64String(croppedCanvasData);

                    // Force a UI refresh to reflect the new image
                    // This is required because we're in an async JS interop callback context,
                    // which runs outside of Blazor’s normal rendering/event loop.
                    // Calling StateHasChanged directly here might not work as expected
                    // because it may not execute on the Blazor synchronization context.
                    // InvokeAsync ensures StateHasChanged is called on the correct thread.

                    // Use InvokeAsync(StateHasChanged) in the following cases:
                    // 1. **JS Interop callbacks** – when data is updated via JS and needs a re-render.
                    // 2. **Background tasks** – when working with tasks outside the Blazor rendering context.

                    // **Be careful with InvokeAsync(StateHasChanged) in components with many elements or heavy rendering logic**:
                    // - Calling StateHasChanged frequently can cause **performance issues** if the component contains many UI elements.
                    // - Each call to StateHasChanged forces a full re-render of the component, which can be costly in large or complex components.
                    // - To mitigate this, consider breaking down your large components into **smaller, more manageable child components**.
                    // - **Smaller components** will re-render independently, reducing the overall re-render scope and improving performance.
                    await InvokeAsync(StateHasChanged);
                }
                catch (ImageProcessingException ex)
                {
                    // Handle any image processing errors (currently empty - consider logging or rethrowing)
                }
            });
    }
}
Crop a polygon image in Background

Note: Note: This is available with the release of version 1.4.1 of the Cropper.Blazor NuGet package.

Get cropped image in background
@using Cropper.Blazor.Extensions;
@using Cropper.Blazor.Models;
@using Cropper.Blazor.Exceptions;

<div class="img-container cropper-face-pentagon">
    <CropperComponent Class="big-img" Src="images/Mushrooms.jpg" @ref="cropperComponent" Options="new Blazor.Models.Options()" />
</div>

<div class="button" @onclick="GetCroppedCanvasDataInBackgroundAsync">
    Get cropped image in background
</div>

<img class="cropped-img-container" src="@croppedCanvasDataURL" />

@* Make sure the size of the image fits perfectly into the container *@
<style>
    .cropper-face {
        opacity: 25%;
    }

    .img-container.cropper-face-pentagon .cropper-container .cropper-crop-box .cropper-face {
        clip-path: polygon(50% 0%, 100% 38%, 82% 100%, 18% 100%, 0% 38%);
    }

    .big-img {
        max-height: 400px;
        /* This rule is very important, please don't ignore this */
        max-width: 100%;
    }

    .img-container {
        max-height: 400px;
        width: 100%;
    }

    /* Means that the cropped image will take up 100% of the width of its containing element */
    .cropped-img-container {
        width: 100%;
    }

    /* These styles are just needed for a nice button and don't related with cropper component */
    .button {
        display: inline-block;
        padding: 10px 20px;
        background-color: #007bff;
        color: #fff;
        border: none;
        border-radius: 5px;
        text-align: center;
        text-decoration: none;
        font-size: 16px;
        cursor: pointer;
    }
</style>
@code {
    [Inject] private IJSRuntime? JSRuntime { get; set; }

    private CropperComponent? cropperComponent = null!;
    private string? croppedCanvasDataURL;

    public async Task GetCroppedCanvasDataInBackgroundAsync()
    {
        GetCroppedCanvasOptions getCroppedCanvasOptions = new GetCroppedCanvasOptions
        {
            MaxHeight = 4096,
            MaxWidth = 4096,
            ImageSmoothingQuality = ImageSmoothingQuality.High.ToEnumString()
        };

        CroppedCanvasReceiver croppedCanvasReceiver = await cropperComponent!.GetCroppedCanvasInBackgroundAsync(
            getCroppedCanvasOptions,
            async (croppedCanvas, ct) =>
            {
                // Create an image receiver to receive the processed image data
                ImageReceiver imageReceiver = new ImageReceiver();

                try
                {
                    // Invoke a JavaScript function to apply elliptical background processing to the canvas,
                    // passing in the cropped canvas object and a .NET object reference for callback
                    await JSRuntime!.InvokeVoidAsync(
                        "window.getPolygonImageInBackground",
                        croppedCanvas!.JSRuntimeObjectRef,
                        // Defines a polygon using an SVG fill rule and a set of vertices previously defined in the following format styles:
                        // .img-container.cropper-face-pentagon.cropper-container.cropper-crop-box.cropper-face {
                        //     clip-path: polygon(50% 0%, 100% 38%, 82% 100%, 18% 100%, 0% 38%);
                        // }
                        // In our case, we need to pass the same data, but without the percent sign (%)
                        new int[] { 50, 0, 100, 38, 82, 100, 18, 100, 0, 38 },
                        DotNetObjectReference.Create(imageReceiver));

                    // Retrieve the image stream from the receiver
                    using MemoryStream croppedCanvasDataStream = await imageReceiver.GetImageChunkStreamAsync();

                    // Convert the stream to a byte array
                    byte[] croppedCanvasData = croppedCanvasDataStream.ToArray();

                    // Encode the image data as a base64 data URL for use in HTML
                    croppedCanvasDataURL = "data:image/png;base64," + Convert.ToBase64String(croppedCanvasData);

                    // Force a UI refresh to reflect the new image
                    // This is required because we're in an async JS interop callback context,
                    // which runs outside of Blazor’s normal rendering/event loop.
                    // Calling StateHasChanged directly here might not work as expected
                    // because it may not execute on the Blazor synchronization context.
                    // InvokeAsync ensures StateHasChanged is called on the correct thread.

                    // Use InvokeAsync(StateHasChanged) in the following cases:
                    // 1. **JS Interop callbacks** – when data is updated via JS and needs a re-render.
                    // 2. **Background tasks** – when working with tasks outside the Blazor rendering context.

                    // **Be careful with InvokeAsync(StateHasChanged) in components with many elements or heavy rendering logic**:
                    // - Calling StateHasChanged frequently can cause **performance issues** if the component contains many UI elements.
                    // - Each call to StateHasChanged forces a full re-render of the component, which can be costly in large or complex components.
                    // - To mitigate this, consider breaking down your large components into **smaller, more manageable child components**.
                    // - **Smaller components** will re-render independently, reducing the overall re-render scope and improving performance.
                    await InvokeAsync(StateHasChanged);
                }
                catch (ImageProcessingException ex)
                {
                    // Handle any image processing errors (currently empty - consider logging or rethrowing)
                }
            });
    }
}
Preparing the image for uploading to the server

With the Decode extension method in DataUrlDecoder static class from the Cropper.Blazor.Extensions namespace, you can decode the data url into a Base64 image data and outs the media type.

Decode method have following argument:

dataUrl (required) - The data url to be decoded (e.g. data:image/png;base64,SGVsbG8gd29ybGQ=).

If the parsing data url was unsuccessful, we throw the following ArgumentException exception with the following message: Could not parse '{dataUrl}' as '"data:(?<type>.+?),(?<data>.+)"' data URL pattern.
Note: This method is available as of version 1.3.1 of the Cropper.Blazor NuGet package.

Get decoded image data
@using Cropper.Blazor.Extensions;
@using Cropper.Blazor.Models;

<div class="img-container">
    <CropperComponent Class="big-img" Src="icon-515x512.png" @ref="cropperComponent" Options="new Blazor.Models.Options()" />
</div>

@if (decodedImageData is { base64ImageData: null, mediaType: null })
{
    <div class="button" @onclick="GetDecodedImageDataAsync">
        Get decoded image data
    </div>
}
else
{
    <MudText Typo="Typo.body2">
        Media type: @decodedImageData!.mediaType
    </MudText>
    <MudText Typo="Typo.body2" Class="text-with-dots">
        Base64: @decodedImageData!.base64ImageData
    </MudText>
    <MudText Typo="Typo.body2" Class="text-with-dots">
        Data URL: @croppedCanvasDataURL
    </MudText>
}

@* Make sure the size of the image fits perfectly into the container *@
<style>
    .big-img {
        max-height: 400px;

        /* This rule is very important, please don't ignore this */
        max-width: 100%;
    }

    .img-container {
        max-height: 400px;
        width: 100%;
    }

    /* Means that the cropped image will take up 100% of the width of its containing element */
    .cropped-img-container {
        width: 100%;
    }

    /* These styles are just needed for a nice button and don't related with cropper component */
    .button {
        display: inline-block;
        padding: 10px 20px;
        background-color: #007bff;
        color: #fff;
        border: none;
        border-radius: 5px;
        text-align: center;
        text-decoration: none;
        font-size: 16px;
        cursor: pointer;
    }
</style>
@code {
    private CropperComponent? cropperComponent = null!;
    private string croppedCanvasDataURL;
    private (string base64ImageData, string mediaType) decodedImageData;

    public async Task GetDecodedImageDataAsync()
    {
        GetCroppedCanvasOptions getCroppedCanvasOptions = new GetCroppedCanvasOptions
        {
            MaxHeight = 4096,
            MaxWidth = 4096,
            ImageSmoothingQuality = ImageSmoothingQuality.High.ToEnumString()
        };

        croppedCanvasDataURL = await cropperComponent!.GetCroppedCanvasDataURLAsync(getCroppedCanvasOptions);
        decodedImageData = croppedCanvasDataURL.Decode();
    }
}
An unhandled error has occurred. Reload 🗙