目录
一,写带通道的RGBA图片(BMP)
1,写BMP图片的代码:
#include "Windows/AllowWindowsPlatformTypes.h"
#include "Windows/PreWindowsApi.h"
#include <windows.h>
#include "Windows/PostWindowsApi.h"
#include "Windows/HideWindowsPlatformTypes.h"
inline LONG BmpPitchCB(const BITMAPINFOHEADER* pFormat)
{
return ((pFormat->biWidth * (pFormat->biBitCount >> 3) + 3) >> 2) << 2;
}
inline HRESULT SaveBmp(
LPCTSTR pFileName,
const void* pBuf,
LONG lBuf_W,
LONG lBuf_H,
LONG lBuf_Bit,
BOOL bAlign)
{
if (pBuf == NULL)
{
return E_INVALIDARG;
}
BITMAPFILEHEADER bfh;
BITMAPINFOHEADER bih;
memset(&bih, 0, sizeof(bih));
bih.biSize = sizeof(bih);
bih.biPlanes = 1;
bih.biBitCount = (WORD)lBuf_Bit;
bih.biWidth = lBuf_W;
bih.biHeight = lBuf_H;
bih.biSizeImage = BmpPitchCB(&bih) * abs(bih.biHeight);
memset(&bfh, 0, sizeof(bfh));
bfh.bfType = ((WORD)('M' << 8) | 'B');
bfh.bfOffBits = 54;
bfh.bfSize = 54 + bih.biSizeImage;
// Correct the param
//
if (bAlign == false)
{
if (bih.biSizeImage == (DWORD)bih.biWidth * bih.biBitCount * abs(bih.biHeight) / 8)
{
bAlign = true;
}
}
//
HANDLE hFile = NULL;
do
{
hFile = CreateFile(
pFileName,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (hFile == NULL || hFile == INVALID_HANDLE_VALUE)
{
hFile = NULL;
break;
}
DWORD dwWrited = 0;
if (WriteFile(hFile, &bfh, sizeof(bfh), &dwWrited, NULL) == false)
{
break;
}
if (WriteFile(hFile, &bih, sizeof(bih), &dwWrited, NULL) == false)
{
break;
}
if (bAlign)
{
if (WriteFile(hFile, pBuf, bih.biSizeImage, &dwWrited, NULL) == false)
{
break;
}
}
else
{
// bitmap format pitch
// ...................................xxx for 32 bit aligned
//
const BYTE* pRow = static_cast<const BYTE*>(pBuf);
const LONG nRow = bih.biSizeImage / abs(bih.biHeight);
LONG n = 0;
for (n = abs(bih.biHeight); n > 1; n--)
{
if (!WriteFile(hFile, pRow, nRow, &dwWrited, NULL))
{
break;
}
pRow += bih.biWidth * bih.biBitCount / 8;
}
if (n != 1)
{
break;
}
if (!WriteFile(hFile, pRow, bih.biWidth * bih.biBitCount / 8, &dwWrited, NULL))
{
break;
}
LONG nPlus = nRow - bih.biWidth * bih.biBitCount / 8;
if (nPlus > 0)
{
if (!WriteFile(hFile, pRow, nPlus, &dwWrited, NULL))
{
break;
}
}
}
CloseHandle(hFile);
return S_OK;
} while (false);
if (hFile)
{
CloseHandle(hFile);
}
return E_FAIL;
}
2,获取图片buffer,并写成代码
UTextureRenderTarget2D* MediaRenderTarget;
FTextureResource* DstTextureRes = MediaRenderTarget->GetResource();
FTextureRHIRef DstTextureRef = DstTextureRes->TextureRHI;
FRHITexture* DstTexture = DstTextureRef->GetTexture2D();
//FRHITexture2D* DstTexture = CapturingRenderTarget->GetResource()->TextureRHI->GetTexture2D();
FIntRect RectTarget(0, 0, DstTexture->GetSizeX(), DstTexture->GetSizeY());
TArray<FColor> DataTarget;
ENQUEUE_RENDER_COMMAND(UPXMediaInputComponent_SaveToImageTarget)
([Texture = DstTexture, RectTarget, Data = &DataTarget](FRHICommandListImmediate& RHICmdList) mutable
{
RHICmdList.ReadSurfaceData(Texture, RectTarget, *Data, FReadSurfaceDataFlags(RCM_UNorm));
});
if (DataTarget.Num() == RectTarget.Area())
{
uint8* tempP = new uint8[RectTarget.Width() * RectTarget.Height() * 4];
for (int32 i = 0; i < RectTarget.Width() * RectTarget.Height(); i++)
{
tempP[i * 4] = DataTarget[i].B;
tempP[i * 4 + 1] = DataTarget[i].G;
tempP[i * 4 + 2] = DataTarget[i].R;
tempP[i * 4 + 3] = DataTarget[i].A;
}
SaveBmp(TEXT("D://RHIUpdateTextureReference.bmp"), tempP, RectTarget.Width(), RectTarget.Height(), 32, true);
}
二,使用UE提供的接口写png图片
1, FTextureResource写成图片
FTextureResource* rhiSource;
FRHITexture* DstTexture = rhiSource->GetTexture2DRHI();
//FRHITexture2D* DstTexture = CapturingRenderTarget->GetResource()->TextureRHI->GetTexture2D();
FIntRect Rect(0, 0, DstTexture->GetSizeX(), DstTexture->GetSizeY());
FString FilePath = TEXT("D://rhiSource.png");
TArray<FColor> Data;
ENQUEUE_RENDER_COMMAND(UPXMediaInputComponent_SaveToImage)
([Texture = DstTexture, Rect, Data = &Data](FRHICommandListImmediate& RHICmdList) mutable
{
RHICmdList.ReadSurfaceData(Texture, Rect, *Data, FReadSurfaceDataFlags(RCM_UNorm));
});
if (Data.Num() == Rect.Area())
{
TArray<uint8> Bitmap;
FImageUtils::ThumbnailCompressImageArray(Rect.Width(), Rect.Height(), Data, Bitmap);
FFileHelper::SaveArrayToFile(Bitmap, *FilePath);
}
2,UTextureRenderTarget2D写成图片
UTextureRenderTarget2D* CapturingRenderTarget = MediaRenderTarget;
if (CapturingRenderTarget)
{
FRHITexture2D* DstTexture = CapturingRenderTarget->GetResource()->TextureRHI->GetTexture2D();
FIntRect Rect(0, 0, DstTexture->GetSizeX(), DstTexture->GetSizeY());
TArray<FColor> Data;
ENQUEUE_RENDER_COMMAND(UPXMediaInputComponent_SaveToImage)
([Texture = DstTexture, Rect, Data = &Data](FRHICommandListImmediate& RHICmdList) mutable
{
RHICmdList.ReadSurfaceData(Texture, Rect, *Data, FReadSurfaceDataFlags(RCM_UNorm));
});
FlushRenderingCommands();
if (Data.Num() == Rect.Area())
{
TArray<uint8> Bitmap;
FImageUtils::ThumbnailCompressImageArray(Rect.Width(), Rect.Height(), Data, Bitmap);
FFileHelper::SaveArrayToFile(Bitmap, *FilePath);
}
}