想要在网络中传输媒体资源,就需要将媒体资源转为二进制数据。这里以简单的图片为例,将UE4中的UTexture2D资产转为TArray类型。这篇笔记不详细讲原理,只放代码。
**读取图片的颜色信息
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
|
bool UTextureToolsBPLibrary::TextureToColorData(TArray<FColor>& colorDataPtr, int& outW, int& outh, UTexture2D* Texture)
{
colorDataPtr.Reset();
outW = outh = 0;
if (!Texture)return false;
FIntPoint Size = FIntPoint::ZeroValue;
bool bReadSuccess = true;
TArray<uint8> RawData;
EPixelFormat Format;
bool bInEditorExec = false;
TArray<uint8*> RawData2;
Size = FIntPoint(Texture->GetPlatformData()->SizeX, Texture->GetPlatformData()->SizeY);
RawData2.AddZeroed(Texture->GetNumMips());
Texture->GetMipData(0, (void**)RawData2.GetData());
const EPixelFormat NewFormat = Texture->GetPixelFormat();
if (Texture->GetPlatformData()->Mips.Num() == 0)
{
bReadSuccess = false;
}
if (NewFormat == PF_B8G8R8A8)
{
Format = PF_B8G8R8A8;
}
else if (NewFormat == PF_FloatRGBA)
{
Format = PF_FloatRGBA;
}
else
{
bReadSuccess = false;
}
//Put first mip data into usable array
if (bReadSuccess)
{
//这里的二进制数据RawData,无法直接使用KismetRenderingLibrary::ImportBufferAsTexture()将其转为Texture,会提示未指定图片的格式。
uint32 TotalSize = Texture->GetPlatformData()->Mips[0].BulkData.GetElementCount();
RawData.AddZeroed(TotalSize);
FMemory::Memcpy(RawData.GetData(), RawData2[0], TotalSize);
}
//Deallocate the mip data
for (auto MipData : RawData2)
{
FMemory::Free(MipData);
}
outW = Size.X;
outh = Size.Y;
uint32 datalen = outW * outh;
if (datalen <= 1)return false;
colorDataPtr.Init(FColor::White, datalen);
if (!bReadSuccess)return false;
uint32 temp = 0;
for (uint32 i = 0; i < datalen; i++)
{
//逐素拷贝
colorDataPtr[i].B = RawData[temp];
temp++;
colorDataPtr[i].G = RawData[temp];
temp++;
colorDataPtr[i].R = RawData[temp];
temp++;
colorDataPtr[i].A = RawData[temp];
temp++;
}
return true;
}
|
将颜色信息转为二进制数据
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
bool UTextureToolsBPLibrary::ColorDataToBinaryData(TArray<uint8>& OutDatas, TArray<FColor> SourceColorData, int SizeX, int SizeY, int32 Quality)
{
if (SizeX * SizeY <= 0 || SourceColorData.Num() < 1)return false;
IImageWrapperModule& ImageWrapperModule = FModuleManager::LoadModuleChecked<IImageWrapperModule>(FName("ImageWrapper"));
TSharedPtr<IImageWrapper> ImageWrapper = ImageWrapperModule.CreateImageWrapper(EImageFormat::JPEG);
int l = SizeX * SizeY * sizeof(FColor);
if (ImageWrapper->SetRaw(SourceColorData.GetData(), l, SizeX, SizeY, ERGBFormat::BGRA, 8))
{
OutDatas.Empty();
OutDatas = ImageWrapper->GetCompressed(Quality);
ImageWrapper.Reset();
return true;
}
ImageWrapper.Reset();
return false;
}
|
包含模块和头文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
#include "IImageWrapper.h"
#include "IImageWrapperModule.h"
//.Build.cs文件中包含 "ImageWrapper"模块
PrivateDependencyModuleNames.AddRange(
new string[]
{
"CoreUObject",
"Engine",
"Slate",
"SlateCore",
"ImageWrapper",
// ... add private dependencies that you statically link with here ...
}
);
|
将二进制数据转为UTexture2D数据
//#include “Kismet/KismetRenderingLibrary.h”
//可以使用UKismetRenderingLibrary库中现有的函数
UTexture2D* UKismetRenderingLibrary::ImportBufferAsTexture2D(UObject* WorldContextObject, const TArray& Buffer)
读取RenderTarget2D的颜色信息(TArray)
//#include “Kismet/KismetRenderingLibrary.h”
//可以使用UKismetRenderingLibrary库中现有的函数
1
|
bool UKismetRenderingLibrary::ReadRenderTarget(UObject* WorldContextObject, UTextureRenderTarget2D* TextureRenderTarget, TArray<FColor>& OutSamples, bool bNormalize)
|
有了这些函数可以将图片在网络中进行传输,