UTexture2D* ULRRTextureManager::GetTexture(FString path, bool alpha) { TArray<uint8> RawFileData; FFileHelper::LoadFileToArray(RawFileData, *path, 0); if (RawFileData.Num() != 0) { IImageWrapperModule& ImageWrapperModule = FModuleManager::LoadModuleChecked<IImageWrapperModule>(FName(TEXT("ImageWrapper"))); // Note: PNG format. Other formats are supported IImageWrapperPtr ImageWrapper = ImageWrapperModule.CreateImageWrapper(EImageFormat::BMP); if (ImageWrapper.IsValid() && ImageWrapper->SetCompressed(RawFileData.GetData(), RawFileData.Num())) { const TArray<uint8>* UncompressedBGRA = nullptr; TArray<uint8> UncompressedRGBA; if (ImageWrapper->GetRaw(ERGBFormat::BGRA, 8, UncompressedBGRA)) { // Create the UTexture for rendering UncompressedRGBA.AddZeroed(UncompressedBGRA->Num()); for (int i = 0; UncompressedBGRA->Num() > i; i += 4) { UncompressedRGBA[i] = (*UncompressedBGRA)[i + 2]; UncompressedRGBA[i + 1] = (*UncompressedBGRA)[i + 1]; UncompressedRGBA[i + 2] = (*UncompressedBGRA)[i]; UncompressedRGBA[i + 3] = (*UncompressedBGRA)[i + 3]; if (alpha) { if ((UncompressedRGBA[i] + UncompressedRGBA[i + 1] + UncompressedRGBA[i + 2]) < 3) { UncompressedRGBA[i + 3] = 0; } } } UTexture2D* MyTexture = UTexture2D::CreateTransient(ImageWrapper->GetWidth(), ImageWrapper->GetHeight(), PF_R8G8B8A8); // Fill in the source data from the file uint8* TextureData = (uint8*)MyTexture->PlatformData->Mips[0].BulkData.Lock(LOCK_READ_WRITE); FMemory::Memcpy(TextureData, UncompressedRGBA.GetData(), UncompressedRGBA.Num()); MyTexture->PlatformData->Mips[0].BulkData.Unlock(); // Update the rendering resource from data. MyTexture->UpdateResource(); return MyTexture; } } } return nullptr; }
TSharedPtr< FSlateDynamicImageBrush > FEpicSurvey::LoadRawDataAsBrush( FName ResourceName, const TArray< uint8 >& RawData ) const { TSharedPtr< FSlateDynamicImageBrush > Brush; uint32 BytesPerPixel = 4; int32 Width = 0; int32 Height = 0; bool bSucceeded = false; TArray<uint8> DecodedImage; IImageWrapperModule& ImageWrapperModule = FModuleManager::LoadModuleChecked<IImageWrapperModule>( FName("ImageWrapper") ); IImageWrapperPtr ImageWrapper = ImageWrapperModule.CreateImageWrapper( EImageFormat::PNG ); if ( ImageWrapper.IsValid() && ImageWrapper->SetCompressed( RawData.GetData(), RawData.Num() ) ) { Width = ImageWrapper->GetWidth(); Height = ImageWrapper->GetHeight(); const TArray<uint8>* RawImageData = NULL; if (ImageWrapper->GetRaw(ERGBFormat::BGRA, 8, RawImageData)) { DecodedImage.AddUninitialized( Width * Height * BytesPerPixel ); DecodedImage = *RawImageData; bSucceeded = true; } } if ( bSucceeded ) { Brush = FSlateDynamicImageBrush::CreateWithImageData( ResourceName, FVector2D(ImageWrapper->GetWidth(), ImageWrapper->GetHeight()), DecodedImage ); } return Brush; }
void FTextureSource::Compress() { if (CanPNGCompress()) { uint8* BulkDataPtr = (uint8*)BulkData.Lock(LOCK_READ_WRITE); IImageWrapperModule& ImageWrapperModule = FModuleManager::LoadModuleChecked<IImageWrapperModule>( FName("ImageWrapper") ); IImageWrapperPtr ImageWrapper = ImageWrapperModule.CreateImageWrapper( EImageFormat::PNG ); // TODO: TSF_BGRA8 is stored as RGBA, so the R and B channels are swapped in the internal png. Should we fix this? ERGBFormat::Type RawFormat = (Format == TSF_G8) ? ERGBFormat::Gray : ERGBFormat::RGBA; if ( ImageWrapper.IsValid() && ImageWrapper->SetRaw( BulkDataPtr, BulkData.GetBulkDataSize(), SizeX, SizeY, RawFormat, Format == TSF_RGBA16 ? 16 : 8 ) ) { const TArray<uint8>& CompressedData = ImageWrapper->GetCompressed(); if ( CompressedData.Num() > 0 ) { BulkDataPtr = (uint8*)BulkData.Realloc(CompressedData.Num()); FMemory::Memcpy(BulkDataPtr, CompressedData.GetTypedData(), CompressedData.Num()); BulkData.Unlock(); bPNGCompressed = true; BulkData.StoreCompressedOnDisk(ECompressionFlags::COMPRESS_None); } } } else { //Can't PNG compress so just zlib compress the lot when its serialized out to disk. BulkData.StoreCompressedOnDisk(ECompressionFlags::COMPRESS_ZLIB); } }
TSharedPtr<FSlateDynamicImageBrush> FNewsFeedCache::RawDataToBrush( FName ResourceName, const TArray< uint8 >& InRawData ) const { TSharedPtr<FSlateDynamicImageBrush> Brush; uint32 BytesPerPixel = 4; int32 Width = 0; int32 Height = 0; bool bSucceeded = false; TArray<uint8> DecodedImage; IImageWrapperModule& ImageWrapperModule = FModuleManager::LoadModuleChecked<IImageWrapperModule>(FName("ImageWrapper")); IImageWrapperPtr ImageWrapper = ImageWrapperModule.CreateImageWrapper( EImageFormat::PNG ); if (ImageWrapper.IsValid() && ImageWrapper->SetCompressed(InRawData.GetData(), InRawData.Num())) { Width = ImageWrapper->GetWidth(); Height = ImageWrapper->GetHeight(); const TArray<uint8>* RawData = NULL; if (ImageWrapper->GetRaw( ERGBFormat::BGRA, 8, RawData)) { DecodedImage.AddUninitialized( Width * Height * BytesPerPixel ); DecodedImage = *RawData; bSucceeded = true; } } if (bSucceeded && FSlateApplication::Get().GetRenderer()->GenerateDynamicImageResource(ResourceName, ImageWrapper->GetWidth(), ImageWrapper->GetHeight(), DecodedImage)) { Brush = MakeShareable(new FSlateDynamicImageBrush(ResourceName, FVector2D(ImageWrapper->GetWidth(), ImageWrapper->GetHeight()))); } return Brush; }
TSharedPtr<FSlateDynamicImageBrush> FContentSourceViewModel::CreateBrushFromRawData(FString ResourceNamePrefix, const TArray< uint8 >& RawData) const { TSharedPtr< FSlateDynamicImageBrush > Brush; uint32 BytesPerPixel = 4; int32 Width = 0; int32 Height = 0; bool bSucceeded = false; TArray<uint8> DecodedImage; IImageWrapperModule& ImageWrapperModule = FModuleManager::LoadModuleChecked<IImageWrapperModule>(FName("ImageWrapper")); IImageWrapperPtr ImageWrapper = ImageWrapperModule.CreateImageWrapper(EImageFormat::PNG); if (ImageWrapper.IsValid() && (RawData.Num() > 0) && ImageWrapper->SetCompressed(RawData.GetData(), RawData.Num())) { Width = ImageWrapper->GetWidth(); Height = ImageWrapper->GetHeight(); const TArray<uint8>* RawImageData = NULL; if (ImageWrapper->GetRaw(ERGBFormat::BGRA, 8, RawImageData)) { DecodedImage.AddUninitialized(Width * Height * BytesPerPixel); DecodedImage = *RawImageData; bSucceeded = true; } } if (bSucceeded) { FString UniqueResourceName = ResourceNamePrefix + "_" + FString::FromInt(ImageID++); Brush = FSlateDynamicImageBrush::CreateWithImageData(FName(*UniqueResourceName), FVector2D(ImageWrapper->GetWidth(), ImageWrapper->GetHeight()), DecodedImage); } return Brush; }
uint8* FTextureSource::LockMip(int32 MipIndex) { uint8* MipData = NULL; if (MipIndex < NumMips) { if (LockedMipData == NULL) { LockedMipData = (uint8*)BulkData.Lock(LOCK_READ_WRITE); if (bPNGCompressed) { bool bCanPngCompressFormat = (Format == TSF_G8 || Format == TSF_RGBA8 || Format == TSF_BGRA8 || Format == TSF_RGBA16); check(NumSlices == 1 && bCanPngCompressFormat); if (MipIndex != 0) { return NULL; } IImageWrapperModule& ImageWrapperModule = FModuleManager::LoadModuleChecked<IImageWrapperModule>( FName("ImageWrapper") ); IImageWrapperPtr ImageWrapper = ImageWrapperModule.CreateImageWrapper( EImageFormat::PNG ); if ( ImageWrapper.IsValid() && ImageWrapper->SetCompressed( LockedMipData, BulkData.GetBulkDataSize() ) ) { check( ImageWrapper->GetWidth() == SizeX ); check( ImageWrapper->GetHeight() == SizeY ); const TArray<uint8>* RawData = NULL; // TODO: TSF_BGRA8 is stored as RGBA, so the R and B channels are swapped in the internal png. Should we fix this? ERGBFormat::Type RawFormat = (Format == TSF_G8) ? ERGBFormat::Gray : ERGBFormat::RGBA; if (ImageWrapper->GetRaw( RawFormat, Format == TSF_RGBA16 ? 16 : 8, RawData )) { if (RawData->Num() > 0) { LockedMipData = (uint8*)FMemory::Malloc(RawData->Num()); // PVS-Studio does not understand that IImageWrapper::GetRaw's return value validates the pointer, so we disable // the warning that we are using the RawData pointer before checking for null: FMemory::Memcpy(LockedMipData, RawData->GetData(), RawData->Num()); //-V595 } } if (RawData == NULL || RawData->Num() == 0) { UE_LOG(LogTexture, Warning, TEXT("PNG decompression of source art failed")); } } else { UE_LOG(LogTexture, Log, TEXT("Only pngs are supported")); } } } MipData = LockedMipData + CalcMipOffset(MipIndex); LockedMips |= (1 << MipIndex); } return MipData; }
/** * Loads a UTexture2D from a package and stores it in the cache * * @param TextureName The name of the texture to load */ bool FSlateRHIResourceManager::LoadTexture( const FName& TextureName, const FString& ResourcePath, uint32& Width, uint32& Height, TArray<uint8>& DecodedImage ) { check( IsThreadSafeForSlateRendering() ); bool bSucceeded = true; uint32 BytesPerPixel = 4; TArray<uint8> RawFileData; if( FFileHelper::LoadFileToArray( RawFileData, *ResourcePath ) ) { IImageWrapperModule& ImageWrapperModule = FModuleManager::LoadModuleChecked<IImageWrapperModule>( FName("ImageWrapper") ); IImageWrapperPtr ImageWrapper = ImageWrapperModule.CreateImageWrapper( EImageFormat::PNG ); if ( ImageWrapper.IsValid() && ImageWrapper->SetCompressed( RawFileData.GetData(), RawFileData.Num() ) ) { Width = ImageWrapper->GetWidth(); Height = ImageWrapper->GetHeight(); const TArray<uint8>* RawData = NULL; if (ImageWrapper->GetRaw( ERGBFormat::BGRA, 8, RawData)) { DecodedImage.AddUninitialized( Width*Height*BytesPerPixel ); DecodedImage = *RawData; } else { UE_LOG(LogSlate, Log, TEXT("Invalid texture format for Slate resource only RGBA and RGB pngs are supported: %s"), *TextureName.ToString() ); bSucceeded = false; } } else { UE_LOG(LogSlate, Log, TEXT("Only pngs are supported in Slate")); bSucceeded = false; } } else { UE_LOG(LogSlate, Log, TEXT("Could not find file for Slate resource: %s"), *TextureName.ToString() ); bSucceeded = false; } return bSucceeded; }
bool FSlateD3DTextureManager::LoadTexture( const FSlateBrush& InBrush, uint32& OutWidth, uint32& OutHeight, TArray<uint8>& OutDecodedImage ) { FString ResourcePath = GetResourcePath( InBrush ); uint32 BytesPerPixel = 4; bool bSucceeded = true; TArray<uint8> RawFileData; if( FFileHelper::LoadFileToArray( RawFileData, *ResourcePath ) ) { IImageWrapperModule& ImageWrapperModule = FModuleManager::LoadModuleChecked<IImageWrapperModule>( FName("ImageWrapper") ); IImageWrapperPtr ImageWrapper = ImageWrapperModule.CreateImageWrapper( EImageFormat::PNG ); if ( ImageWrapper.IsValid() && ImageWrapper->SetCompressed( RawFileData.GetData(), RawFileData.Num() ) ) { OutWidth = ImageWrapper->GetWidth(); OutHeight = ImageWrapper->GetHeight(); const TArray<uint8>* RawData = NULL; if (ImageWrapper->GetRaw(ERGBFormat::RGBA, 8, RawData) == false) { UE_LOG(LogSlateD3D, Log, TEXT("Invalid texture format for Slate resource only RGBA and RGB pngs are supported: %s"), *InBrush.GetResourceName().ToString() ); bSucceeded = false; } else { OutDecodedImage = *RawData; } } else { UE_LOG(LogSlateD3D, Log, TEXT("Only pngs are supported in Slate")); bSucceeded = false; } } else { UE_LOG(LogSlateD3D, Log, TEXT("Could not find file for Slate resource: %s"), *InBrush.GetResourceName().ToString() ); bSucceeded = false; } return bSucceeded; }
void FSSTBatchCombinerModule::PluginButtonClicked() { TArray<FString> OutFileNames; TArray<FString> OutFileNames2; FDesktopPlatformModule::Get()->OpenFileDialog(nullptr, "select First Image Files", "", "", "Image Files (*.png)|*.png", 1, OutFileNames); FDesktopPlatformModule::Get()->OpenFileDialog(nullptr, "select Second Image Files", "", "", "Image Files (*.png)|*.png", 1, OutFileNames2); if (OutFileNames.Num() && OutFileNames2.Num()) { if (OutFileNames.Num() != OutFileNames2.Num()) { FString DialogText = "Error! first set quantity does not match second set!"; FMessageDialog::Open(EAppMsgType::Ok, FText::FromString(DialogText)); return; } IImageWrapperModule& ImageWrapperModule = FModuleManager::LoadModuleChecked<IImageWrapperModule>(FName("ImageWrapper")); for (int32 i = 0; i < OutFileNames.Num(); i++) { TArray<uint8> RawFileData; TArray<uint8> RawFileData2; if (FFileHelper::LoadFileToArray(RawFileData, *OutFileNames[i]) && FFileHelper::LoadFileToArray(RawFileData2, *OutFileNames2[i])) { IImageWrapperPtr ImageWrapper = ImageWrapperModule.CreateImageWrapper(EImageFormat::PNG); IImageWrapperPtr ImageWrapper2 = ImageWrapperModule.CreateImageWrapper(EImageFormat::PNG); if (ImageWrapper.IsValid() && ImageWrapper->SetCompressed(RawFileData.GetData(), RawFileData.Num()) && ImageWrapper2.IsValid() && ImageWrapper2->SetCompressed(RawFileData2.GetData(), RawFileData2.Num())) { const TArray<uint8>* RawData = nullptr; const TArray<uint8>* RawData2 = nullptr; if (ImageWrapper->GetRaw(ERGBFormat::BGRA, ImageWrapper->GetBitDepth(), RawData) && ImageWrapper2->GetRaw(ERGBFormat::BGRA, ImageWrapper2->GetBitDepth(), RawData2)) { uint32 ImageWidth = ImageWrapper->GetWidth(); uint32 ImageHeight = ImageWrapper->GetHeight(); uint32 ImageWidth2 = ImageWrapper2->GetWidth(); uint32 ImageHeight2 = ImageWrapper2->GetHeight(); if ((ImageWidth != ImageWidth2) || (ImageHeight != ImageHeight2)) { FString DialogText = "Error! Image dimensions do not match for frame " + FString::FromInt(i); FMessageDialog::Open(EAppMsgType::Ok, FText::FromString(DialogText)); return; } TArray<uint8> newdata; newdata = *RawData; for (int32 a = 0; a < RawData->Num() - 4; a = a + 4) { newdata[a + 1] = (*RawData2)[a]; } //save ImageWrapper->SetRaw(newdata.GetData(), newdata.GetAllocatedSize(), ImageWidth, ImageHeight, ERGBFormat::BGRA, 8); const TArray<uint8>& PNGData = ImageWrapper->GetCompressed(100); FFileHelper::SaveArrayToFile(PNGData, *OutFileNames[i]); } //if imagewrapper.getraw } //if imagewrapper.valid } //if load file }// for files loop } //if files }
bool FTextureSource::GetMipData(TArray<uint8>& OutMipData, int32 MipIndex) { bool bSuccess = false; if (MipIndex < NumMips && BulkData.GetBulkDataSize() > 0) { void* RawSourceData = BulkData.Lock(LOCK_READ_ONLY); if (bPNGCompressed) { bool bCanPngCompressFormat = (Format == TSF_G8 || Format == TSF_RGBA8 || Format == TSF_BGRA8 || Format == TSF_RGBA16); if (MipIndex == 0 && NumSlices == 1 && bCanPngCompressFormat) { IImageWrapperModule& ImageWrapperModule = FModuleManager::LoadModuleChecked<IImageWrapperModule>( FName("ImageWrapper") ); IImageWrapperPtr ImageWrapper = ImageWrapperModule.CreateImageWrapper( EImageFormat::PNG ); if ( ImageWrapper.IsValid() && ImageWrapper->SetCompressed( RawSourceData, BulkData.GetBulkDataSize() ) ) { if (ImageWrapper->GetWidth() == SizeX && ImageWrapper->GetHeight() == SizeY) { const TArray<uint8>* RawData = NULL; // TODO: TSF_BGRA8 is stored as RGBA, so the R and B channels are swapped in the internal png. Should we fix this? ERGBFormat::Type RawFormat = (Format == TSF_G8) ? ERGBFormat::Gray : ERGBFormat::RGBA; if (ImageWrapper->GetRaw( RawFormat, Format == TSF_RGBA16 ? 16 : 8, RawData )) { OutMipData = *RawData; bSuccess = true; } else { UE_LOG(LogTexture, Warning, TEXT("PNG decompression of source art failed")); OutMipData.Empty(); } } else { UE_LOG(LogTexture, Warning, TEXT("PNG decompression of source art failed. ") TEXT("Source image should be %dx%d but is %dx%d"), SizeX, SizeY, ImageWrapper->GetWidth(), ImageWrapper->GetHeight() ); } } else { UE_LOG(LogTexture, Log, TEXT("Only pngs are supported")); } } } else { int32 MipOffset = CalcMipOffset(MipIndex); int32 MipSize = CalcMipSize(MipIndex); if (BulkData.GetBulkDataSize() >= MipOffset + MipSize) { OutMipData.Empty(MipSize); OutMipData.AddUninitialized(MipSize); FMemory::Memcpy( OutMipData.GetTypedData(), (uint8*)RawSourceData + MipOffset, MipSize ); } bSuccess = true; } BulkData.Unlock(); } return bSuccess; }