UE4初探——从外部导入图片

版本

UE4.26


一、UE4处理图片方式

在UE4中,引擎本身提供了ImagerWrapper 作为所有图片类型的抽象层来处理图片。
导入图片具体步骤为:

  1. 读取文件压缩后的数据CompressedData.方法为FFileHelper::LoadFileToArray(TArray<uint8> &result, const char* filename)

  2. 将压缩数据填充进ImageWrapper的类中.方法为SetCompressed(const void *InCompressedData, int64 InCompressedSize)

  3. 获取未压缩的图片数据RawData.方法为GetRaw(ERGBFormat InFormat, int32 InBitDepth, TArray<uint8> &OutRawData)

  4. 用未压缩的数据复制进输出变量。方法为Fmemory::Memcpy(void *Dest, const void *Src, SIZE_T Count)

二、具体步骤

创建C++类的函数库

(1).h文件

代码如下:

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "IImageWrapper.h"
#include "IImageWrapperModule.h"
#include "CoreMinimal.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "PictureToolsLibaray.generated.h"


/**
 * 
 */
UCLASS()
class PICTURETR_API UPictureToolsLibaray : public UBlueprintFunctionLibrary
{
	GENERATED_BODY()
public:
	UFUNCTION(BlueprintCallable, Category = "PictureTool")
		static bool LoadImageToTexture2D(const FString& ImagePath, UTexture2D*& InTexture, int32& Width, int32& Height);
	
};

这里重点就是public里面的方法

static bool LoadImageToTexture2D(const FString& ImagePath, UTexture2D*& InTexture, int32& Width, int32& Height);

参数依次为: 图片路径+文件名处理后图片输出为纹理图片宽度图片高度

(2).cpp方法实现

  1. 启用引擎自带图片处理模型ImageWrapperModule.
IImageWrapperModule&ImageWrapperModule = FModuleManager::LoadModuleChecked <IImageWrapperModule>(FName("ImageWrapper"));//启用"ImageWrapper"模型
  1. 创建ImageWrapper类,存储图片数据.参数为传入图片类型,这里为PNG
TSharedPtr<IImageWrapper> SourceImageWrapper = ImageWrapperModule.CreateImageWrapper(EImageFormat::PNG);//实例化ImageWrapper类,构造参数为输入图片的类型

:这里的类型在4.16之前为IImageWrapperPtr,在4.16之后改为TSharedPtr<IImageWrapper>,虽然目前仍能使用IImageWrapperPtr但是官方建议使用TSharedPtr<IImageWrapper>

  1. 载入压缩后的图片数据.
TArray<uint8> SourceImageData;	//存储原始图片的颜色信息
FFileHelper::LoadFileToArray(SourceImageData, *ImagePath)
  1. 填充压缩数据进之前的ImageWrapper
SourceImageWrapper->SetCompressed(SourceImageData.GetData(), SourceImageData.GetAllocatedSize())
  1. 获取未压缩颜色数据,UE4所用图片颜色为BGRA 格式,所以这边的ERGBFormatBGRA
Array <uint8> UncompressedBGRA;					//存储未压缩的颜色数据,UE4用的颜色格式为BGRA
SourceImageWrapper->GetRaw(ERGBFormat::BGRA, 8, UncompressedBGRA)
  1. 复制未压缩数据
   Height = SourceImageWrapper->GetHeight();	//获取高度和宽度
   Width = SourceImageWrapper->GetWidth();
   
   /*
   临时填充——应该是先确定图片长宽->再填充颜色数据
   */
   InTexture = UTexture2D::CreateTransient(Width, Height, PF_B8G8R8A8);	
   
   /*
   用自带方法"PlatformData"让 InTexture和指针TextureData绑定(Lock)并且可读可写,
   因为下一行的复制函数中的参数要求为void*
   */
   void* TextureData = InTexture->PlatformData->Mips[0].BulkData.Lock(LOCK_READ_WRITE);	
   
   /*复制,将未压缩的颜色数据和数据大小复制*/
   FMemory::Memcpy(TextureData, UncompressedBGRA.GetData(), UncompressedBGRA.Num());	
   
   InTexture->PlatformData->Mips[0].BulkData.Unlock();//将指针和InTexture解绑(unlock)
   InTexture->UpdateResource();//刷新

(3)完整方法代码

// Fill out your copyright notice in the Description page of Project Settings.


#include "PictureToolsLibaray.h"
bool UPictureToolsLibaray::LoadImageToTexture2D(const FString& ImagePath, UTexture2D*& InTexture, int32& Width, int32& Height) 
{
   TArray<uint8> SourceImageData;	//存储原始图片的颜色信息

   IImageWrapperModule&ImageWrapperModule = FModuleManager::LoadModuleChecked <IImageWrapperModule>(FName("ImageWrapper"));//启用"ImageWrapper"模型
   TSharedPtr<IImageWrapper> SourceImageWrapper = ImageWrapperModule.CreateImageWrapper(EImageFormat::PNG);//实例化ImageWrapper类,构造参数为输入图片的类型

   if (!FPlatformFileManager::Get().GetPlatformFile().FileExists(*ImagePath))//是否存在该文件
   {
   	return false;
   }
   
   if (!FFileHelper::LoadFileToArray(SourceImageData, *ImagePath))//将文件有压缩的文件信息传入SourceImageData
   {
   	return false;
   }

   if (SourceImageWrapper.IsValid() && SourceImageWrapper->SetCompressed(SourceImageData.GetData(), SourceImageData.GetAllocatedSize()))//填充数据进创建的"ImageWrapper"
   {
   	TArray <uint8> UncompressedBGRA;					//存储未压缩的颜色数据,UE4用的颜色格式为BGRA
   	if (SourceImageWrapper->GetRaw(ERGBFormat::BGRA, 8, UncompressedBGRA))//获取未压缩的图片颜色信息
   	{
   		Height = SourceImageWrapper->GetHeight();	//获取高度和宽度
   		Width = SourceImageWrapper->GetWidth();

   		InTexture = UTexture2D::CreateTransient(Width, Height, PF_B8G8R8A8);	//临时填充——应该是先确定图片长宽->再填充颜色数据

   		if (InTexture)
   		{
   			void* TextureData = InTexture->PlatformData->Mips[0].BulkData.Lock(LOCK_READ_WRITE);	//用自带方法"PlatformData"让 InTexture和指针TextureData绑定(Lock)并且可读可写,因为下一行的复制函数中的参数要求为void*
   																									

   			FMemory::Memcpy(TextureData, UncompressedBGRA.GetData(), UncompressedBGRA.Num());	//复制,将未压缩的颜色数据和数据大小复制

   			InTexture->PlatformData->Mips[0].BulkData.Unlock();//将指针和InTexture解绑(unlock)

   			InTexture->UpdateResource();//刷新
   			return true;
   		}
   	}
   }
   return false;

}

参考文献

《大象无形》

B站视频吉叶子


版权声明:本文为qq_43803640原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。