Home > Software design >  How to get the image pixel value when mouse click on the image with Flutter
How to get the image pixel value when mouse click on the image with Flutter

Time:02-21

How do I can get the image pixel value (the pixel coordinate x and y of the image) when mouse click anywhere on the image by using Flutter?

Thank you

CodePudding user response:

You can use/add a GestureDetector as parent of stack, and register onTapDownDetails listener. This will call the listenr on every tap down and will give you the offset of the tap. Use the TapDownDetail Parameter of that event listener.

Code you can use :

import 'package:flutter/material.dart';

void main() {
  runApp(new MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Flutter Demo',
      home: new MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  MyHomePageState createState() => new MyHomePageState();
}

class MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
        appBar: new AppBar(
          title: new Text('Popup Demo'),
        ),
        body: new MyWidget());
  }
}

class MyWidget extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return new MyWidgetState();
  }
}

class MyWidgetState extends State<MyWidget> {
  double posx = 100.0;
  double posy = 100.0;

  void onTapDown(BuildContext context, TapDownDetails details) {
    print('${details.globalPosition}');
    final RenderBox box = context.findRenderObject();
    final Offset localOffset = box.globalToLocal(details.globalPosition);
    setState(() {
      posx = localOffset.dx;
      posy = localOffset.dy;
    });
  }

  @override
  Widget build(BuildContext context) {
    return new GestureDetector(
      onTapDown: (TapDownDetails details) => onTapDown(context, details),
      child: new Stack(fit: StackFit.expand, children: <Widget>[
        // Hack to expand stack to fill all the space. There must be a better
        // way to do it.
        new Container(color: Colors.white),
        new Positioned(
          child: new Text('hello'),
          left: posx,
          top: posy,
        )
      ]),
    );
  }
}

CodePudding user response:

You can get the touch position by using a GestureDetector, and then the pixel color by using the ImagePixels widget from the image_pixels package:

ImagePixels(
   imageProvider: ...,
   builder: (BuildContext context, ImgDetails img) {
      var color = img.pixelColorAt(x, y);

This is a working example:

import 'package:image_pixels/image_pixels.dart';
...

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, this.title}) : super(key: key);
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final AssetImage flutter = const AssetImage("lib/images/FlutterLogo.jpg");

  Offset localPosition = const Offset(-1, -1);
  Color color = const Color(0x00000000);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SizedBox.expand(
        child: Column(
          children: [
            const Expanded(
              flex: 1,
              child: Center(
                child: Text('Tap the image to see the pixel color:'),
              ),
            ),
            Expanded(
                flex: 4,
                child: Padding(
                    padding: const EdgeInsets.all(40.0),
                    child: Center(
                        child: Container(
                            color: Colors.grey,
                            child: Listener(
                                onPointerMove: (PointerMoveEvent details) {
                                  setState(() {
                                    localPosition = details.localPosition;
                                  });
                                },
                                onPointerDown: (PointerDownEvent details) {
                                  setState(() {
                                    localPosition = details.localPosition;
                                  });
                                },
                                child: ImagePixels(
                                    imageProvider: flutter,
                                    builder: (BuildContext context, ImgDetails img) {
                                      var color = img.pixelColorAt!(
                                        localPosition.dx.toInt(),
                                        localPosition.dy.toInt(),
                                      );

                                      WidgetsBinding.instance!.addPostFrameCallback((_) {
                                        if (mounted)
                                          setState(() {
                                            if (color != this.color) this.color = color;
                                          });
                                      });

                                      return SizedBox(
                                        width: 150,
                                        height: 213,
                                        child: Image(image: flutter),
                                      );
                                    })))))),
            
            Expanded(
              flex: 2,
              child: Column(
                children: [
                  Container(width: 75, height: 55, color: color),
                  Container(height: 20),
                  Text(localPosition.toString()),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }
}

Get the code from GitHub.

Note: I am the author of the package.

  • Related