1. 绑定截图回调
FScreenshotRequest::OnScreenshotRequestProcessed().AddUObject(this, &UMyWidget::SetExportTexture); //本文由CSDN博主执手画眉弯原创,未经允许不得转载!
绑定回调后,截图成功处理后回调到该函数
2. 调用截图功能
FScreenshotRequest::RequestScreenshot(FileName, bShowUI, true);//本文由CSDN博主执手画眉弯原创,未经允许不得转载!
3. 截图处理模块
添加GameViewportClient子类,重载ProcessScreenShots(FViewport * InViewport)函数。
//在原图上添加水印
UTexture2D* LogoTexture = Cast<UTexture2D>(StaticLoadObject(UTexture2D::StaticClass(), NULL, TEXT("/Game/UI/Texture/Watermark")));
uint8* BitMapPtr = (uint8*)&Bitmap[Size.X * (Size.Y - (LogoTexture->GetSizeY()) * 2)];
uint8* MipData = static_cast<uint8*>(LogoTexture->PlatformData->Mips[0].BulkData.Lock(LOCK_READ_WRITE));
uint8* PixelPtr = &MipData[0];//本文由CSDN博主执手画眉弯原创,未经允许不得转载!
for (int i = 0; i < LogoTexture->GetSizeY(); ++i)
{
BitMapPtr += (Size.X - LogoTexture->GetSizeX() - LogoTexture->GetSizeY()) * 4;
for (int j = 0; j < LogoTexture->GetSizeX(); ++j)
{
if (*(PixelPtr + 3) == 0x0)
{
PixelPtr += 4;
BitMapPtr += 4;
continue;
}
*BitMapPtr++ = *PixelPtr++;
*BitMapPtr++ = *PixelPtr++;
*BitMapPtr++ = *PixelPtr++;
*BitMapPtr++ = *PixelPtr++;
}
BitMapPtr += LogoTexture->GetSizeY() * 4;
}
LogoTexture->PlatformData->Mips[0].BulkData.Unlock();
#if PLATFORM_IOS
//保存至IOS相册
BitMapPtr = (uint8*)&Bitmap[0];
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = CGBitmapContextCreate(BitMapPtr, Size.X, Size.Y, 8, Size.X * 4, colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst);
CGImageRef imageRef = CGBitmapContextCreateImage(context);
UIImage* saveImage = [UIImage imageWithCGImage : imageRef];
CGContextRelease(context);
CGColorSpaceRelease(colorSpace);
CGImageRelease(imageRef);
UIImageWriteToSavedPhotosAlbum(saveImage, nil, nil, nil);
#endif//本文由CSDN博主执手画眉弯原创,未经允许不得转载!
//存储一个缩小过的图到沙盒文件夹
TArray<uint8> CompressedBitmap;
TArray<FColor> NewBitmap;
int32 NewWidget = 0;
int32 NewHeight = 0;
if (ImageShrink(Bitmap, Size.X, Size.Y, 0.15f, NewBitmap, NewWidget, NewHeight)) //缩放+切圆角
{
FImageUtils::CompressImageArray(NewWidget, NewHeight, NewBitmap, CompressedBitmap); //序列化为uint8数组
UTexture2D *ShrikTexture = gOpenCVManager.CreateTexture2D(NewBitmap, NewWidget, NewHeight, EPixelFormat::PF_B8G8R8A8);
if (ShrikTexture)//本文由CSDN博主执手画眉弯原创,未经允许不得转载!
{
gImageManager.AddTexture2D(FPaths::GetCleanFilename(ScreenShotName), ShrikTexture);
}
}
//这里一定要先回调,再清空信息,不然回调函数无法获取保存的文件名字
FScreenshotRequest::OnScreenshotRequestProcessed().Broadcast();
FScreenshotRequest::Reset();
//本文由CSDN博主执手画眉弯原创,未经允许不得转载!
//缩放图片
bool UXXGameViewportClient::ImageShrink(const TArray<FColor> &Bitmap, const int32 Width, const int32 Height, const float Ratio,
TArray<FColor> &NewBitmap, int32 &NewWidth, int32 &NewHeight)
{
if (Bitmap.Num() <= 0 || Width < 1 || Height < 1 || Ratio < 0.01f || Ratio > 0.99f)
return false;
if (NewBitmap.Num() > 0)
NewBitmap.Empty();
NewWidth = (int32)((float)Width * Ratio);
NewHeight = (int32)((float)Height * Ratio);
NewBitmap.SetNum(NewWidth * NewHeight);
int32 nStep = Width / NewWidth;
int32 nVStep = Height / NewHeight;
int32 nRowStep = 0;//本文由CSDN博主执手画眉弯原创,未经允许不得转载!
for (int32 i = 0; i < NewHeight; i++)
{
for (int32 j = 0; j < NewWidth; j++)
{
//是否需要切角
if (IsNeedRid(j, i, NewWidth, NewHeight))
NewBitmap[i * NewWidth + j] = FColor(0, 0, 0, 0);
else
NewBitmap[i * NewWidth + j] = Bitmap[nRowStep + j * nStep];
}
nRowStep += Width * nVStep;
}
return true;
}
//切一个小圆角
bool UXXGameViewportClient::IsNeedRid(const int32 w, const int32 h, const int32 Width, const int32 Height)
{
if (h < 6 && w < 6)
{
if ((5 - w) * (5 - w) + (5 - h) * (5 - h) > 25)
return true;
return false;
}
else if (h < 6 && w + 6 > Width)
{
if ((w - Width + 5) * (w - Width + 5) + (5 - h) * (5 - h) > 25)
return true;
return false;
}
else if (h + 6 > Height && w < 6)
{
if ((5 - w) * (5 - w) + (h - Height + 5) * (h - Height + 5) > 25)
return true;
return false;
}//本文由CSDN博主执手画眉弯原创,未经允许不得转载!
else if (h + 6 > Height && w + 6 > Width)
{
if ((w - Width + 5) * (w - Width + 5) + (h - Height + 5) * (h - Height + 5) > 25)
return true;
return false;
}
return false;
}
4. 回调处理
FScreenshotRequest::OnScreenshotRequestProcessed().RemoveAll(this); //清空回调绑定
FScreenshotRequest::GetFilename(); //获取截图保存的文件名字