SixLabors / ImageSharp

:camera: A modern, cross-platform, 2D Graphics library for .NET
https://sixlabors.com/products/imagesharp/
Other
7.36k stars 850 forks source link

Looking for methods to Plot Single Pixel #1088

Closed StevenGann closed 4 years ago

StevenGann commented 4 years ago

Description

Attempting to use the following code results in a compile-time error:

using (Image image = new Image<Rgba32>(1920, 1080))
{
    for (int i = 0; i < 1920; i++)
    {
        for (int j = 0; j < 1080; j++)
        {
            double A = tree.Get(i, j, 0, 4).A;
            byte a = (byte)(A * 255);
            Rgba32 pixel = new Rgba32(a, a, a);
            image[i, j] = pixel;
        }
    }
}

Error message:

Error   CS0021  Cannot apply indexing with [] to an expression of type 'Image'

All I need is a way to plot greyscale pixels onto an image in .NET Core. How am I supposed to plot individual pixels with ImageSharp?

JimBobSquarePants commented 4 years ago

As indicated by the issue template. Please do not ask questions in the issues tracker.

You should not create an issue but use Gitter instead: https://gitter.im/ImageSharp/General

(This is your first issue though so I can understand and appreciate an honest mistake)

So to answer your question. Image is a pixel agnostic abstraction of your pixel buffer that allows operating on pixel data via the processing pipeline without being concerned by the pixel format. If you look at our readme we are actually using the implicit typed local variable var to represent Image<Rgba32> which contains the indexer you are looking for.

Image<TPixel> inherits Image adding direct pixel access.

using SixLabors.ImageSharp;
using SixLabors.ImageSharp.PixelFormats;

// Individual pixels
using (var image = new Image<Rgba32>(400, 400))
{
    image[200, 200] = Rgba32.White;
}

Our API docs. Linked from the repository representing the Image<TPixel>[x, y] indexer can be found here.

In your scenario though I would recommend using image.GetPixelRowSpan<TPixel>(y) since that allows you to operate on a per-row basis removing the need to calculate the pixel offset in the buffer per pixel operation.

using (Image<Rgba32> image = new Image<Rgba32>(1920, 1080))
{
    for (int y = 0; y < image.Height; y++)
    {
        Span<Rgba32> row = image.GetPixelRowSpan(y);

        for (int x = 0; x < row.Length; x++)
        {
            double A = tree.Get(y, x, 0, 4).A;
            byte a = (byte)(A * 255);

            ref Rgba32 pixel =  ref row[x];
            pixel.R = a;
            pixel.G = a;
            pixel.B = a;
            pixel.A = 255;
        }
    }
}

I hope that all makes sense. 😄

StevenGann commented 4 years ago

Just as well, the Span<Rgba32> approach has a similar problem:

CS1061 'Image<Rgba32>' does not contain a definition for 'GetPixelRowSpan' and no accessible extension method 'GetPixelRowSpan' accepting a first argument of type 'Image<Rgba32>' could be found

tocsoft commented 4 years ago

closing as its a question raised due to not knowing how to use the APIs and where to find them not because APIs in ImageSharp are broken.

JimBobSquarePants commented 4 years ago

so please direct your juvenile attitude at whoever did instead of the end user who's trying to make use of your software and is quickly realizing he'd be better off using a library maintained by professionals instead.

You owe everyone here an apology for your incredibly unprofessional behavior. The working code attached here is a copy/paste from the sample I posted above.

ISPixelDemo.zip

using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Advanced;
using SixLabors.ImageSharp.PixelFormats;
using System;

namespace ISPixelDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            // Individual pixels
            using (Image<Rgba32> image = new Image<Rgba32>(400, 400))
            {
                image[200, 200] = Rgba32.White;
            }

            using (Image<Rgba32> image2 = new Image<Rgba32>(1920, 1080))
            {
                for (int y = 0; y < image2.Height; y++)
                {
                    Span<Rgba32> row = image2.GetPixelRowSpan(y);

                    for (int x = 0; x < row.Length; x++)
                    {
                        byte a = 100;

                        ref Rgba32 pixel = ref row[x];
                        pixel.R = a;
                        pixel.G = a;
                        pixel.B = a;
                        pixel.A = 255;
                    }
                }
            }

            Console.WriteLine("You owe everyone here an apology!");
        }
    }
}
JimBobSquarePants commented 4 years ago

Here's a working (compiled, run) version of the example application targeting NET Core 2.1

ISPixelDemo_2_1.zip

peter-dolkens commented 4 years ago

There's a number of problems here, and one may just be my own .NET install. One thing I know for sure is that lack of professionalism and excess of ego is a major one. In the future, when dealing with end users, it is worth actually reading tickets instead of falsely categorizing them and rudely dismissing them.

As an outsider looking in - @JimBobSquarePants answered you quite professionally by directing you to the correct place to receive the support you needed, and still attempted to help you in here.

Not only that, but you're citing #458 as the your reference issue, and the exact same message is provided there: For Q&A, use Gitter, for bugs, use Github.

To be honest, the only ego I really saw here was yours when you attacked the repo maintainers for explaining to you that you didn't quite understand the API implementation, that there was no bug, and then provided working sample code that solved your problem.

This guy's been maintaining this library for longer than you've been out of school, so perhaps consider that next time you accuse him of not understanding his own creation?

merarischroeder commented 4 years ago

I wonder, is "incorrect" documentation considered a bug by the maintainers here? I suggest that clarification of this will help others in the future.

That will help the maintainers and newcomers alike.

tocsoft commented 4 years ago

@merarischroeder yes it is I we welcome a docs issues being pointed out.

Thing we consider official documentation however is limited to our docs website (https://docs.sixlabors.com), the README files on our repos and our xml code comments (as they get presented in visual studio).

tocsoft commented 4 years ago

Something I would like to clarify on this particular issue is we believe at no point have we been presented with an identified issue with the docs. i.e. a link pointing out a piece of our official documentation that is incorrect.

What we were provided with was a code snippet from the developers own code that would not able to be compiled directly as it was missing core code (the tree.Get() stuff) which is why this ticket was deamed a question and as by our guidelines was directed over to gitter for more real time/direct help. (despite this we actually did answer the question here.)

I hope this helps to clarify why this ticket was handled in the way it was.

peter-dolkens commented 4 years ago

For reference @StevenGann, @merarischroeder - the documentation for the method in question is here:

https://docs.sixlabors.com/api/ImageSharp/SixLabors.ImageSharp.Advanced.AdvancedImageExtensions.html

public static Span<TPixel> GetPixelRowSpan<TPixel>(this Image<TPixel> source, int rowIndex)
where TPixel : struct, IPixel<TPixel>

Visual Studio will generally suggest the required includes automatically these days too if you simply right click on the error, and view the recommended fixes.

StevenGann commented 4 months ago

@JimBobSquarePants @tocsoft @peter-dolkens Hey I just wanted to toss a final comment here. I came across this issue while troubleshooting exactly the same issue 4 years later and reading back over my comments here I feel terrible, but at least I hope I've grown a bit as a person since then.

Anyway, thanks for maintaining this project and trying to assist with my issue, even if I wasn't very appreciative at the time.

antonfirsov commented 4 months ago

exactly the same issue 4 years later

In case anyone would land on this page in the future, here are the docs for the 2.0+ pixel manipulation APIs: https://docs.sixlabors.com/articles/imagesharp/pixelbuffers.html