一:使用说明
对已拍照的FColor数据进行裁剪、压缩的操作,达到减少内存的效果:
PC上原截图 约900+kb
PC上裁剪截图 约200+kb
PC上裁剪截图加转格式 约130kb
PC上裁剪截图加转格式加压缩 约13kb
下面提供示例接口,有需要可以进行参考修改
二、调用示例:
C侧:
1、命令行方式截图
void UPhotoSubsys::CaptureScreenShot()
{
if (GEngine && GEngine->GameViewport)
{
GCaptureDelaHandle = UGameViewportClient::OnScreenshotCaptured().AddUObject(this, &UPhotoSubsys::OnCaptureScreenShotComplete);
//命令行截屏
FString cmdStr = GetShotCmdStr();
GEngine->GameViewport->Exec(GetWorld(), *cmdStr, *GLog);
}
}
void UPhotoSubsys::OnCaptureScreenShotComplete(int32 InWidth, int32 InHeight, const TArray<FColor>& InColors)
{
if (ImmediatelySave()) //直接保存
{
bool bSaveSucceed = false;
TArray<uint8> PNGData;
FImageUtils::CompressImageArray(InWidth, InHeight, InColors, PNGData);
FString pngFilePath = GetSaveFilePath();
bSaveSucceed = FFileHelper::SaveArrayToFile(PNGData, *pngFilePath);
OnEndSaveImageFileInC(bSaveSucceed, pngFilePath);
}
else
{
//将数据传递给Lua侧,进行后续处理,本文采用这种方式
OnEndCaptureScreenShot(InWidth, InHeight, InColors);
}
}
2、根据尺寸保存压缩jpg
bool UPhotoSubsys::SaveImageArrayWithJPG(int32 InWidth, int32 InHeight, int32 Quality, const TArray<FColor>& InColors, const FString& ScreenShotName)
{
IImageWrapperModule& ImageWrapperModule = FModuleManager::Get().LoadModuleChecked<IImageWrapperModule>(FName("ImageWrapper"));
IImageWrapperPtr ImageWrapper = ImageWrapperModule.CreateImageWrapper(EImageFormat::JPEG);
if (ImageWrapper->SetRaw(InColors.GetData(), InColors.Num() * sizeof(FColor), InWidth, InHeight, ERGBFormat::BGRA, 8))
{
return FFileHelper::SaveArrayToFile(ImageWrapper->GetCompressed(Quality), *ScreenShotName);
}
return false;
}
3、通过传参路径和jpg/png 读取本地图片转换成UTexture2D
UTexture2D* UBlueprintFunctionLibrary::LoadTexture2dFromFile(const FString& FilePath, UTexture2D* texture2d, int ImageFormat)
{
TArray<uint8> ImageResultData;
if (FFileHelper::LoadFileToArray(ImageResultData, *FilePath) == false)//读取图片的二进制数据
return nullptr;
//EImageFormat ImageFormat = EImageFormat::PNG;
IImageWrapperModule& ImageWrapperModule = FModuleManager::LoadModuleChecked<IImageWrapperModule>("ImageWrapper");
TSharedPtr<IImageWrapper> ImageWrapperptr = ImageWrapperModule.CreateImageWrapper(EImageFormat(ImageFormat));//创建对应格式图片壳子
const bool PtrIsValid = ImageWrapperptr.IsValid();
if (PtrIsValid && ImageWrapperptr->SetCompressed(ImageResultData.GetData(),ImageResultData.GetAllocatedSize()))
{
TArray64<uint8> OutRawData;
ImageWrapperptr->GetRaw(ERGBFormat::BGRA, 8, OutRawData); //按规则提取数据
if (texture2d == nullptr ||
texture2d->GetSizeX() != ImageWrapperptr->GetWidth() ||
texture2d->GetSizeY() != ImageWrapperptr->GetHeight())
texture2d = UTexture2D::CreateTransient(ImageWrapperptr->GetWidth(), ImageWrapperptr->GetHeight(), PF_B8G8R8A8);
if (texture2d)
{
void* TextureData = texture2d->PlatformData->Mips[0].BulkData.Lock(LOCK_READ_WRITE);
FMemory::Memcpy(TextureData, OutRawData.GetData(),OutRawData.Num());//将数据写入*TextureData
texture2d->PlatformData->Mips[0].BulkData.Unlock();
texture2d->UpdateResource();
}
}
return texture2d;
}
Lua侧:
裁剪
function UPhotoSubsys:ClipPhoto(InWidth, InHeight, InColors, startX, startY, targetX, targetY, fileName)
if startX > InWidth or targetX > InWidth or startY > InHeight or targetY > InHeight then
print("ClipPhoto Failed: Invaild InputParms")
return false
end
local baseColorTable = InColors:ToTable()
local nColors = UE4.TArray(UE4.FColor)
for y = 1, targetY do
for x = 1, targetX do
if y > startY and x > startX then
local baseColor = UE4.FColor
baseColor = baseColorTable[(y * InWidth + x)]
nColors:Add(baseColor)
end
end
end
local rootPath = GetAbsoluteSavePath("Snapshot/")
local filePath = rootPath .. fileName
local bSaved = false
--压缩jpg
if UPhotoSubsys.SaveImageArrayWithJPG then
bSaved = UPhotoSubsys:SaveImageArrayWithJPG(targetX - startX, targetY - startY, 50, nColors, filePath)
end
return bSaved
end