UFUNCTION(BlueprintCallable,BlueprintPure)
static TArray<FColor> GetMediaTexturePixels(UMediaTexture* MyMediaTexture)
{
TArray<FColor> PixelColorsArr;
UTexture2D* UT2 = MediaTextureToTexture2D(MyMediaTexture);
const FColor* const Colors = static_cast<FColor*>(UT2->PlatformData->Mips[0].BulkData.Lock(LOCK_READ_ONLY));
uint16 OutX = UT2->GetSizeX();
uint16 OutY = UT2->GetSizeY();
for(int i = 0; i < OutY; i++)
{
for(int j = 0; j < OutX; j++)
{
FColor PixelColor = Colors[i * OutX + j];
PixelColorsArr.Add(PixelColor);
}
}
UT2->PlatformData->Mips[0].BulkData.Unlock();
return PixelColorsArr;
}
UFUNCTION(BlueprintCallable,BlueprintPure)
static UTexture2D* MediaTextureToTexture2D(UMediaTexture* MyMediaTexture)
{
check(IsInGameThread());
TArray<FColor> OutColors;
FMediaTextureResource* MediaTextureResource = static_cast<FMediaTextureResource*>(MyMediaTexture->GetResource());
MediaTextureResource->ReadPixels(OutColors);
UTexture2D* NewTexture2D = nullptr;
void* TextureData = nullptr;
const int32 ImageWidth = MyMediaTexture->GetWidth();
const int32 ImageHeight = MyMediaTexture->GetHeight();
UE_LOG(LogTemp, Warning, TEXT("ImageWidth:%d"), ImageWidth);
UE_LOG(LogTemp, Warning, TEXT("ImageHeight:%d"), ImageHeight);
NewTexture2D = UTexture2D::CreateTransient(ImageWidth, ImageHeight, PF_B8G8R8A8, FName(TEXT("测试贴图")));
FTexture2DMipMap& Mipmap = NewTexture2D->GetPlatformData()->Mips[0];
TextureData = Mipmap.BulkData.Lock(LOCK_READ_WRITE);
FMemory::Memcpy(TextureData, OutColors.GetData(), OutColors.Num() * 4);
Mipmap.BulkData.Unlock();
NewTexture2D->UpdateResource();
Mipmap.BulkData.Unlock();
return NewTexture2D;
}
这里有两个类型的像素
一个是UTexture2D的像素
二是UMediaTexture的像素
static FColor GetScreenPositionColor(POINT P)
{
Windows::HDC hdc = ::GetDC(NULL);
COLORREF Color = ::GetPixel(hdc, P.x, P.y);
int R = GetRValue(Color);
int G = GetGValue(Color);
int B = GetBValue(Color);
::ReleaseDC(NULL, hdc);
FColor realColor = FColor(R, G, B);
return realColor;
}
UFUNCTION(BlueprintCallable)
static TArray<FColor> GetScreenColors()
{
TArray<FColor> ScreenColors;
for(int y = 0; y < 1080; y++)
{
for(int x = 0; x < 1920; x++)
{
ScreenColors.Add(GetScreenPositionColor(POINT{x, y}));
}
}
return ScreenColors;
}
这里使用Windows的HDC来获取屏幕中所有像素,这个不适合获取屏幕上所有像素,速度很慢,适合做取色器来获取其中鼠标中的一个像素
UFUNCTION(BlueprintCallable)
static TArray<FColor> GetPixelsFromSceneCapture(USceneCaptureComponent2D* scc)
{
TArray<FColor> Pixels;
scc->TextureTarget->GameThread_GetRenderTargetResource()->ReadPixels(Pixels);
return Pixels;
}
获取场景捕获器中,捕获的RT中所有的像素