How to get the color of the image pixel on which I clicked?

Viewed 5193

I have an image, specifically, it's loaded in from Image.asset().

It's wrapped in an extended widget, and has its own context.

I can click on it, and get the local position on which I clicked (x/y local to the image/context).

All I want to do from that point is get some information (specifically, color and alpha/opacity, but color is key). I really just want THAT context's image information, and the ability to definitively say "I need byte #" or "I need pixel info from X and Y". I feel like this HAS to exist in Flutter as it's pretty trivial in many (most?) other platforms with a rich UI.

Am I missing something simple, or is this just harder in this platform than I'm mentally allowing for?

Or should I load the html library and do what I need in there?

Thanks!

(by way of history, I'm fluent in iOS dev, C# and .Net, HTML and canvas work, and a host of other platforms over more years than I want to remember, etc, but fairly new to Flutter because we're doing an emergency rewrite of an app we had in Trigger, which is not behaving well any more. Thanks.) :)

2 Answers

I don't know if you are still looking for a solution.

I just made this prototype for you... hope is clear enough.

Here's a video of the result.

By the way, the image library has plenty of methods to workaround what you need... in case you need it, and pixel values are accessible as List, so you can workaround the KML colors and treat the list as a grid (rows, cols math to find the index).

Warning: the library uses a different color format (#AABBGGRR), but can be converted easily though.

UPDATE:

I made a v2 based on the limitations noted in the comments, but change the original snippet to show both approaches. This one generates a snapshot of whatever widget you want (so it takes transforms/colorization/box fittings/whatever u have rendered on screen).

Gives you a lot of versatility, if you don't have to animate or invalidate the widget often.

Check the demo in youtube.

I'd like to add an answer, only available since September 2020.

If you need to read image pixels of an image you have in your widget tree, you can use the ImagePixels widget from the https://pub.dev/packages/image_pixels package (note: I am the author of the package).

Note, you don't need to preload it manually from Image.asset(). You just need to provide the imageProvider. You need to calculate yourself the relative position from the absolute position given by the GestureDetector:

// Some (x, y) position you got from the GestureDetector.
var x = 50;
var y = 25;

@override
Widget build(BuildContext context) {
    return ImagePixels(
              imageProvider: imageProvider,
              builder: (context, img) =>
                  double xRelative = ... // Calculate from x and img.width;
                  double yRelative = ... // Calculate from y and img.width;
                  Text(
                     "Pixel color is: ${img.pixelColorAt(xRelative, yRelative)}.");
              );
} 
Related