UE4 截图处理相关内容

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();   //获取截图保存的文件名字

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值