UE4 图片上绘制文字并保存(C++)

.h

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

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/HUD.h"
#include "Engine/Canvas.h"
#include <Engine/CanvasRenderTarget2D.h>
#include "MyHUD.generated.h"

/**
 * 
 */
UCLASS()
class MYPROJECT_API AMyHUD : public AHUD
{
	GENERATED_BODY()	
	
public:

	AMyHUD();

	virtual void BeginPlay() override;

protected:
	//字体
	UFont * FindFont;
	//图片
	UTexture*  FindTexture;

	FCanvasIcon  FindIcons;

protected:
	//
	void TomDrawHUD();
	
	//绘制画布和文字,绑定在一事件上
	UFUNCTION()
	void OnCanvasUpdate(UCanvas* InCanvas, int32 Width, int32 Height);

	//保存UTextureRenderTarget2D到本地文件
	static bool SaveRenderTargetToFile(UTextureRenderTarget2D* rt, const FString& fileDestination);
};

.cpp

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

#include "MyHUD.h"
#include <ConstructorHelpers.h>
#include <FileHelper.h>
#include <ImageUtils.h>
#include "Engine/CanvasRenderTarget2D.h"
#include <Engine/Engine.h>

// 在图片上绘制文字

AMyHUD::AMyHUD()
{
	// 加载图片 // 仅供参考还有一种加载图片方式
	static ConstructorHelpers::FObjectFinder<UTexture> FindTextureOb(TEXT("/Game/UI/One"));
	FindTexture= FindTextureOb.Object;
	// FindIcons= UCanvas::MakeIcon(FindTextureOb, 0, 0, 0, 0);

	// 加载字体
	static ConstructorHelpers::FObjectFinder<UFont> FindFontOb(TEXT("/Game/UI/Roboto51_Font"));
	FindFont= FontOb.Object;
}   

void AMyHUD::DrawHUD ()
{
	Super::DrawHUD ();
	// 开始绘制,只是参考,如果一直创建画布的话会很卡的(此函数每贞调用)
	CanvasRender->UpdateResource();
}

void AMyHUD::BeginPlay()
{
	Super::BeginPlay();
	TomDrawHUD();
}

void AMyHUD::TomDrawHUD()
{

	// 1. CanvasRenderTarget2D呈现目标.使用CreateCanvasRenderTarget2D()建呈现目标纹理. 创建画布
	UCanvasRenderTarget2D* CanvasRender = Cast<UCanvasRenderTarget2D>(UCanvasRenderTarget2D::CreateCanvasRenderTarget2D(this, UCanvasRenderTarget2D::StaticClass(), 1920, 1080));

	// 2. 将函数绑定到OnCanvasRenderTargetUpdate委托,在更新呈现目标时调用该委托。

	CanvasRender->OnCanvasRenderTargetUpdate.AddDynamic(this, &AMyHUD::OnCanvasUpdate);
}


void AMyHUD::OnCanvasUpdate(UCanvas* InCanvas, int32 Width, int32 Height)
{
// 把图片绘制到画板上 
InCanvas->K2_DrawTexture(加载图片的路径, FVector2D(0, 0), FVector2D(图片的宽, 图片的高(可以自定义)), UV坐标:FVector2D(0, 0), FVector2D(1, 1));

//加载系统字体
UObject* DefaultFontRes = StaticLoadObject(UFont::StaticClass(), nullptr, TEXT("Font'/Engine/EngineFonts/Roboto.Roboto'"));
UFont* DefaultFont = Cast<UFont>(DefaultFontRes);

// 3. 用 ProjectWorldToScreen(3D -> 2D);
FVector2D ScreenPos;
UGameplayStatics::ProjectWorldToScreen(Controller,3D坐标, 2D坐标(ScreenPos));

// 绘制的名字
InCanvas->K2_DrawText(DefaultFont, 要绘制的文字, ScreenPos, FLinearColor::Red);

// 保存
if (InCanvas)
{
	SaveRenderTargetToFile(InCanvas, TEXT("保存位置格式"));
}
}



 // 保存绘制好的图片
 bool APanelAssembly::SaveRenderTargetToFile(UTextureRenderTarget2D* TextureRender, const FString& FileDestination)
{
	FTextureRenderTargetResource* Resource = TextureRender->GameThread_GetRenderTargetResource();

	FReadSurfaceDataFlags ReadPixelFlags(RCM_UNorm);

	TArray<FColor> OutBMP;
	OutBMP.AddUninitialized(TextureRender->GetSurfaceWidth() * TextureRender->GetSurfaceHeight());
	Resource->ReadPixels(OutBMP, ReadPixelFlags);

	FIntPoint DestSize(TextureRender->GetSurfaceWidth(), TextureRender->GetSurfaceHeight());
	TArray<uint8> CompressedBitmap;
	FImageUtils::CompressImageArray(DestSize.X, DestSize.Y, OutBMP, CompressedBitmap);

	bool ImageSavedOk = FFileHelper::SaveArrayToFile(CompressedBitmap, *FileDestination);
	
	return ImageSavedOk;
}

