/
Manifest
/
Real_Texture
Обзор
Документация
Войти
/
Manifest
/
Real_Texture
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
Plugins/pixelreader/Source/PixelReader/Private/AsyncCaptureLibrary.cpp
322 строки
12 KB
m.samodurov
init commit for The Invaders
17 фев 2026, 04:57
17 фев 2026, 04:57
4a668d4
Код
Авторство
О чём код?
// Fill out your copyright notice in the Description page of Project Settings. #include "AsyncCaptureLibrary.h" // UAsyncCaptureLibrary // void UAsyncCaptureLibrary::AsyncCaptureByTimeDelegated ( FImageStructDelegate Out, USceneCaptureComponent2D* CameraCapture, E_PR_ImageFormat imFormat, int imQuality ) { if (!IsValid(CameraCapture) || !IsValid(CameraCapture->TextureTarget)) { UE_LOG(LogTemp, Error, TEXT("Invalid CameraCapture or TextureTarget!")); Out.ExecuteIfBound(FImageStruct()); return; } FRenderTarget* RenderTarget = CameraCapture->TextureTarget->GameThread_GetRenderTargetResource(); if (RenderTarget == nullptr) { UE_LOG(LogTemp, Error, TEXT("RenderTarget is nullptr!")); return; } const FIntPoint Size = RenderTarget->GetSizeXY(); UE_LOG(LogTemp, Log, TEXT("Starting async capture from %dx%d"), Size.X, Size.Y); // ���������� ������� ����������� ������ ReadPixelsLib::ThreadSafe_ReadPixels_Fast( RenderTarget, [Out, Size, imFormat, imQuality](TSharedPtr<TArray<FColor>> ColorData) { int32 img_array_size = Size.X * Size.Y; if (!ColorData.IsValid() || ColorData->Num() == 0 || ColorData->Num() != img_array_size) { UE_LOG(LogTemp, Error, TEXT("Failed to capture image data")); return; } UE_LOG(LogTemp, Log, TEXT("Capture completed - %d pixels"), ColorData->Num()); // ��������� � ������� ������ Async(EAsyncExecution::ThreadPool, [ColorData, Out, Size, imFormat, imQuality]() { TArray<uint8> CapturedImage; std::pair<EImageFormat, FString> imParams; if (preDefineCompressingParams(imFormat, imParams)) { TArray<FColor> ProcessedColorBuffer = *ColorData; if (imFormat == E_PR_ImageFormat::PNG) { for (FColor& Color : ProcessedColorBuffer) { Color.A = 255; } } IImageWrapperModule& ImageWrapperModule = FModuleManager::GetModuleChecked<IImageWrapperModule>(FName("ImageWrapper")); TSharedPtr<IImageWrapper> ImageWrapper = ImageWrapperModule.CreateImageWrapper(imParams.first); if (ImageWrapper.IsValid() && ImageWrapper->SetRaw(ProcessedColorBuffer.GetData(), ProcessedColorBuffer.Num() * sizeof(FColor), Size.X, Size.Y, ERGBFormat::BGRA, 8)) { CapturedImage = ImageWrapper->GetCompressed(imQuality); } } else { // Package only RED Channel CapturedImage.Reserve(ColorData->Num()); for (const FColor& Color : *ColorData) { CapturedImage.Add(Color.R); } } // ���������� ��������� � Game Thread AsyncTask(ENamedThreads::GameThread, [Out, CapturedImage, Size, imFormat]() { Out.ExecuteIfBound(FImageStruct(CapturedImage, Size.X, Size.Y, imFormat)); }); }); } ); } void UAsyncCaptureLibrary::AsyncCaptureByTimeWithSaveDelegated ( FImageStructDelegate Out, USceneCaptureComponent2D* CameraCapture, const FString& FileName, const FString& SubFolder, E_PR_ImageFormat imFormat, int imQuality, bool bNeedSaved ) { if (!IsValid(CameraCapture) || !IsValid(CameraCapture->TextureTarget)) { UE_LOG(LogTemp, Error, TEXT("Invalid CameraCapture or TextureTarget!")); return; } FRenderTarget* RenderTarget = CameraCapture->TextureTarget->GameThread_GetRenderTargetResource(); if (RenderTarget == nullptr) { UE_LOG(LogTemp, Error, TEXT("RenderTarget is nullptr!")); return; } const FIntPoint Size = RenderTarget->GetSizeXY(); ReadPixelsLib::ThreadSafe_ReadPixels_Fast( RenderTarget, [Out, FileName, SubFolder, Size, imFormat, imQuality, bNeedSaved](TSharedPtr<TArray<FColor>> ColorData) { int32 img_array_size = Size.X * Size.Y; if (!ColorData.IsValid() || ColorData->Num() == 0 || ColorData->Num() != img_array_size) { UE_LOG(LogTemp, Error, TEXT("Failed to capture image data")); return; } // ��������� � ������� ������ Async(EAsyncExecution::ThreadPool, [ColorData, Out, FileName, SubFolder, Size, imFormat, imQuality, bNeedSaved]() { std::pair<EImageFormat, FString> imParams; if (!preDefineCompressingParams(imFormat, imParams)) { UE_LOG(LogTemp, Error, TEXT("Unsupported image format!")); return; } UE_LOG(LogTemp, Log, TEXT("Processing captured image: %d pixels"), ColorData->Num()); TArray<FColor> ProcessedColorBuffer = *ColorData; // ��������� PNG ������� if (imFormat == E_PR_ImageFormat::PNG) { for (FColor& Color : ProcessedColorBuffer) { Color.A = 255; } } TArray<uint8> CapturedImage; // ������� ImageWrapper � ������� ����������� IImageWrapperModule& ImageWrapperModule = FModuleManager::GetModuleChecked<IImageWrapperModule>(FName("ImageWrapper")); TSharedPtr<IImageWrapper> ImageWrapper = ImageWrapperModule.CreateImageWrapper(imParams.first); if (ImageWrapper.IsValid() && ImageWrapper->SetRaw(ProcessedColorBuffer.GetData(), ProcessedColorBuffer.Num() * sizeof(FColor), Size.X, Size.Y, ERGBFormat::BGRA, 8)) { CapturedImage = ImageWrapper->GetCompressed(imQuality); } // ���������� ����� if (bNeedSaved && CapturedImage.Num() > 0){ FString SaveDir = FPaths::Combine(FPaths::ProjectDir(), TEXT("Saved"), SubFolder); if (!IFileManager::Get().DirectoryExists(*SaveDir)) { IFileManager::Get().MakeDirectory(*SaveDir, true); } FString FullPath = FPaths::Combine(SaveDir, FileName + imParams.second); FFileHelper::SaveArrayToFile(CapturedImage, *FullPath); } // ���������� ��������� � Game Thread AsyncTask(ENamedThreads::GameThread, [Out, CapturedImage, Size, imFormat]() { Out.ExecuteIfBound(FImageStruct(CapturedImage, Size.X, Size.Y, imFormat)); }); }); } ); } // UAsyncCaptureImageWithSaveReternedBase // UAsyncCaptureImageWithSaveReternedBase::UAsyncCaptureImageWithSaveReternedBase(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer) , ImageQuality(0) , bNeedSaved(false) { } UAsyncCaptureImageWithSaveReternedBase* UAsyncCaptureImageWithSaveReternedBase::AsyncCaptureByTimeWithSaveReterned ( UObject* WorldContextObject, USceneCaptureComponent2D* CameraCapture, const FString& FileName, const FString& SubFolder, E_PR_ImageFormat imFormat, int imQuality, bool NeedSaved ) { if (!IsValid(CameraCapture) || !IsValid(CameraCapture->TextureTarget)) { UE_LOG(LogTemp, Error, TEXT("Invalid CameraCapture or TextureTarget!")); return nullptr; } UAsyncCaptureImageWithSaveReternedBase* BlueprintNode = NewObject<UAsyncCaptureImageWithSaveReternedBase>(); BlueprintNode->WeakCameraCapture = CameraCapture; BlueprintNode->FileName = FileName; BlueprintNode->SubFolder = SubFolder; BlueprintNode->ImageFormat = imFormat; BlueprintNode->ImageQuality = imQuality; BlueprintNode->bNeedSaved = NeedSaved; return BlueprintNode; } void UAsyncCaptureImageWithSaveReternedBase::Activate() { ExecuteCapture(); } void UAsyncCaptureImageWithSaveReternedBase::ExecuteCapture() { USceneCaptureComponent2D* CameraCapture = WeakCameraCapture.Get(); if (!CameraCapture || !CameraCapture->TextureTarget) { UE_LOG(LogTemp, Error, TEXT("Invalid CameraCapture or TextureTarget!")); return; } FRenderTarget* RenderTarget = CameraCapture->TextureTarget->GameThread_GetRenderTargetResource(); if (RenderTarget == nullptr) { UE_LOG(LogTemp, Error, TEXT("RenderTarget is nullptr!")); return; } FIntPoint CaptureSize = RenderTarget->GetSizeXY(); ReadPixelsLib::ThreadSafe_ReadPixels_Fast( RenderTarget, [this, CaptureSize](TSharedPtr<TArray<FColor>> ColorData) { int32 img_array_size = CaptureSize.X * CaptureSize.Y; if (!ColorData.IsValid() || ColorData->Num() == 0 || ColorData->Num() != img_array_size) { UE_LOG(LogTemp, Error, TEXT("Failed to capture image data")); return; } // ��������� � ������� ������ Async(EAsyncExecution::ThreadPool, [this, CaptureSize, ColorData]() { std::pair<EImageFormat, FString> imParams; if (!preDefineCompressingParams(ImageFormat, imParams)) { UE_LOG(LogTemp, Error, TEXT("Failed to get image parameters")); return; } TArray<FColor> ProcessedColorBuffer = *ColorData; if (ImageFormat == E_PR_ImageFormat::PNG) { for (FColor& Color : ProcessedColorBuffer) { Color.A = 255; } } TArray<uint8> CapturedImage; IImageWrapperModule& ImageWrapperModule = FModuleManager::GetModuleChecked<IImageWrapperModule>(FName("ImageWrapper")); TSharedPtr<IImageWrapper> ImageWrapper = ImageWrapperModule.CreateImageWrapper(imParams.first); if (ImageWrapper.IsValid() && ImageWrapper->SetRaw(ProcessedColorBuffer.GetData(), ProcessedColorBuffer.Num() * sizeof(FColor), CaptureSize.X, CaptureSize.Y, ERGBFormat::BGRA, 8)) { CapturedImage = ImageWrapper->GetCompressed(ImageQuality); } // ���������� ����� if (bNeedSaved && CapturedImage.Num() > 0) { FString SaveDir = FPaths::Combine(FPaths::ProjectDir(), TEXT("Saved"), SubFolder); if (!IFileManager::Get().DirectoryExists(*SaveDir)) { IFileManager::Get().MakeDirectory(*SaveDir, true); } FString FullPath = FPaths::Combine(SaveDir, FileName + imParams.second); FFileHelper::SaveArrayToFile(CapturedImage, *FullPath); } FImageStruct ImageStruct(CapturedImage, CaptureSize.X, CaptureSize.Y, ImageFormat); AsyncTask(ENamedThreads::GameThread, [this, ImageStruct]() { OnCaptureCompleted(ImageStruct); }); }); } ); } void UAsyncCaptureImageWithSaveReternedBase::OnCaptureCompleted(const FImageStruct& ImageStruct) { ImageAsyncCaptured.Broadcast(ImageStruct); SetReadyToDestroy(); }