Offsets are different onTap and OnDrag - Flutter

its working for me

class _HomeState extends State<Home> {
  ImageInfo _imageInfo;
  AssetImage assestImage;
  double getheight;
  double getywidth;

  Offset dragOffset;
  @override
  void initState() {
    super.initState();
    assestImage = AssetImage('assets/hospital.jpg');
    WidgetsBinding.instance.addPostFrameCallback((a) => _getImageInfo());
  }

  void _getImageInfo() async {
    Image image = new Image.asset('assets/hospital.jpg');
    image.image
        .resolve(new ImageConfiguration())
        .addListener((ImageInfo info, bool _) {
      _imageInfo = info;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
          child: Column(
        children: <Widget>[
          TapImage(
            onTap: (Offset offset, RenderBox getBox, TapDownDetails details) {
              double dx;
              double dy;
              dx = offset.dx * _imageInfo.image.width;
              dy = offset.dy * _imageInfo.image.height;
              setState(() {
                dragEnd(dx, dy);
              });
            },
            image: assestImage,
          ),
          Draggable(
              dragAnchor: DragAnchor.pointer,
              onDragStarted: () {
                WidgetsBinding.instance
                    .addPostFrameCallback((_) => setState(() {
                          RenderBox getBox = context.findRenderObject();
                          getheight = getBox.size.height;
                          getywidth = getBox.size.width;
                        }));
              },
              onDragEnd: (details) {
                double dx;
                double dy;
                dx = (details.offset.dx / getywidth) * _imageInfo.image.width;
                dy =
                    ((details.offset.dy) / getywidth) * _imageInfo.image.height;
                setState(() {
                  dragEnd(dx, dy);
                });
              },
              child: Padding(
                padding: const EdgeInsets.only(top: 28.0),
                child: Container(
                    color: Colors.green,
                    child: Text(
                      'tree',
                      style: TextStyle(fontSize: 30.0),
                    )),
              ),
              feedback: Container(
                height: 10.0,
                child: Text(
                  'tree',
                  style: TextStyle(fontSize: 15.0),
                ),
              )),
        ],
      )),
    );
  }

  void dragEnd(double dx, double dy) {
    if (_imageInfo != null) {
      if ((673 <= dx && dx <= 822) && (635 <= dy && dy <= 849)) {
        showDialog(
          context: context,
          builder: (context) {
            return _textDescriptionDialog(
              context,
              'Drag on tree',
            );
          },
        );
      } else {
        showDialog(
          context: context,
          builder: (context) {
            return _textDescriptionDialog(
              context,
              'Drag outside',
            );
          },
        );
      }
    }
  }

  Widget _textDescriptionDialog(BuildContext context, String text) {
    return new FractionallySizedBox(
        heightFactor: MediaQuery.of(context).orientation == Orientation.portrait
            ? 0.5
            : 0.8,
        widthFactor: MediaQuery.of(context).orientation == Orientation.portrait
            ? 0.8
            : 0.4,
        child: Card(
          shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.all(
              Radius.circular(20.0),
            ),
          ),
          child: Container(child: Center(child: Text(text))),
        ));
  }
}

typedef void OnTapLocation(
    Offset offset, RenderBox getBox, TapDownDetails details);

class TapImage extends StatelessWidget {
  TapImage({Key key, this.onTap, this.image}) : super(key: key);

  final OnTapLocation onTap;
  final ImageProvider image;

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTapDown: (TapDownDetails details) => _onTap(details, context),
      child: Image(image: AssetImage('assets/hospital.jpg')),
    );
  }

  void _onTap(TapDownDetails details, BuildContext context) {
    RenderBox getBox = context.findRenderObject();
    print('size is ${getBox.size}');
    Offset local = getBox.globalToLocal(details.globalPosition);
    print('local is $local');
    onTap(Offset(local.dx / getBox.size.width, local.dy / getBox.size.height),
        getBox, details);
  }
}

You could make new Widget then get local render box size. Something like this:

class _MyHomePageState extends State<MyHomePage> {
  NetworkImage _networkImage;
  ImageInfo _imageInfo;

  @override
  void initState() {
    super.initState();

    _networkImage = NetworkImage('https://i.stack.imgur.com/2PnTa.jpg');
    _getImageInfo();
  }

  void _getImageInfo() async {
    NetworkImage _key = await _networkImage.obtainKey(ImageConfiguration());
    _networkImage.load(_key).addListener((ImageInfo i, bool b){
      print('Image size: ${i.image.width} - ${i.image.height}');
      _imageInfo = i;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: ImageDetector(
          onTap: (Offset offset){
            if(_imageInfo != null){
              print('Image clicked: ${offset.dx * _imageInfo.image.width} x ${offset.dy * _imageInfo.image.height}');
            }
          },
          image: _networkImage,
        ),
      ),
    );
  }
}

typedef void OnTapLocation(Offset offset);

class ImageDetector extends StatelessWidget {
  ImageDetector({Key key, this.onTap, this.image}) : super(key: key);

  final OnTapLocation onTap;
  final ImageProvider image;

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTapDown: (TapDownDetails details) => _onTap(details, context),
      child: Image(image: image),
    );
  }


  void _onTap(TapDownDetails details, BuildContext context) {
    RenderBox getBox = context.findRenderObject();
    Offset local = getBox.globalToLocal(details.globalPosition);

    print('Clicked on: ${local.dx / getBox.size.width} - ${local.dy / getBox.size.height}');
    onTap(Offset(local.dx / getBox.size.width, local.dy / getBox.size.height));
  }
}

This will return click position between 0.0, 0.0 and 1.0, 1.0, you can get size of the image and get exact location from those.

Edit: updated the code