UE4截图方式一(利用USceneCaptureComponent2D组件截图)(C++程序)

目录

1、所需要准备的环境:    Visual studio 2019,UE4.26

2、通过UE4新建一个C++的空白工程

3、在UE4中添加类(切记不要在 Visual studio新建,一定从UE4中新建) 

4、 在ScreenShot.h中添加所需要的头文件:

5、ScreenShot.h文件中添加代码

6、在ScreenShot.cpp文件中添加代码实现以上两个函数

7、关卡蓝图中的实现

8、测试效果

 9、代码说明:

交流qq: 1137221527


1、所需要准备的环境:    Visual studio 2019,UE4.26


  

2、通过UE4新建一个C++的空白工程


3、在UE4中添加类(切记不要在 Visual studio新建,一定从UE4中新建) 

设定类名为ScreenShot

 


4、 在ScreenShot.h中添加所需要的头文件:

#include "Components/SceneCaptureComponent2D.h"//SceneCaptureComponent2D组件的头文件
#include "Engine/TextureRenderTarget2D.h"//TextureRenderTarget2D组件的头文件
#include "Engine/World.h"//GetWord()方法所需要的头文件
#include "TimerManager.h"//定时器所需要的头文件
#include "Modules/ModuleManager.h"//Fmodule头文件
//与图片相关的头文件
#include "IImageWrapperModule.h"
#include "IImageWrapper.h"
#include "Misc/FileHelper.h"
#include "ImageUtils.h"

以上的头文件可以从UE4官网的C++ API文档上可以找到


5、ScreenShot.h文件中添加代码

  •  声明一个USceneCaptureComponent2D组件,并且暴露在蓝图中
UPROPERTY(Category = Default, VisibleAnywhere, BlueprintReadOnly)
class	USceneCaptureComponent2D* CaptureComponent2D;// 声明一个2D截图的组件USceneCaptureComponent2D这个
  • 声明两个自定义的函数
UFUNCTION(BlueprintCallable)
void ScreenShotToImage(const FString& InImagePath,const FVector2D& InRangeSize);//将截屏转换为相片
UFUNCTION(BlueprintCallable)
void ColorToImage(const FString& InImagePath, TArray<FColor>InColor,int32 InWidth,int32 InHight);//将颜色数据提取

6、在ScreenShot.cpp文件中添加代码实现以上两个函数

  • 在构造函数中创建一下所需要的组件
AScreenShot::AScreenShot()
{
 	// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;
	RootComponent = CreateDefaultSubobject<USceneComponent>(TEXT("RootComponent"));// 创建可附加内容的虚拟根组件。
	CaptureComponent2D = CreateDefaultSubobject<USceneCaptureComponent2D>(TEXT("CaptureComponent2D"));	// 创建2D相机
	CaptureComponent2D->SetupAttachment(RootComponent);//将CaptureComponent2D绑定到RootComponent组件

}
  •  ScreenShotToImage函数的实现
void AScreenShot::ScreenShotToImage(const FString& InImagePath, const FVector2D& InRangeSize)
{

	
	if (CaptureComponent2D && CaptureComponent2D->TextureTarget)
	{
		
		auto Lab = [=]()  // 简单自动类型推断
		{
			//获取randerTarget贴图资源  将颜色值全部放入FTextureRenderTargetResource中
			FTextureRenderTargetResource* TextureRenderTargetResource = CaptureComponent2D->TextureTarget->GameThread_GetRenderTargetResource();
			int32 Width = CaptureComponent2D->TextureTarget->SizeX;//获取高度
			int32 Height = CaptureComponent2D->TextureTarget->SizeY;//获取宽度
			TArray<FColor> OutData;//声明一个Fcolor数组
			TextureRenderTargetResource->ReadPixels(OutData);  //读取像素点

			ColorToImage(InImagePath, OutData, Width, Height);//写入到本地存成图片
		};
		
		FTimerHandle TimerHandle;//定义一个定时器
		//0.001f后再解析图片写入本地  防止掉帧
		GetWorld()->GetTimerManager().SetTimer(TimerHandle, Lab, 0.001f, false,0);

			
	}
	
}
  •  ColorToImage函数实现
void AScreenShot::ColorToImage(const FString& InImagePath, TArray<FColor> InColor, int32 InWidth, int32 InHight)
{

	IImageWrapperModule& ImageWrapperModule = FModuleManager::LoadModuleChecked<IImageWrapperModule>("ImageWrapper");
	FString	Ex = FPaths::GetExtension(InImagePath);
	if (Ex.Equals(TEXT("jpg"),ESearchCase::IgnoreCase)|| Ex.Equals(TEXT("jpeg"), ESearchCase::IgnoreCase))
	{
		TSharedPtr<IImageWrapper>ImageWrapper = ImageWrapperModule.CreateImageWrapper(EImageFormat::JPEG);
		//往本地写,获取颜色数据,获取尺寸,获取长度,高度,格式rgb,8位
		if (ImageWrapper->SetRaw(InColor.GetData(),InColor.GetAllocatedSize(),InWidth,InHight,ERGBFormat::BGRA,8))
		{
			FFileHelper::SaveArrayToFile(ImageWrapper->GetCompressed(100), *InImagePath);
		}
	}
	else
	{
		TArray<uint8>OutPNG;
		
		for (FColor&color:InColor)
		{
			color.A = 255;//不写的画截屏的图片都是透明通道,就是透明的
		}
		FImageUtils::CompressImageArray(InWidth, InHight, InColor, OutPNG);
		FFileHelper::SaveArrayToFile(OutPNG, *InImagePath);

	}

}
  •  在UE4中找到声明的组件,拖进去UE4中,此时面板中就会有一个组件出现

 

  • 注意事项:当拖进去以后记住要选中渲染的图,否则会造成捕获失败。

 

