当前位置:   article > 正文

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

uscenecapturecomponent2d

目录

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中添加所需要的头文件:

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

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


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

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

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

  • 在构造函数中创建一下所需要的组件
  1. AScreenShot::AScreenShot()
  2. {
  3. // Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
  4. PrimaryActorTick.bCanEverTick = true;
  5. RootComponent = CreateDefaultSubobject<USceneComponent>(TEXT("RootComponent"));// 创建可附加内容的虚拟根组件。
  6. CaptureComponent2D = CreateDefaultSubobject<USceneCaptureComponent2D>(TEXT("CaptureComponent2D")); // 创建2D相机
  7. CaptureComponent2D->SetupAttachment(RootComponent);//将CaptureComponent2D绑定到RootComponent组件
  8. }
  •  ScreenShotToImage函数的实现
  1. void AScreenShot::ScreenShotToImage(const FString& InImagePath, const FVector2D& InRangeSize)
  2. {
  3. if (CaptureComponent2D && CaptureComponent2D->TextureTarget)
  4. {
  5. auto Lab = [=]() // 简单自动类型推断
  6. {
  7. //获取randerTarget贴图资源 将颜色值全部放入FTextureRenderTargetResource中
  8. FTextureRenderTargetResource* TextureRenderTargetResource = CaptureComponent2D->TextureTarget->GameThread_GetRenderTargetResource();
  9. int32 Width = CaptureComponent2D->TextureTarget->SizeX;//获取高度
  10. int32 Height = CaptureComponent2D->TextureTarget->SizeY;//获取宽度
  11. TArray<FColor> OutData;//声明一个Fcolor数组
  12. TextureRenderTargetResource->ReadPixels(OutData); //读取像素点
  13. ColorToImage(InImagePath, OutData, Width, Height);//写入到本地存成图片
  14. };
  15. FTimerHandle TimerHandle;//定义一个定时器
  16. //0.001f后再解析图片写入本地 防止掉帧
  17. GetWorld()->GetTimerManager().SetTimer(TimerHandle, Lab, 0.001f, false,0);
  18. }
  19. }
  •  ColorToImage函数实现
  1. void AScreenShot::ColorToImage(const FString& InImagePath, TArray<FColor> InColor, int32 InWidth, int32 InHight)
  2. {
  3. IImageWrapperModule& ImageWrapperModule = FModuleManager::LoadModuleChecked<IImageWrapperModule>("ImageWrapper");
  4. FString Ex = FPaths::GetExtension(InImagePath);
  5. if (Ex.Equals(TEXT("jpg"),ESearchCase::IgnoreCase)|| Ex.Equals(TEXT("jpeg"), ESearchCase::IgnoreCase))
  6. {
  7. TSharedPtr<IImageWrapper>ImageWrapper = ImageWrapperModule.CreateImageWrapper(EImageFormat::JPEG);
  8. //往本地写,获取颜色数据,获取尺寸,获取长度,高度,格式rgb,8位
  9. if (ImageWrapper->SetRaw(InColor.GetData(),InColor.GetAllocatedSize(),InWidth,InHight,ERGBFormat::BGRA,8))
  10. {
  11. FFileHelper::SaveArrayToFile(ImageWrapper->GetCompressed(100), *InImagePath);
  12. }
  13. }
  14. else
  15. {
  16. TArray<uint8>OutPNG;
  17. for (FColor&color:InColor)
  18. {
  19. color.A = 255;//不写的画截屏的图片都是透明通道,就是透明的
  20. }
  21. FImageUtils::CompressImageArray(InWidth, InHight, InColor, OutPNG);
  22. FFileHelper::SaveArrayToFile(OutPNG, *InImagePath);
  23. }
  24. }
  •  在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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/107467
推荐阅读
相关标签
  

闽ICP备14008679号