(39) 's Extra Blueprint Nodes for You as a Plugin, No C++ Required!

Load Image From File, and Retrieve Pixel Data!

Dear Community,

As requested I’ve made a node that let’s you load an image from file, and get the pixel data from the image for use in Blueprints!

Very conveniently, the pixel data comes in the Linear Color format so you can directly plug your pixels into Print string nodes or any other node that wants a color in UE4 Blueprints!!

** node is live as of April 17th, 2015 5:43am version!**


**Bonus Just For You ~ Get Pixel by Coordinate!**

And as a bonus, just for you Community members, I've added a node that let's you specify a pixel coordinate and retrieves that value from the pixel data array!

Picture explanation

In the top picture I am loading an image at runtime, and then using print string to display the color values of different pixels within the image, notice how they match correctly in a 5 x 5 image! (it blurs cause of how textures work)


**BP Implementation**

![LoadImagePixels.jpg|1280x960](upload://x4rr84sVoeasRSMdQnWY13yUVvZ.jpeg)

![GetImagePixel.jpg|1280x960](upload://ywwata5V8Ypp8BnDKI1xqeuHKhi.jpeg)

Indices Start at 0,0

Please note that in the image that is 5 x 5, the lower right corner is 4,4 because picture indices start at 0,0 not 1,1.


**PNG Format**

Please make sure to use .png format for small images if you are wanting to use the pixel data to proceduraly generate world, jpg has compression quality loss that destroys pixel-level precision, especially for small files.

Plugin Download ( Tiny file, about 0.5 MB )

**Latest Download From the UE4 Wiki Site **


**My C++ Code For You**

Here's the C++ code for my new node!



```


UTexture2D* UVictoryBPFunctionLibrary::Victory_LoadTexture2D_FromFile_Pixels(const FString& FullFilePath,EJoyImageFormats ImageFormat,bool& IsValid, int32& Width, int32& Height, TArray<FLinearColor>& OutPixels)
{
	//Clear any previous data
	OutPixels.Empty();
	
	IsValid = false;
	UTexture2D* LoadedT2D = NULL;
	
	IImageWrapperModule& ImageWrapperModule = FModuleManager::LoadModuleChecked<IImageWrapperModule>(FName("ImageWrapper"));
	// Note: PNG format.  Other formats are supported
	IImageWrapperPtr ImageWrapper = ImageWrapperModule.CreateImageWrapper(GetJoyImageFormat(ImageFormat));
 
	//Load From File
	TArray<uint8> RawFileData;
	if (!FFileHelper::LoadFileToArray(RawFileData, *FullFilePath)) return NULL;
	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	  
	//Create T2D!
	if (ImageWrapper.IsValid() && ImageWrapper->SetCompressed(RawFileData.GetData(), RawFileData.Num()))
	{  
		const TArray<uint8>* UncompressedBGRA = NULL;
		if (ImageWrapper->GetRaw(ERGBFormat::BGRA, 8, UncompressedBGRA))
		{
			LoadedT2D = UTexture2D::CreateTransient(ImageWrapper->GetWidth(), ImageWrapper->GetHeight(), PF_B8G8R8A8);
			
			//Valid?
			if(!LoadedT2D) return NULL;
			//~~~~~~~~~~~~~~
			
			//Out!
			Width = ImageWrapper->GetWidth();
			Height = ImageWrapper->GetHeight();
			
			const TArray<uint8>& ByteArray = *UncompressedBGRA;
			//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
			
			for(int32 v = 0; v < ByteArray.Num(); v+=4) 
			{ 
				if(!ByteArray.IsValidIndex(v+3)) 
				{ 
					break;
				}   
				  
				const uint8& B = ByteArray[v];
				const uint8& G = ByteArray[v+1];
				const uint8& R = ByteArray[v+2];
				const uint8& A = ByteArray[v+3]; 
				
				OutPixels.Add(FLinearColor(R,G,B,A));
			}
			//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
			   
			//Copy!
			void* TextureData = LoadedT2D->PlatformData->Mips[0].BulkData.Lock(LOCK_READ_WRITE);
			FMemory::Memcpy(TextureData, UncompressedBGRA->GetData(), UncompressedBGRA->Num());
			LoadedT2D->PlatformData->Mips[0].BulkData.Unlock();

			//Update!
			LoadedT2D->UpdateResource();
		}
	}
	 
	// Success!
	IsValid = true;
	return LoadedT2D;
	
}


```



C++ Pixel Core

Here’s the core of my C++ code above where I turn the loaded byte array into Linear Color Pixel data!

Note how the provided format is BGRA so I have to re-arrange the values when I send them out to the FLinearColor constructor!



const TArray<uint8>& ByteArray = *UncompressedBGRA;

for(int32 v = 0; v < ByteArray.Num(); v+=4) 
{ 
	if(!ByteArray.IsValidIndex(v+3)) 
	{ 
		break;
	}   
	  
	const uint8& B = ByteArray[v];
	const uint8& G = ByteArray[v+1];
	const uint8& R = ByteArray[v+2];
	const uint8& A = ByteArray[v+3]; 
	
	OutPixels.Add(FLinearColor(R,G,B,A));
}



Enjoy!

♥