KLingo Project Documentation 1.0.0
Unreal Engine 5.6 C++ Project Documentation
로딩중...
검색중...
일치하는것 없음
DrawingBoardWidget.cpp
이 파일의 문서화 페이지로 가기
1// Fill out your copyright notice in the Description page of Project Settings.
2
3
5
6#include "GameLogging.h"
7#include "IImageWrapper.h"
8#include "IImageWrapperModule.h"
9#include "UImageButton.h"
10#include "Components/Button.h"
11#include "Components/Image.h"
12#include "Components/Overlay.h"
13#include "Engine/Canvas.h"
14#include "Kismet/KismetRenderingLibrary.h"
15#include "PNGCombineManager.h"
16
17UDrawingBoardWidget::UDrawingBoardWidget(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer)
18{
19 // ConstructorHelpers::FObjectFinder<UTextureRenderTarget2D> rtCanvasRef(TEXT("/Script/Engine.TextureRenderTarget2D'/Game/CustomContents/UI/DrawingBoard/RT_Canvas.RT_Canvas'"));
20 // if (rtCanvasRef.Succeeded())
21 // {
22 // RT_Canvas = rtCanvasRef.Object;
23 // }
24}
25
27{
28 Super::NativeConstruct();
29
30 // Button Event
31 Button_Clear->OnButtonClickedEvent.AddDynamic(this, &UDrawingBoardWidget::ClearCanvas);
32 Button_Save->OnButtonClickedEvent.AddDynamic(this, &UDrawingBoardWidget::SaveCanvas);
33}
34
35FReply UDrawingBoardWidget::NativeOnMouseButtonDown(const FGeometry& InGeometry, const FPointerEvent& InMouseEvent)
36{
37 // Check Mouse is in Canvas
38 const FGeometry CanvasGeometry = Image_Canvas->GetCachedGeometry();
39 if (!CanvasGeometry.IsUnderLocation(InMouseEvent.GetScreenSpacePosition()))
40 {
41 return FReply::Unhandled();
42 }
43
44 // Get Mouse Position in Local Image Coordinate System
45 // Save Current MousePos to prevMousePos
46 prevMousePos = GetLocalMousePos(InMouseEvent.GetScreenSpacePosition());
47 bIsDrawing = true;
48
49 // Draw Point Once
50 // PRINT_STRING(TEXT("%s"), *InMouseEvent.GetEffectingButton().GetFName().ToString());
51 if (InMouseEvent.IsMouseButtonDown(EKeys::LeftMouseButton)) // Draw
52 {
53 DrawPoint(GetLocalMousePos(InMouseEvent.GetScreenSpacePosition()), FLinearColor::Black);
54 }
55 else if (InMouseEvent.IsMouseButtonDown(EKeys::RightMouseButton)) // Erase
56 {
57 DrawPoint(GetLocalMousePos(InMouseEvent.GetScreenSpacePosition()), FLinearColor::White);
58 }
59
60 return FReply::Handled();
61}
62
63FReply UDrawingBoardWidget::NativeOnMouseButtonUp(const FGeometry& InGeometry, const FPointerEvent& InMouseEvent)
64{
65 // Get Mouse Position in Local Image Coordinate System
66 // Save ZeroVector to prevMousePos
67 prevMousePos = GetLocalMousePos(FVector2D::ZeroVector);
68 bIsDrawing = false;
69
70 return FReply::Handled();
71}
72
73FReply UDrawingBoardWidget::NativeOnMouseMove(const FGeometry& InGeometry, const FPointerEvent& InMouseEvent)
74{
75 // return When Mouse Not Pressed
76 if (!bIsDrawing) return Super::NativeOnMouseMove(InGeometry, InMouseEvent);
77
78 if (InMouseEvent.IsMouseButtonDown(EKeys::LeftMouseButton)) // Draw
79 {
80 DrawLines(GetLocalMousePos(InMouseEvent.GetScreenSpacePosition()), FLinearColor::Black);
81 }
82 else if (InMouseEvent.IsMouseButtonDown(EKeys::RightMouseButton)) // Erase
83 {
84 DrawLines(GetLocalMousePos(InMouseEvent.GetScreenSpacePosition()), FLinearColor::White);
85 }
86
87 return FReply::Handled();
88}
89
90void UDrawingBoardWidget::DrawPoint(FVector2D mousePos, FLinearColor drawColor)
91{
92 // Begin Draw Canvas To Render Target
93 UCanvas* canvas = nullptr;
94 FVector2D size;
95 FDrawToRenderTargetContext context;
96 UKismetRenderingLibrary::BeginDrawCanvasToRenderTarget(this, RT_Canvas, canvas, size, context);
97
98 // Set thickness Whether now in Draw or Erase
99 float thickness = (drawColor == FLinearColor::Black) ? 10 : 30;
100 // Draw Box
101 canvas->K2_DrawBox(mousePos, FVector2D(1, 1), thickness, drawColor);
102
103 UKismetRenderingLibrary::EndDrawCanvasToRenderTarget(this, context);
104}
105
106void UDrawingBoardWidget::DrawLines(FVector2D mousePos, FLinearColor drawColor)
107{
108 // Begin Draw Canvas To Render Target
109 UCanvas* canvas = nullptr;
110 FVector2D size;
111 FDrawToRenderTargetContext context;
112 UKismetRenderingLibrary::BeginDrawCanvasToRenderTarget(this, RT_Canvas, canvas, size, context);
113
114 // Calculate Draw Positions
115 FVector2D currPos = prevMousePos;
116 int32 div = 64;
117 FVector2D drawOffset = (mousePos - currPos) / div;
118
119 // Draw
120 for (int32 i = 1; i < div; ++i)
121 {
122 currPos = prevMousePos + drawOffset * i;
123
124 // Set thickness Whether now in Draw or Erase
125 float thickness = (drawColor == FLinearColor::Black) ? 10 : 30;
126 // Draw Line
127 canvas->K2_DrawLine(prevMousePos, currPos, thickness, drawColor);
128 }
129 prevMousePos = mousePos;
130
131 UKismetRenderingLibrary::EndDrawCanvasToRenderTarget(this, context);
132}
133
134FVector2D UDrawingBoardWidget::GetLocalMousePos(FVector2D mousePos)
135{
136 // Get Absolute Local Pos
137 const FGeometry& geometry = Image_Canvas->GetCachedGeometry();
138 FVector2D localPos = geometry.AbsoluteToLocal(mousePos);
139
140 // Get Canvas Size
141 const FVector2D canvasSize = geometry.GetLocalSize();
142 // Transform localPos(in Image_Canvas Coord) to RT_Canvas Coord && Clamp upto RT_Canvas' Border
143 localPos.X = FMath::Clamp((localPos.X / canvasSize.X * RT_Canvas->SizeX), 0.f, RT_Canvas->SizeX);
144 localPos.Y = FMath::Clamp((localPos.Y / canvasSize.Y * RT_Canvas->SizeY), 0.f, RT_Canvas->SizeY);
145 return localPos;
146}
147
149{
150 UKismetRenderingLibrary::ClearRenderTarget2D(this, RT_Canvas, RT_Canvas->ClearColor);
151}
152
154{
155 // File Path
156 const FString filePath = FPaths::ProjectSavedDir() / TEXT("WriteImage/");
157 IFileManager::Get().MakeDirectory(*filePath, true);
158 // File Name
159 FString fileName = FDateTime::Now().ToString(TEXT("%Y_%m_%d_%H_%M_%S.png"));
160
161 // Export Render Target to png
162 UKismetRenderingLibrary::ExportRenderTarget(this, RT_Canvas, filePath, fileName);
163 // UE_LOG(LogTemp, Warning, TEXT("%s | %s"), *filePath, *fileName);
164
165 SaveRenderTargetToPNG(RT_Canvas, filePath / fileName);
166}
167
168bool UDrawingBoardWidget::SaveRenderTargetToPNG(UTextureRenderTarget2D* RenderTarget, const FString& FullFilePath)
169{
170 FTextureRenderTargetResource* RTResource = RenderTarget->GameThread_GetRenderTargetResource();
171 if (!RTResource)
172 {
173 return false;
174 }
175
176 // Get Width & Height
177 const int32 Width = RenderTarget->SizeX;
178 const int32 Height = RenderTarget->SizeY;
179
180 // Set Bitmap array
181 TArray<FColor> Bitmap;
182 Bitmap.AddUninitialized(Width * Height);
183
184 // Read BGRA8 pixels in RenderTarget
185 RTResource->ReadPixels(Bitmap);
186
187 // PNG Encoder
188 IImageWrapperModule& ImageWrapperModule =
189 FModuleManager::LoadModuleChecked<IImageWrapperModule>("ImageWrapper");
190
191 TSharedPtr<IImageWrapper> ImageWrapper =
192 ImageWrapperModule.CreateImageWrapper(EImageFormat::PNG);
193
194 if (!ImageWrapper.IsValid())
195 {
196 return false;
197 }
198
199 ImageWrapper->SetRaw(
200 Bitmap.GetData(),
201 Bitmap.GetAllocatedSize(),
202 Width,
203 Height,
204 ERGBFormat::BGRA,
205 8
206 );
207
208 // Compress to PNG
209 const TArray64<uint8>& PNGData = ImageWrapper->GetCompressed(100);
210
211 // Make Directory
212 const FString Directory = FPaths::GetPath(FullFilePath);
213 IFileManager::Get().MakeDirectory(*Directory, true);
214
215 return FFileHelper::SaveArrayToFile(PNGData, *FullFilePath);
216}
YiSan 전반에서 사용하는 공용 인터페이스를 선언합니다.
virtual FReply NativeOnMouseButtonDown(const FGeometry &InGeometry, const FPointerEvent &InMouseEvent) override
TObjectPtr< class UImageButton > Button_Clear
void DrawLines(FVector2D mousePos, FLinearColor drawColor)
TObjectPtr< class UImageButton > Button_Save
UDrawingBoardWidget(const FObjectInitializer &ObjectInitializer)
TObjectPtr< class UTextureRenderTarget2D > RT_Canvas
FVector2D GetLocalMousePos(FVector2D mousePos)
TObjectPtr< class UImage > Image_Canvas
virtual FReply NativeOnMouseMove(const FGeometry &InGeometry, const FPointerEvent &InMouseEvent) override
void DrawPoint(FVector2D mousePos, FLinearColor drawColor)
bool SaveRenderTargetToPNG(UTextureRenderTarget2D *RenderTarget, const FString &FullFilePath)
virtual void NativeConstruct() override
virtual FReply NativeOnMouseButtonUp(const FGeometry &InGeometry, const FPointerEvent &InMouseEvent) override