【UE4 C++】 外部图片读取、Texture 保存 png

蓝图版

导入外部图片

file://E:/UE___Projects_Test/MyProjectAAA/Plugins/WXimage.jpg

image

导出图图片

  • 一般导出 .hdr 文件
  • 导出 png 设置一些格式

image


C++ 版

读取外部图片

  • build.cs 添加 ImageWrapper 模块,使用时注意添加相关头文件

    PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "ImageWrapper" });
    
  • 支持图片类型

    • png
    • jpg
    • bmp
    • ico
    • exr
    • icns
  • 注意 jpg 读取后 R 和 B 的通道位置

    • ERGBFormat::RGBA、PF_R8G8B8A8 → ERGBFormat::BGR、PF_B8G8R8A8
  • 代码实现(4.26)

    UENUM(BlueprintType)
    enum class EImgFormat : uint8
    {
    
    	/** Portable Network Graphics. */
    	PNG = 0,
    
    	/** Joint Photographic Experts Group. */
    	JPEG,
    
    	/** Single channel JPEG. */
    	GrayscaleJPEG,
    
    	/** Windows Bitmap. */
    	BMP,
    
    	/** Windows Icon resource. */
    	ICO,
    
    	/** OpenEXR (HDR) image file format. */
    	EXR,
    
    	/** Mac icon. */
    	ICNS
    };
    
    UTexture2D* ADataDriveActor::ImportImage(const FString& path, EImgFormat Type, bool& IsValid, int32& OutWidth, int32& OutHeight)
    {
    	UTexture2D* Texture = nullptr;
    	IsValid = false;
    	// 文件是否存在
    	if (!FPlatformFileManager::Get().GetPlatformFile().FileExists(*path))
    	{
    		return nullptr;
    	}
    	// 图片是否加载
    	TArray<uint8> RawFileData;
    	if (!FFileHelper::LoadFileToArray(RawFileData, *path))
    	{
    		return nullptr;
    	}
    
    	IImageWrapperModule& ImageWrapperModule = FModuleManager::LoadModuleChecked<IImageWrapperModule>(FName("ImageWrapper"));
    	// 自定义枚举转换 EImageFormat
    	// IImageWrapperPtr 变更为 TSharedPtr<IImageWrapper>
    	TSharedPtr<IImageWrapper> ImageWrapper = ImageWrapperModule.CreateImageWrapper(static_cast<EImageFormat>((int8)Type));
    	
    	if (ImageWrapper.IsValid() && ImageWrapper->SetCompressed(RawFileData.GetData(), RawFileData.Num()))
    	{
    		// 此处有所变动 低版本为 const TArray<uint8>* UncompressedRGBA = nullptr;
    		TArray<uint8> UncompressedRGBA ;
    		if (ImageWrapper->GetRaw(ERGBFormat::RGBA, 8, UncompressedRGBA))
    		{
    			Texture = UTexture2D::CreateTransient(ImageWrapper->GetWidth(), ImageWrapper->GetHeight(), PF_R8G8B8A8);
    			if (Texture != nullptr)
    			{
    				IsValid = true;
    				OutWidth = ImageWrapper->GetWidth();
    				OutHeight = ImageWrapper->GetHeight();
    				void* TextureData = Texture->PlatformData->Mips[0].BulkData.Lock(LOCK_READ_WRITE);
    				FMemory::Memcpy(TextureData, UncompressedRGBA.GetData(), UncompressedRGBA.Num());
    				Texture->PlatformData->Mips[0].BulkData.Unlock();
    				Texture->UpdateResource();
    			}
    		}
    	}
    	return Texture;
    }
    

    image

Texture 导出 图片

  • 原博客地址

  • 使用 mip.BulkData.Lock(LOCK_READ_WRITE) 前需要对Texture 设置一些参数,否则会返回 nullptr

    • CompressionSettings set to VectorDisplacementmap
    • MipGenSettings to NoMipmaps
    • SRGB to false
  • 代码实现

    bool ADataDriveActor::ExportImage(UTexture2D* Texture2D, const FString& Path)
    {
    	// setup required parameters
    	TextureCompressionSettings OldCompressionSettings = Texture2D->CompressionSettings;
    	TextureMipGenSettings OldMipGenSettings = Texture2D->MipGenSettings;
    	bool OldSRGB = Texture2D->SRGB;
    
    	Texture2D->CompressionSettings = TextureCompressionSettings::TC_VectorDisplacementmap;
    	Texture2D->MipGenSettings = TextureMipGenSettings::TMGS_NoMipmaps;
    	Texture2D->SRGB = false;
    	Texture2D->UpdateResource();
    
    	FTexture2DMipMap& mipmap = Texture2D->PlatformData->Mips[0];
    	uint8* Data = (uint8*)mipmap.BulkData.Lock(LOCK_READ_WRITE);
    	//FColor* FormatedImageData = static_cast<FColor*>(mipmap.BulkData.Lock(LOCK_READ_WRITE));
    	if (Data == nullptr)
    	{
    		mipmap.BulkData.Unlock(); // 不释放,会卡住
    		Texture2D->UpdateResource();
    		return false;
    	}
    
    	int width = Texture2D->PlatformData->SizeX;
    	int height = Texture2D->PlatformData->SizeY;
    	TArray<FColor> nColors;
    
    	for (int32 y = 0; y < height; y++)
    	{
    		for (int32 x = 0; x < width; x++)
    		{
    			FColor bColor;
    			bColor.B = Data[(y * width + x) * 4 + 0];//B 0 - 255
    			bColor.G = Data[(y * width + x) * 4 + 1];//G
    			bColor.R = Data[(y * width + x) * 4 + 2];//R
    			bColor.A = Data[(y * width + x) * 4 + 3];//A 
    			nColors.Add(bColor);
    		}
    	}
    	mipmap.BulkData.Unlock();
    
    	// return old parameters
    	Texture2D->CompressionSettings = OldCompressionSettings;
    	Texture2D->MipGenSettings = OldMipGenSettings;
    	Texture2D->SRGB = OldSRGB;
    
    	Texture2D->UpdateResource();
    
    	//获取 uint8 数据,保存
    	TArray<uint8> ImgData;
    	FImageUtils::CompressImageArray(width, height, nColors, ImgData);
    	return FFileHelper::SaveArrayToFile(ImgData, *Path);
    }
    

    image

posted @ 2021-05-13 22:53  砥才人  阅读(6760)  评论(0编辑  收藏  举报