Is it possible to make GeometryReader less vertically greedy?

I must be missing something here. I want to put a landscape image in a geometry reader that contains a ZStack that contains an image and an overlay centred on top of the Image. I would like the ZStack and GeoReader's sizes to be the size of Image. (ie I want geometry.size to be the size of the image, which can be used to control the offset of the overlay's position.) Unfortunately the ZStack also includes the space above the image (ie the top safeArea) and the GeometryReader also includes all the space below the Image. (so geometry.size.height is greater than the height of Image)

I've gone down rabbit holes of adding other items above/below, but I don't seem to be able to prevent the GeometryReader from being vertically greedy. eg the Text(" ") above the ZStack in the VStack solves the ZStack claiming the top safe area. But adding Text(" ") below the ZStack does not prevent the GeometryReader from claiming more vertical space below the image. Any/all guidance greatly appreciated.

struct ContentView: View {
    var body: some View {
        VStack {
//            Text(" ")
            
            GeometryReader { geometry in
                ZStack {
                    Image(
                        uiImage: .init(imageLiteralResourceName: "LandscapeSample")
                    )
                    .resizable()
                    .aspectRatio(contentMode: .fit)
                    Text("Hello, world!")
                        .background(.white)
                }
                .background(.red)
            }
            .background(.blue)
//            Text(" ")
        }
    }
}

GeometryReader is a flexible container and will fill the size of any view its placed in. Ultimately it depends on what you want to do with the size, e.g. one approach used for scenarios that require it is to add an overlay with the geometry reader:

Image("LandscapeSample")
    .resizable()
    .aspectRatio(contentMode: .fit)
    .border(Color.blue)
    .overlay {
        GeometryReader { proxy in
            Color.clear
                .contentShape(.rect)
                .onTapGesture { location in
                    print("Tap position: \(location.x) x \(location.y)")
                    print("Local frame: \(proxy.frame(in: .local).width) x \(proxy.frame(in: .local).height)")
                }
        }
    }

I realized, in hindsight my original question was likely too specific. Stepping back, my high level requirements are:

  1. Display an image
  2. show a draggable overlay 'marker' view
  3. update a stateVar/modelProperty unitVector CGSize value with the marker's location

(eg top left would be 0,0, centre would be 0.5, 0.5, bottom right would be 1,1) 4. marker should not be able to be dragged beyond the edges of the image I now feel like my initial plan to do GeometryReader { ZStack { Image marker } } Might not be the right approach. I feel like the 'hard part' will be determining the marker's position relative to the Image. Any guidance on this is greatly appreciated.

Is it possible to make GeometryReader less vertically greedy?
 
 
Q