7、关卡蓝图中的实现

  • 打开关卡蓝图

  •  将ScreenShot组件从右边拖进去蓝图中

  •  添加ScreenShotToImage函数蓝图

  • 从蓝色引脚拖出一条线,添加2D向量蓝图

  •  依次添加下蓝图函数:

  • 最终蓝图效果如下所示

8、测试效果

运行游戏,按下鼠标键“1” ,在电脑中打开工程文件夹,可以发现 123.jpg已经成功保存到本地

 9、代码说明:

1、用auto Lab = [=]()和定时组合的原因:如果直接截图,可能会出现掉帧现象,此时截出的图片就是黑色,所以一定要延时0.001秒再去截图。

2、for (FColor&color:InColor) { color.A = 255; }这个必须写,否则会出现透明通道,这个和PNG格式有关系

交流qq: 1137221527


代码参考的UP主(吉叶子丶)的视频:UE4C++截图的几种方式(合集)_哔哩哔哩_bilibili

  • 8
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是一个简单的UE4 C++动态程序化网格生成的示例代码,它可以创建一个立方体网格,您可以在其中添加更多的功能或修改代码来满足您的需求。 ```cpp // 在您的头文件中包含以下头文件 #include "CoreMinimal.h" #include "GameFramework/Actor.h" #include "ProceduralMeshComponent.h" #include "ProceduralMesh.generated.h" UCLASS() class AProceduralMesh : public AActor { GENERATED_BODY() public: // 设置默认值 AProceduralMesh(); protected: // 在BeginPlay中创建网格 virtual void BeginPlay() override; private: // 动态创建立方体网格 void CreateCubeMesh(); // 用于创建网格的组件 UPROPERTY(VisibleAnywhere) UProceduralMeshComponent* MeshComponent; }; // 在.cpp文件中实现CreateCubeMesh函数 void AProceduralMesh::CreateCubeMesh() { TArray<FVector> Vertices; TArray<int32> Triangles; TArray<FVector> Normals; TArray<FVector2D> UVs; TArray<FProcMeshTangent> Tangents; // 创建6个面,每个面有4个顶点 const int32 NumFaces = 6; const int32 NumVertsPerFace = 4; // 创建立方体的顶点 FVector Verts[] = { FVector(-50.f, 50.f, 50.f), FVector(-50.f, -50.f, 50.f), FVector(50.f, -50.f, 50.f), FVector(50.f, 50.f, 50.f), FVector(50.f, 50.f, -50.f), FVector(50.f, -50.f, -50.f), FVector(-50.f, -50.f, -50.f), FVector(-50.f, 50.f, -50.f), FVector(-50.f, 50.f, -50.f), FVector(-50.f, -50.f, -50.f), FVector(-50.f, -50.f, 50.f), FVector(-50.f, 50.f, 50.f), FVector(50.f, 50.f, 50.f), FVector(50.f, -50.f, 50.f), FVector(50.f, -50.f, -50.f), FVector(50.f, 50.f, -50.f), FVector(-50.f, 50.f, -50.f), FVector(-50.f, 50.f, 50.f), FVector(50.f, 50.f, 50.f), FVector(50.f, 50.f, -50.f), FVector(-50.f, -50.f, 50.f), FVector(-50.f, -50.f, -50.f), FVector(50.f, -50.f, -50.f), FVector(50.f, -50.f, 50.f), }; // 创建立方体的三角形面 int32 Indices[] = { 0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, 8, 9, 10, 8, 10, 11, 12, 13, 14, 12, 14, 15, 16, 17, 18, 16, 18, 19, 20, 21, 22, 20, 22, 23, }; // 为每个面添加法线 FVector Norms[] = { FVector(0.f, 0.f, 1.f), FVector(0.f, 0.f, -1.f), FVector(-1.f, 0.f, 0.f), FVector(1.f, 0.f, 0.f), FVector(0.f, 1.f, 0.f), FVector(0.f, -1.f, 0.f), }; // 创建立方体的UV坐标 FVector2D UV[] = { FVector2D(0.f, 0.f), FVector2D(0.f, 1.f), FVector2D(1.f, 1.f), FVector2D(1.f, 0.f), }; for (int32 i = 0; i < NumFaces; i++) { for (int32 j = 0; j < NumVertsPerFace; j++) { const int32 VertexIndex = i * NumVertsPerFace + j; Vertices.Add(Verts[Indices[VertexIndex]]); Triangles.Add(VertexIndex); Normals.Add(Norms[i]); UVs.Add(UV[j]); Tangents.Add(FProcMeshTangent(1.f, 0.f, 0.f)); } } // 将创建的数据设置到网格组件中 MeshComponent->CreateMeshSection_LinearColor(0, Vertices, Triangles, Normals, UVs, TArray<FColor>(), Tangents, true); } // 在BeginPlay中创建网格 void AProceduralMesh::BeginPlay() { Super::BeginPlay(); // 创建一个新的ProceduralMeshComponent MeshComponent = CreateDefaultSubobject<UProceduralMeshComponent>(TEXT("ProceduralMesh")); RootComponent = MeshComponent; // 创建立方体网格 CreateCubeMesh(); } // 设置默认值 AProceduralMesh::AProceduralMesh() { PrimaryActorTick.bCanEverTick = false; } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值