0

I'm trying to build a Blazor Server web app that modifies any uploaded image by ARGB pixels, using ImageSharp. So, I came across this webpage (<https://docs.sixlabors.com/articles/imagesharp/pixelbuffers.html). In the "Parallel, Pixel-Format Agnostic Image Manipulation" section, it has a code sample that I want to add to my web app:

image.Mutate(c => c.ProcessPixelRowsAsVector4(row =>
{
    for (int x = 0; x < row.Length; x++)
    {
        // We can apply any custom processing logic here
        row[x] = Vector4.SquareRoot(row[x]);
    }
}));

However, I'm stuck figuring how to get this code work on my web app. Can you provide me an example of custom processing logic in this code? Or, is there other better code I can use?


Here is my web app's Razor page for your information.

@using BlazorServerApp1; @*project name*@
@using BlazorInputFile
@using SixLabors.ImageSharp;
@using SixLabors.ImageSharp.Formats;
@using SixLabors.ImageSharp.Processing;
@using SixLabors.ImageSharp.PixelFormats; @*<rgba32>*@
@using System;
@using System.IO;
@using System.Numerics; @*vector4*@
@page "/imageedit0"


<h1>Image Edit</h1>
<h3>Upload an image</h3>

@*button upload an image*@
<InputFile OnChange="HandleFileSelected_function" />

@*display an image, upload status, and filter button*@
@if (displayImage == true)
{
    <h5>@status</h5>
    <img src="@_ip.getBase64String_function()" style="width:400px" />
    <p>
        <button class="btn btn-primary" @onclick="Filter1">filter1</button> <br />
        <button class="btn btn-primary" @onclick="Filter2">filter2</button> <br />
    </p>
}



@code {
    string status;
    string Error;
    bool displayImage = false;
    ImageProcessing_CS _ip;
    Image<Rgba32> image;
    IImageFormat IIF1;

    //filter1 = replace dark colors with red color
    void Filter1()
    {
        for (int w = 0; w < image.Width; w++)
        {
            for (int h = 0; h < image.Height; h++)
            {
                if (image[w, h].R < 200 && image[w, h].G < 200 && image[w, h].B < 200)
                    image[w, h] = new Rgba32(255, image[w, h].G, image[w, h].B, image[w, h].A);
            }
        }
    }

    //how to add custom processing logic here?
    void Filter2()
    {
        image.Mutate(c => c.ProcessPixelRowsAsVector4(row =>
        {
            for (int x = 0; x < row.Length; x++)
            {
                // We can apply any custom processing logic here
                row[x] = Vector4.SquareRoot(row[x]);
            }
        }));
    }

    //uploads and initalizes image
    async Task HandleFileSelected_function(IFileListEntry[] files)
    {
        var imageFile = files.FirstOrDefault();

        if (imageFile != null)
        {
            var ms = new MemoryStream();
            await imageFile.Data.CopyToAsync(ms);
            try
            {
                image = Image.Load<Rgba32>(ms.ToArray(), out IIF1);
                _ip = new ImageProcessing_CS(image, IIF1);
                displayImage = true;
                status = $"Finished loading {imageFile.Size} bytes from {imageFile.Name}";
            }
            catch (Exception e)
            {
                Error = $"Error occured while loading image {e.Message}";
            }
        }
    }
}
  • Honestly, docs are a bit misleading IMO: "There is a way to process image data that is even faster than using the approach mentioned before" It's only faster if you need to do some computational stuff that better performed with Vector4 than with Rgba32, or if you really need to go pixel agnostic. If you're fine with your image always being an image of `Rgba32` go to the previous paragraph in those docs (Efficient pixel manipulation), and use GetPixelRowSpan. – antonfrv May 28 '21 at 14:24
  • @klapancius Oh I'm not the only one then. Ok, I went with previous paragraph and it works with editing my Rgba32 images. Thank you!! – Patrick DLR Jun 04 '21 at 23:21

0 Answers0