Unexpected get_pixel() behavior

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By DDoop

Trying to get the Color value out of a specific image’s pixel given a LMB click. This script is attached to a basic Node (I prefer to use them as my scene roots):

func _process(delta):
if Input.is_action_just_pressed("lmb"):
	var data: Image = get_viewport().get_texture().get_data()
	data.lock()
	var world_click_pos: Vector2 = get_viewport().get_mouse_position()
	print("click at: %s" % world_click_pos)
	var color: Color = data.get_pixelv(world_click_pos);
	ColorNode.color = color # A ColorRect child, aliased out of scope of _process()
	print(str(color))
	data.unlock()

I fairly consistently get incorrect Color values out of this. The printed Vector4 is incorrect and the ColorRect displays the wrong color. It’s almost like the position I’m feeding to get_pixelv() isn’t right.
I’ve tried world_click_pos = get_global_mouse_pos() to no avail as well. (That I had to try in a script attached to the Sprite itself, since bare Node objects don’t have access to that method).
I’ve tried it by keeping the Sprite at (0, 0) with offset = false, as well as setting the position programmatically to the center of the screen. Both give me false color readings. For clarification, here is the scene tree:
enter image description here

:bust_in_silhouette: Reply From: DDoop

I solved it by using a radial rainbow gradient as the Sprite’s image, which made it very clear that the coordinates needed to be “inverted” along the center X-axis of the Image.

Source for the curious/frustrated:

func _process(delta):
if Input.is_action_just_pressed("lmb"):
	var data: Image = get_viewport().get_texture().get_data()
	data.lock()
	print(data.data["width"])
	print(data.data["height"])
	var click_pos: Vector2 = get_viewport().get_mouse_position()
	var adj_click_pos: Vector2 = invert_coordinates(click_pos)
	print("click at: %s" % click_pos)
	print("flipped pos: %s" % adj_click_pos)
	var color: Color = data.get_pixelv(adj_click_pos);
	ColorNode.color = color
	print(str(color))
	data.unlock()

func invert_coordinates(first_pos: Vector2) -> Vector2:
    var view_size = get_viewport().size
    var view_dim = Vector2(view_size.x, view_size.y)
    var adj_coords = Vector2(first_pos.x, view_size.y - first_pos.y)
    return adj_coords

DDoop | 2020-06-29 19:26