赞
踩
1、所需要准备的环境: Visual studio 2019,UE4.26
3、在UE4中添加类(切记不要在 Visual studio新建,一定从UE4中新建)
6、在ScreenShot.cpp文件中添加代码实现以上两个函数
设定类名为ScreenShot
- #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文档上可以找到
- 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);//将颜色数据提取
- 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组件
-
- }
- 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);
-
-
- }
-
- }
- 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);
-
- }
-
- }
运行游戏,按下鼠标键“1” ,在电脑中打开工程文件夹,可以发现 123.jpg已经成功保存到本地
1、用auto Lab = [=]()和定时组合的原因:如果直接截图,可能会出现掉帧现象,此时截出的图片就是黑色,所以一定要延时0.001秒再去截图。
2、for (FColor&color:InColor) { color.A = 255; }这个必须写,否则会出现透明通道,这个和PNG格式有关系
代码参考的UP主(吉叶子丶)的视频:UE4C++截图的几种方式(合集)_哔哩哔哩_bilibili
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。