Unreal Engine 5 C++(C#)开发:使用蓝图库实现插件(四)GetImageWrapperByExtention

时间:2024-10-29 08:03:36

目录

引言

一、IImageWrapper

二、返回类型TSharedPtr

 三、GetImageWrapperByExtention的实现

3.1IImageWrapperModule

 3.2加载ImageWrapperModule

3.3EImageFormat 

3.3根据文件后缀来创建IImageWrapper接口实例


引言

static TSharedPtr<IImageWrapper> GetImageWrapperByExtention(const FString InImagePath);

经过前之前的学习和了解,我们已经可以大致了解了一个蓝图类插件的主要构成框架,以及如何将我们在VS中实现的代码转换成接口从而暴露在UE引擎中,从而提供给非变成人员,比如建模师,地编来直接调用我们的static静态函数从而在UE中可以直接运用它。

本次在我们自己的UTextureReaderBPLibrary实现一个函数GetImageWrapperByExtention用于通过文件后缀创建一个IImageWrapper类型的智能指针。

一、IImageWrapper

IImageWrapper是虚幻引擎(Unreal Engine,简称UE)中的一个接口,它定义了一个用于图像处理的通用接口。

一、定义与功能

IImageWrapper是一个接口类,它提供了一套用于处理图像数据的标准方法和属性。这些方法和属性允许开发者在不依赖于具体图像格式的情况下,对图像数据进行读取、转换、压缩和解压缩等操作

二、核心功能

  1. 图像数据读取:IImageWrapper能够读取多种格式的图像文件,并将其转换为引擎内部可处理的图像数据格式。
  2. 数据转换与压缩:它支持将图像数据从一种格式转换为另一种格式,例如从压缩格式转换为原始RGB格式。同时,它也支持对图像数据进行压缩和解压缩操作。
  3. 元数据管理:IImageWrapper还负责管理图像的元数据,如图像的宽度、高度、颜色深度等,这些信息对于后续的图像处理至关重要。

三、应用场景

  1. 纹理创建与更新:在UE中,IImageWrapper经常与UTexture2D类一起使用。开发者可以利用IImageWrapper读取和处理图像数据,然后将其填充到UTexture2D对象中,从而创建或更新纹理。
  2. 图像处理插件开发:对于需要处理图像的插件开发者来说,IImageWrapper提供了一个强大的接口。通过实现这个接口,开发者可以创建自己的图像处理插件,支持多种图像格式和复杂的图像处理算法。
  3. 游戏开发中的图像处理:在游戏开发过程中,经常需要对图像进行各种处理,如调整大小、裁剪、旋转等。IImageWrapper为这些操作提供了统一和便捷的接口,使得开发者能够更加高效地处理图像数据。

四、实现与使用

在UE中,IImageWrapper通常通过模块接口IImageWrapperModule来加载和使用。开发者需要先加载IImageWrapperModule模块,然后使用该模块提供的CreateImageWrapper方法来创建IImageWrapper对象。创建完成后,开发者就可以利用IImageWrapper提供的接口来处理图像数据了。

五、注意事项

  1. 内存管理:在使用IImageWrapper处理图像数据时,需要注意内存管理。特别是在处理大型图像文件时,要确保及时释放内存资源,避免内存泄漏。
  2. 线程安全:在多线程环境下使用IImageWrapper时,需要注意线程安全问题。例如,在访问共享资源时需要使用锁机制来确保线程安全。
  3. 格式支持:虽然IImageWrapper支持多种图像格式,但在实际使用时仍需注意格式支持情况。如果引擎不支持某种格式,则需要使用其他工具进行转换或寻找替代方案。

二、返回类型TSharedPtr

TSharedPtr是虚幻引擎(Unreal Engine,简称UE)中提供的一种智能指针类型,属于其智能指针库的一部分。以下是对TSharedPtr的详细解释:

一、定义与功能

TSharedPtr是一种共享智能指针,用于管理在多个对象间共享所有权的指针。它使用引用计数来控制对象的生命周期,当最后一个持有的TSharedPtr被销毁时,对象才会被释放。这有助于自动管理内存,减少内存泄漏的风险。

二、模板参数

TSharedPtr是一个模板类,其模板参数主要包括ObjectType和Mode。其中,ObjectType指代原始对象的类型,而Mode是一个枚举类,表明智能指针的操作是否需要线程安全。

三、主要特性

  1. 线程安全:TSharedPtr提供了线程安全的版本,可以在多线程环境下安全地使用。
  2. 引用计数:通过引用计数来管理对象的生命周期,当引用计数降为零时,对象会被自动释放。
  3. 空指针检查:提供了IsValid方法用于检查指针是否有效,避免了空指针访问导致的崩溃。
  4. 智能转换:TSharedPtr可以与其他智能指针类型(如TSharedRef和TWeakPtr)进行转换,但需要注意转换的规则和条件。

四、使用方法

  1. 创建TSharedPtr:可以使用MakeShareable函数或TSharedPtr的构造函数来创建TSharedPtr对象。例如:
    TSharedPtr<MyStruct> mySharedPtr = MakeShareable(new MyStruct());
  2. 访问对象:通过TSharedPtr的箭头操作符(->)或星号操作符(*)来访问所指向的对象。例如:
    mySharedPtr->SomeMethod();  
    MyStruct& myStructRef = *mySharedPtr;
  3. 判断有效性:使用IsValid方法来检查TSharedPtr是否有效。例如:
    if (mySharedPtr.IsValid()) {  
        // Do something with mySharedPtr  
    }
  4. 重置指针:使用Reset方法来重置TSharedPtr,使其不再指向任何对象。例如:
    mySharedPtr.Reset();

    五、注意事项

  5. 循环引用:在使用TSharedPtr时,需要注意避免循环引用导致的内存泄漏。可以通过使用TWeakPtr来打破循环引用。
  6. 性能考虑:虽然TSharedPtr提供了自动内存管理的功能,但在频繁创建和销毁大量对象时,引用计数的增减可能会带来一定的性能开销。因此,在性能敏感的场景中需要谨慎使用。
  7. 适用场景:TSharedPtr适用于多个对象需要共享数据且希望自动管理其生命周期的场景。但对于UObject类型的对象,由于UE的垃圾回收系统已经管理了其生命周期,因此不应使用TSharedPtr来管理UObject类型的对象。

 三、GetImageWrapperByExtention的实现

在TextureReaderBPLibrary.h中对此函数进行声明以后,我们就可以在TextureReaderBPLibrary.cpp中对其进行实现。接下来博主将会对此段代码中的各个进行详细的拆解。

TSharedPtr<IImageWrapper> UTextureReaderBPLibrary::GetImageWrapperByExtention(const FString InImagePath)
{
	IImageWrapperModule& ImageWrapperModule = FModuleManager::LoadModuleChecked<IImageWrapperModule>(FName("ImageWrapper"));
	if (InImagePath.EndsWith(".png"))
	{
		return ImageWrapperModule.CreateImageWrapper(EImageFormat::PNG);
	}
	else if (InImagePath.EndsWith(".jpg")||InImagePath.EndsWith("jpeg"))
	{
		return ImageWrapperModule.CreateImageWrapper(EImageFormat::JPEG);
	}
	else if (InImagePath.EndsWith(".bmp"))
	{
		return ImageWrapperModule.CreateImageWrapper(EImageFormat::BMP);
	}
	else if (InImagePath.EndsWith(".ico"))
	{
		return ImageWrapperModule.CreateImageWrapper(EImageFormat::ICO);
	}
	else if (InImagePath.EndsWith(".exr") )
	{
		return ImageWrapperModule.CreateImageWrapper(EImageFormat::EXR);
	}
	else if (InImagePath.EndsWith(".icns"))
	{
		return ImageWrapperModule.CreateImageWrapper(EImageFormat::ICNS);
	}

	return nullptr;
}

3.1IImageWrapperModule

IImageWrapperModule是Unreal Engine(虚幻引擎)中的一个模块接口,它定义了一个名为IImageWrapperModule的接口。这个接口在Unreal Engine的图像处理系统中扮演着重要角色,为不同类型的图像数据提供了一个统一的访问和操作方式。

具体来说,IImageWrapperModule接口的主要功能包括:

  1. 图像加载与保存:通过该接口,可以加载和保存不同格式的图像文件,如PNG、JPEG等。这使得开发者能够在不依赖于具体图像格式的情况下,轻松地处理图像数据。
  2. 图像格式转换:IImageWrapperModule支持将图像数据从一种格式转换为另一种格式,例如从压缩的图像数据转换为原始的RGBA数据,或者从一种颜色空间转换为另一种颜色空间。
  3. 图像处理:该接口还提供了一系列图像处理功能,如图像缩放、裁剪、旋转等。这些功能使得开发者能够在加载图像后对其进行必要的处理,以满足游戏或应用程序的需求。

在Unreal Engine中,IImageWrapperModule通常与IImageWrapper接口一起使用。IImageWrapper是一个用于图像处理的通用接口,它定义了处理图像数据所需的各种方法。而IImageWrapperModule则负责创建和管理IImageWrapper对象以及提供与图像格式相关的功能

为了使用IImageWrapperModule和IImageWrapper接口,开发者需要在项目中包含相应的头文件,并在.build.cs文件中添加对ImageWrapper模块的依赖(之前在.build.cs中添加此模块的原因)。然后,就可以通过调用IImageWrapperModule的方法来加载、保存和处理图像数据了。

总的来说,IImageWrapperModule是Unreal Engine中一个非常重要的接口,它为开发者提供了一个强大且灵活的图像处理系统。通过使用该接口,开发者可以轻松地处理各种格式的图像数据,并将其应用于游戏或应用程序中。

 3.2加载ImageWrapperModule

IImageWrapperModule& ImageWrapperModule = FModuleManager::LoadModuleChecked<IImageWrapperModule>(FName("ImageWrapper"));
  • IImageWrapperModule& ImageWrapperModule
    • 这部分声明了一个对IImageWrapperModule类型的引用,命名为ImageWrapperModule
    • 意味着ImageWrapperModule将直接引用(或“指向”)一个IImageWrapperModule类型的对象,而不是复制该对象。
    • 通过引用,你可以直接操作被引用的对象,而无需复制数据,这通常更高效。
  • FModuleManager::LoadModuleChecked<IImageWrapperModule>(FName("ImageWrapper"))
    • 这部分是调用FModuleManager类的静态成员函数LoadModuleChecked,并传递了两个参数。
    • FModuleManager是Unreal Engine中用于管理模块加载和卸载的类。
    • <IImageWrapperModule>是模板参数,指定了要加载的模块的类型,即IImageWrapperModule
    • FName("ImageWrapper")是传递给LoadModuleChecked函数的第一个参数,它是一个FName类型的对象,表示要加载的模块的名称。FName是Unreal Engine中用于存储字符串的类,它优化了字符串的比较和存储。
    • LoadModuleChecked函数的作用是加载指定名称和类型的模块,并返回一个对该模块接口的引用。如果模块无法加载(例如,模块不存在或加载失败),该函数将抛出一个异常。

3.3EImageFormat 

EImageFormat 是一个在图像处理、游戏开发或类似领域中常用的枚举(Enumeration)类型,特别是在使用Unreal Engine(UE)等游戏引擎时。它定义了一系列的图像格式,这些格式通常用于指示图像数据的存储方式、编码方式或颜色深度等信息。

EImageFormat 枚举中通常包含多个成员,每个成员都代表一种特定的图像格式。在Unreal Engine中,EImageFormat 可能包含以下成员:

  • PNG:表示Portable Network Graphics格式,是一种无损压缩的图像格式,常用于网页和图像存档。
  • JPEG:表示Joint Photographic Experts Group格式,是一种有损压缩的图像格式,常用于照片和图像压缩。
  • BMP:表示Bitmap格式,是一种未压缩的图像格式,常用于Windows操作系统中的图像存储。
  • GIF:表示Graphics Interchange Format格式,是一种无损压缩的图像格式,支持动画和透明背景。
  • TIFF:表示Tagged Image File Format格式,是一种灵活的图像存储格式,常用于高质量图像打印和存档。
  • 其他格式:可能还包括其他专有或特定用途的图像格式,如PSD(Photoshop Document)、TGA等。

3.3根据文件后缀来创建IImageWrapper接口实例

if (InImagePath.EndsWith(".png"))
	{
		return ImageWrapperModule.CreateImageWrapper(EImageFormat::PNG);
	}

首先我们要知道InImagePath是我们调用参数时传入的一个FString参数,FString是UE自己封装实现的一个字符串类,类似于C++中的string,EndsWith则是其中的一个接口,可以检测FString的后缀,我们也可以理解为根据字符串类型从后往前进行检查。返回类型学过C++的铁子一眼就可以看出这个函数的返回类型是bool类型。如果FString中存在相匹配的后缀,那我们就调用ImageWrapperModule中的CreateImageWrapper函数去创建一个对应格式的IImageWrapper的实例并返回,用TSharedPtr<IImageWrapper>进行接收。