Sure, this code cannot work. In order for Control.Begin/Invoke() to work, .NET first needs to know what specific thread your code needs to run on. Which it figures out from the Handle property. Which tells it which specific thread owns the window, the underlying winapi call is GetWindowThreadProcessId().
But that's a chicken-and-egg problem in your code. The native window doesn't get created until your code calls the Controls.Add() method. Which must run on the UI thread of your program, the thread that owns the Form object. Windows does not permit a child window to be owned by a different thread.
So it just doesn't know what thread to invoke to. If you force the handle to be created then your program just dies a different way because of the ownership rule.
Keep your eye on the bigger problem: you are creating a thread to run code that takes a handful of nanoseconds. These property assignments are very cheap. The real work is creating the window, that takes many microseconds. Which you want (and need) to run on the UI thread. So there's just no benefit to using a thread at all, the UI thread won't sweat spending a few nanoseconds on setting the properties as well.
So remove the thread completely to get ahead. If you are doing something else that's slow, like loading the image, then that can easily be done on a worker thread.