警告:想要绘制画布只能在 DrawHUD 函数运行时调用。

仅供参考!!!

.AddDynamic(函数);// 绑定函数
.RemoveDynamic(函数);// 函数绑定
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
UE4中,你可以使用C++代码来实现截取场景中的图片保存到本地。具体步骤如下: 1. 创建一个C++类,并继承自AActor类。命名为"ScreenshotActor"。 2. 在"ScreenshotActor.h"文件中添加以下头文件: ```cpp #include "Engine/Engine.h" #include "Kismet/GameplayStatics.h" #include "Engine/GameViewportClient.h" #include "Misc/FileHelper.h" #include "Misc/Paths.h" ``` 3. 在"ScreenshotActor.h"文件中添加以下声明: ```cpp UCLASS() class YOURPROJECT_API AScreenshotActor : public AActor { GENERATED_BODY() public: // Sets default values for this actor's properties AScreenshotActor(); // Take screenshot and save to file UFUNCTION(BlueprintCallable, Category = "Screenshot") void TakeScreenshot(); private: // The resolution multiplier for the screenshot UPROPERTY(EditAnywhere, Category = "Screenshot") int32 ResolutionMultiplier = 1; }; ``` 4. 在"ScreenshotActor.cpp"文件中添加以下代码: ```cpp #include "ScreenshotActor.h" AScreenshotActor::AScreenshotActor() { PrimaryActorTick.bCanEverTick = false; } void AScreenshotActor::TakeScreenshot() { // Get the game viewport client UGameViewportClient* ViewportClient = GEngine->GameViewport; if (ViewportClient) { // Get the viewport size FVector2D Size; ViewportClient->GetViewportSize(Size); // Calculate the screenshot resolution int32 ResolutionX = Size.X * ResolutionMultiplier; int32 ResolutionY = Size.Y * ResolutionMultiplier; // Take the screenshot TArray<FColor> Bitmap; Bitmap.AddUninitialized(ResolutionX * ResolutionY); ViewportClient->ReadPixels(Bitmap); // Create the screenshot texture UTexture2D* Screenshot = UTexture2D::CreateTransient(ResolutionX, ResolutionY); Screenshot->CompressionSettings = TC_HDR; Screenshot->SRGB = false; Screenshot->AddToRoot(); Screenshot->UpdateResource(); // Copy the pixel data to the texture uint8* MipData = static_cast<uint8*>(Screenshot->PlatformData->Mips[0].BulkData.Lock(LOCK_READ_WRITE)); FMemory::Memcpy(MipData, Bitmap.GetData(), Bitmap.Num() * sizeof(FColor)); Screenshot->PlatformData->Mips[0].BulkData.Unlock(); // Save the screenshot to file FDateTime Now = FDateTime::Now(); FString Filename = FString::Printf(TEXT("Screenshot_%04d%02d%02d_%02d%02d%02d.png"), Now.GetYear(), Now.GetMonth(), Now.GetDay(), Now.GetHour(), Now.GetMinute(), Now.GetSecond()); FString SaveDirectory = FPaths::GameSavedDir() + TEXT("Screenshots/"); if (!FPaths::DirectoryExists(SaveDirectory)) { FPlatformFileManager::Get().GetPlatformFile().CreateDirectory(*SaveDirectory); } FString FilePath = SaveDirectory + Filename; FFileHelper::SaveArrayToFile(Screenshot->GetRawImageData(), Screenshot->GetAllocatedSize(), *FilePath); // Remove the screenshot texture Screenshot->RemoveFromRoot(); } } ``` 5. 在UE4编辑器中创建一个蓝图,并选择"ScreenshotActor"作为其父类。 6. 在蓝图中添加一个"Take Screenshot"函数,并调用AScreenshotActor::TakeScreenshot()函数。 7. 在场景中放置该蓝图,并运行游戏。当需要截取场景中的图片时,调用蓝图中的"Take Screenshot"函数即可。 注意:在截图之前需要确保场景中的所有元素都已经加载完毕,否则可能会导致截图不完整或者出现其他问题。另外,该实现只适用于PC平台,如果需要支持其他平台,请参考UE4官方文档或者相关论坛。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值