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

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章