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

GetPixel and GetPixelArray

Are Back!

:heart:


**4.25 ****(win32, win64, editor, dev packaged, and shipping)**
[https://www.mediafire.com/file/pgrps...gin25.zip/file](https://www.mediafire.com/file/pgrpsf9my7tv1ae/VictoryPlugin25.zip/file)

Usage

Please note the implementation has changed for GetPixelArray, I traverse the image row-wise now, please see picture for how to traverse the new returned array!

Please note that your texture must be set to compression of VectorDisplacementmap to be used with these nodes! I cancel out with an error if is not the case.


**Source Code Explanation**

I now just use a byte ptr and iterate in sets of 4, which I can do safely because VectorDisplacementmap is the only allowed type (the byte order will always be as expected by my code)

Please also note that VectorDisplacementmap is BGRA ordering, not RGBA.



```


uint8* RawByteArray = (uint8*)RawImageData->Lock(LOCK_READ_ONLY);

//Get!, converting FColor to FLinearColor
FColor ByteColor;
ByteColor.B = RawByteArray[Y * TextureWidth * 4 + (X * 4) ];
ByteColor.G = RawByteArray[Y * TextureWidth * 4 + (X * 4) + 1];
ByteColor.R = RawByteArray[Y * TextureWidth * 4 + (X * 4) + 2];
ByteColor.A = RawByteArray[Y * TextureWidth * 4 + (X * 4) + 3];

//Set!
PixelColor = ByteColor.ReinterpretAsLinear();

RawImageData->Unlock();


```



Full Source Code For Older Versions

If you are using an older version, here are the relevant changes!

VictoryBPFunctionLibrary.h



/**  will modify the original T2D to remove sRGB and change compression to VectorDisplacementMap to ensure accurate pixel reading. -*/
UFUNCTION(BlueprintCallable, Category = "Victory BP Library|Load Texture From File",meta=(Keywords="create image png jpg jpeg bmp bitmap ico icon exr icns"))//, DeprecatedFunction, DeprecationMessage=" function will not work until I figure out how to update it to 4.25, if you need it urgently, please post in my ue4 forum thread for  plugin"))
static bool Victory_GetPixelFromT2D(UTexture2D* T2D, int32 X, int32 Y, FLinearColor& PixelColor);

/**  will modify the original T2D to remove sRGB and change compression to VectorDisplacementMap to ensure accurate pixel reading. -*/
UFUNCTION(BlueprintCallable, Category = "Victory BP Library|Load Texture From File",meta=(Keywords="create image png jpg jpeg bmp bitmap ico icon exr icns"))//, DeprecatedFunction, DeprecationMessage=" function will not work until I figure out how to update it to 4.25, if you need it urgently, please post in my ue4 forum thread for  plugin"))
static bool Victory_GetPixelsArrayFromT2D(UTexture2D* T2D, int32& TextureWidth, int32& TextureHeight,TArray<FLinearColor>& PixelArray);


.cpp



bool UVictoryBPFunctionLibrary::Victory_GetPixelFromT2D(UTexture2D* T2D, int32 X, int32 Y, FLinearColor& PixelColor)
{
if(!T2D)
{
return false;
}

if(X <= -1 || Y <= -1)
{
return false;
}


//~~~
if(T2D->CompressionSettings != TC_VectorDisplacementmap)
{
#if WITH_EDITOR
FMessageLog("PIE").Error(FText::Format(LOCTEXT("Victory_GetPixelFromT2D", "UVictoryBPFunctionLibrary::Victory_GetPixelFromT2D >> Texture Compression must be VectorDisplacementmap <3: {0}'"), FText::FromString(T2D->GetName())));
#endif // WITH_EDITOR
return false;
}


//~~~

T2D->SRGB = false;

T2D->CompressionSettings = TC_VectorDisplacementmap;

//Update settings
T2D->UpdateResource();

FTexture2DMipMap& MipsMap = T2D->PlatformData->Mips[0];
int32 TextureWidth = MipsMap.SizeX;
int32 TextureHeight = MipsMap.SizeY;

//Safety check!
if (X >= TextureWidth || Y >= TextureHeight)
{
#if WITH_EDITOR
FMessageLog("PIE").Error(FText::Format(LOCTEXT("Victory_GetPixelFromT2D", "UVictoryBPFunctionLibrary::Victory_GetPixelFromT2D >> X or Y is outside of texture bounds! <3: {0}'"), FText::FromString(FString::FromInt(TextureWidth) + " x " + FString::FromInt(TextureHeight) )));
#endif // WITH_EDITOR
return false;
}

FByteBulkData* RawImageData = &MipsMap.BulkData;

if(!RawImageData)
{
return false;
}

int32 TotalCount = RawImageData->GetElementCount();
if(TotalCount < 1)
{
return false;
}

uint8* RawByteArray = (uint8*)RawImageData->Lock(LOCK_READ_ONLY);

//TC_VectorDisplacementmap UMETA(DisplayName="VectorDisplacementmap (RGBA8)"),
//! 4 because includes alpha <3
/*
for(int32 v = 0; v < TextureWidth * TextureHeight * RawImageData->GetElementSize() * 4; v++)
{
DebugString += FString::FromInt(RawByteArray[v]) + " ";
}
*/

//Texture.cpp
/*
else if (FormatSettings.CompressionSettings == TC_VectorDisplacementmap)
{
TextureFormatName = NameBGRA8;
}
*/

//Get!, converting FColor to FLinearColor
FColor ByteColor;
ByteColor.B = RawByteArray[Y * TextureWidth * 4 + (X * 4) ];
ByteColor.G = RawByteArray[Y * TextureWidth * 4 + (X * 4) + 1];
ByteColor.R = RawByteArray[Y * TextureWidth * 4 + (X * 4) + 2];
ByteColor.A = RawByteArray[Y * TextureWidth * 4 + (X * 4) + 3];

//Set!
PixelColor = ByteColor.ReinterpretAsLinear();

RawImageData->Unlock();

return true;
}


bool UVictoryBPFunctionLibrary::Victory_GetPixelsArrayFromT2D(UTexture2D* T2D, int32& TextureWidth, int32& TextureHeight,TArray<FLinearColor>& PixelArray)
{

if(!T2D)
{
return false;
}

if(T2D->CompressionSettings != TC_VectorDisplacementmap)
{
#if WITH_EDITOR
FMessageLog("PIE").Error(FText::Format(LOCTEXT("Victory_GetPixelFromT2D", "UVictoryBPFunctionLibrary::Victory_GetPixelFromT2D >> Texture Compression must be VectorDisplacementmap <3: {0}'"), FText::FromString(T2D->GetName())));
#endif // WITH_EDITOR
return false;
}

//To prevent overflow in BP if used in a loop
PixelArray.Empty();

T2D->SRGB = false;
T2D->CompressionSettings = TC_VectorDisplacementmap;

//Update settings
T2D->UpdateResource();

FTexture2DMipMap& MyMipMap = T2D->PlatformData->Mips[0];
TextureWidth = MyMipMap.SizeX;
TextureHeight = MyMipMap.SizeY;

FByteBulkData* RawImageData = &MyMipMap.BulkData;

if(!RawImageData)
{
return false;
}

uint8* RawByteArray = (uint8*)RawImageData->Lock(LOCK_READ_ONLY);


for(int32 y = 0; y < TextureHeight; y++)
{
for(int32 x = 0; x < TextureWidth; x++)
{
FColor ByteColor;
ByteColor.B = RawByteArray[y * TextureWidth * 4 + (x * 4) ];
ByteColor.G = RawByteArray[y * TextureWidth * 4 + (x * 4) + 1];
ByteColor.R = RawByteArray[y * TextureWidth * 4 + (x * 4) + 2];
ByteColor.A = RawByteArray[y * TextureWidth * 4 + (x * 4) + 3];

PixelArray.Add(ByteColor.ReinterpretAsLinear());
}
}

RawImageData->Unlock();
return true;
}



Enjoy!

:heart: