/
Manifest
/
Real_Texture
Обзор
Документация
Войти
/
Manifest
/
Real_Texture
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
Plugins/pixelreader/Source/PixelReader/Private/FenceCaptureLibrary.cpp
284 строки
8 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 "FenceCaptureLibrary.h" #include <fstream> #include <iterator> #include <vector> bool UFenceCaptureLibrary::CaptureByFenceReterned ( FImageStruct& img_data, USceneCaptureComponent2D* CameraCapture, E_PR_ImageFormat imFormat, int imQuality ) { FRenderTarget* RenderTarget = CameraCapture->TextureTarget->GameThread_GetRenderTargetResource(); if (RenderTarget == nullptr) { UE_LOG(LogTemp, Error, TEXT("RenderTarget is nullptr!")); return false; } TArray<FColor> ColorBuffer; FRenderCommandFence CaptureFence; ReadPixelsLib::Command_ReadPixels_Fast(RenderTarget, ColorBuffer); CaptureFence.BeginFence(); CaptureFence.Wait(); const int32 img_width = RenderTarget->GetSizeXY().X; const int32 img_height = RenderTarget->GetSizeXY().Y; const int32 img_array_size = img_width * img_height; if (!CaptureFence.IsFenceComplete() || ColorBuffer.Num() == 0 || ColorBuffer.Num() != img_array_size) { UE_LOG(LogTemp, Warning, TEXT("Image not ready!")); return false; } UE_LOG(LogTemp, Log, TEXT("IMG WAS CAPTURED")); UE_LOG(LogTemp, Log, TEXT("Color Buffer size - %d. Resolution %d x %d"), ColorBuffer.Num(), img_width, img_height); TArray<uint8> CapturedImage; std::pair<EImageFormat, FString> imParams; if (preDefineCompressingParams(imFormat, imParams)) { if (imFormat == E_PR_ImageFormat::PNG) { for (int i = 0; i < ColorBuffer.Num(); ++i) { ColorBuffer[i].A = 255; } } IImageWrapperModule& ImageWrapperModule = FModuleManager::LoadModuleChecked<IImageWrapperModule>(FName("ImageWrapper")); TSharedPtr<IImageWrapper> ImageWrapper = ImageWrapperModule.CreateImageWrapper(imParams.first); if (ImageWrapper.IsValid() && ImageWrapper->SetRaw(ColorBuffer.GetData(), ColorBuffer.Num() * sizeof(FColor), img_width, img_height, ERGBFormat::BGRA, 8)) { CapturedImage = ImageWrapper->GetCompressed(imQuality); } } else { // Package only RED Channel for (int i = 0; i < ColorBuffer.Num(); ++i) { CapturedImage.Add(ColorBuffer[i].R); } } img_data.img_array = CapturedImage; img_data.width = img_width; img_data.height = img_height; img_data.img_format = imFormat; return true; } bool UFenceCaptureLibrary::CaptureByFenceWithSaveReterned ( FImageStruct& img_data, USceneCaptureComponent2D* CameraCapture, FString FileName, FString SubFolder, E_PR_ImageFormat imFormat, int imQuality, bool bNeedSaved ) { FRenderTarget* RenderTarget = CameraCapture->TextureTarget->GameThread_GetRenderTargetResource(); if (RenderTarget == nullptr) { UE_LOG(LogTemp, Error, TEXT("RenderTarget is nullptr!")); return false; } std::pair<EImageFormat, FString> imParams; if (!preDefineCompressingParams(imFormat, imParams)) { UE_LOG(LogTemp, Error, TEXT("Image with this format cannot be saved!")); return false; } IImageWrapperModule& ImageWrapperModule = FModuleManager::LoadModuleChecked<IImageWrapperModule>(FName("ImageWrapper")); TSharedPtr<IImageWrapper> ImageWrapper = ImageWrapperModule.CreateImageWrapper(imParams.first); TArray<FColor> ColorBuffer; FRenderCommandFence CaptureFence; ReadPixelsLib::Command_ReadPixels_Fast(RenderTarget, ColorBuffer); CaptureFence.BeginFence(); CaptureFence.Wait(); const int32 img_width = RenderTarget->GetSizeXY().X; const int32 img_height = RenderTarget->GetSizeXY().Y; const int32 img_array_size = img_width * img_height; if (!CaptureFence.IsFenceComplete() || ColorBuffer.Num() == 0 || ColorBuffer.Num() != img_array_size) { UE_LOG(LogTemp, Warning, TEXT("Image not ready!")); return false; } UE_LOG(LogTemp, Log, TEXT("IMG '%s.%s' WAS CAPTURED"), *FileName, *imParams.second); UE_LOG(LogTemp, Log, TEXT("Color Buffer size - %d. Resolution %d x %d"), ColorBuffer.Num(), img_width, img_height); if (imFormat == E_PR_ImageFormat::PNG) { for (int i = 0; i < ColorBuffer.Num(); ++i) { ColorBuffer[i].A = 255; } } TArray<uint8> CapturedImage; if (ImageWrapper.IsValid() && ImageWrapper->SetRaw(ColorBuffer.GetData(), ColorBuffer.Num() * sizeof(FColor), img_width, img_height, ERGBFormat::BGRA, 8)) { CapturedImage = ImageWrapper->GetCompressed(imQuality); } Async(EAsyncExecution::ThreadPool, [=]() { if (bNeedSaved) { bool bSubFolderMaked = true; if (!FPaths::DirectoryExists(FPaths::Combine(FPaths::ProjectDir(), TEXT("Saved"), SubFolder))) { bSubFolderMaked = IFileManager::Get().MakeDirectory(*(FPaths::Combine(FPaths::ProjectDir(), TEXT("Saved"), SubFolder))); } if (bSubFolderMaked) { FString PathToFile = FPaths::Combine(FPaths::ProjectDir(), TEXT("Saved"), SubFolder, FileName + imParams.second); FFileHelper::SaveArrayToFile(CapturedImage, *(PathToFile)); UE_LOG(LogTemp, Log, TEXT("WE SAVE Image as FILE... %s"), *PathToFile); } } }); img_data.img_array = CapturedImage; img_data.width = img_width; img_data.height = img_height; img_data.img_format = imFormat; return true; } bool UFenceCaptureLibrary::ReturnedResizeImageWithSave ( FImageStruct inImageData, FResizeImgParams ResizeImageParams, FString FileName, FString SubFolder, FImageStruct& outImageData ) { if (!inImageData.img_array.Num()) return false; std::vector<uchar> convert_buffer; convert_buffer.assign(inImageData.img_array.GetData(), inImageData.img_array.GetData() + inImageData.img_array.Num()); if (!convert_buffer.size()) return false; cv::Mat val(convert_buffer); cv::Mat image_background = cv::imdecode(val, -1); cv::Mat resized_image; cv::resize(image_background, resized_image, cv::Size(ResizeImageParams.NewWidth, ResizeImageParams.NewHeight), 0.0, 0.0, cv::INTER_AREA); cv::String CVFormat; std::vector<int> CVParams; if (inImageData.img_format == E_PR_ImageFormat::JPEG) { CVFormat = cv::String(".jpg"); CVParams = { cv::IMWRITE_JPEG_QUALITY, (ResizeImageParams.imQuality == 0 ? 85 : ResizeImageParams.imQuality) }; } else if (inImageData.img_format == E_PR_ImageFormat::PNG) { CVFormat = cv::String(".png"); int quality; // define png compress strategy // imQuality from 0 to 100 if (ResizeImageParams.imQuality == 0) quality = 8; if (ResizeImageParams.imQuality == 100) quality = 9; else if (ResizeImageParams.imQuality > 10 && ResizeImageParams.imQuality < 100) quality = static_cast<int>(ResizeImageParams.imQuality / 10); else quality = 0; CVParams = { cv::IMWRITE_PNG_COMPRESSION, quality }; } std::vector<uchar, std::allocator<uchar>> encoded_buffer; volatile int sz = (resized_image.total() * resized_image.channels()) << 1; encoded_buffer.reserve(sz); cv::imencode(CVFormat, resized_image, encoded_buffer, CVParams); if (ResizeImageParams.bNeedSave) SaveCVImage(resized_image, inImageData.img_format, FString::Printf(TEXT("%d"), FCString::Atoi(*FileName)), SubFolder); // возвращать Resize-картинку outImageData.img_array.Empty(); TArray<uint8> result_array(reinterpret_cast<uint8*>(&encoded_buffer.data()[0]), encoded_buffer.size()); outImageData.img_array = result_array; outImageData.width = ResizeImageParams.NewWidth; outImageData.height = ResizeImageParams.NewHeight; outImageData.img_format = inImageData.img_format; return true; } void UFenceCaptureLibrary::SaveCVImage ( const cv::Mat& mat_image, E_PR_ImageFormat ImgFormat, const FString& FileName, const FString& SubFolder ) { bool bSubFolderMaked = true; if (!FPaths::DirectoryExists(FPaths::Combine(FPaths::ProjectDir(), TEXT("Saved"), SubFolder))) { bSubFolderMaked = IFileManager::Get().MakeDirectory(*(FPaths::Combine(FPaths::ProjectDir(), TEXT("Saved"), SubFolder))); } if (bSubFolderMaked) { FString imFormat; if (ImgFormat == E_PR_ImageFormat::JPEG) imFormat = TEXT(".jpg"); else if (ImgFormat == E_PR_ImageFormat::PNG) imFormat = TEXT(".png"); else { UE_LOG(LogTemp, Log, TEXT("Unsupported format for Image Saving")); return; } FString PathToFile = FPaths::Combine(FPaths::ProjectDir(), TEXT("Saved"), SubFolder, FileName + imFormat); std::string sPathToFile(TCHAR_TO_UTF8(*PathToFile)); cv::imwrite(sPathToFile, mat_image); UE_LOG(LogTemp, Log, TEXT("RESIZE Image SAVED as FILE... %s"), *PathToFile); } } //==========