How to generate a new UTexture2D asset from only pixel data?

I have been knocking my head around at this problem for a couple days now. I have no source texture, I want to generate a new Texture2D asset (not at runtime) from generated pixel data.

The object shows up in editor and appears to get down to the Texture->Source.Init() line without issue. For the life of me I cannot figure out how to apply the pixel data. I am sure I am missing something obvious but clearly I’ve been staring at it for too long.

// Texture Information
	FString FileName = FString("MyTexture");
	int width = 1024;
	int height = 1024;
	uint8* pixels = 1728061504; //magic number in PF_R8G8B8A8
	
	// Create Package
	FString pathPackage = FString("/Game/MyTextures/");
	FString absolutePathPackage = FPaths::ProjectContentDir() + "/MyTextures/";

	// Load necessary modules
	FAssetToolsModule& AssetToolsModule = FModuleManager::Get().LoadModuleChecked<FAssetToolsModule>("AssetTools");
	FAssetRegistryModule& AssetRegistryModule = FModuleManager::LoadModuleChecked<FAssetRegistryModule>(TEXT("AssetRegistry"));
	 
	// Generate a unique asset name
	FString Name, PackageName;
	AssetToolsModule.Get().CreateUniqueAssetName(TEXT("/Game/MyTextures/AssetName"), TEXT(""), PackageName, Name);
	FString PackagePath = FPackageName::GetLongPackagePath(PackageName);
		
	// Create and Cast the new object as a UTexture2D
	UPackage* Package = CreatePackage(*PackageName);
	UTexture2DFactoryNew* MyFactory = NewObject<UTexture2DFactoryNew>(UTexture2DFactoryNew::StaticClass()); 
	UObject* NewObject = AssetToolsModule.Get().CreateAsset(Name, PackagePath, UTexture2D::StaticClass(), MyFactory);
	UTexture2D* Texture = Cast<UTexture2D>(NewObject);

	Texture->Source.Init(width, height, 1, 1, TSF_RGBA16, 0);
	Texture->GetPlatformData()->PixelFormat = PF_R8G8B8A8;

	//Add pixel data
	FTexture2DMipMap Mip = Texture->GetPlatformMips()[0];
	Mip.BulkData.Lock(LOCK_READ_WRITE);
	uint8* TextureData = (uint8 *) Mip.BulkData.Realloc(height * width * sizeof(uint8)*4);
	FMemory::Memcpy(TextureData, pixels, sizeof(uint8) * height * width * 4);
	Mip.BulkData.Unlock();

	Texture->AddToRoot();
	Texture->UpdateResource();
	Texture->PostEditChange();
	Package->MarkPackageDirty();

You can look how epic does it in UCurveLinearColorAtlas.
That one takes a list color curves and creates a texture out of it.

I would not necessarily do it exactly the same way and just reuse the part writing into the texture.