
1.有时候使用UE4 的Http实现不了某些功能,所以就得想办法了,看一下自己写的ftp功能,
功能是接受图片,这功能如果使用的话就测试一下吧,我写的这个功能已经用到项目里面了.
下面就看代码吧.
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "AllowWindowsPlatformTypes.h"
#include <windows.h>
#include <wininet.h>
#include <iostream>
#include "HideWindowsPlatformTypes.h"
#include "Engine/Texture2DDynamic.h"
class IImageWrapper;
class UTexture2D;
/**
*
*/
class LoadImageFromFtp
{
public:
static UTexture2D* DownLoader(FString URL, FString localPath, TSharedPtr<IImageWrapper> ImageWrapperPtr);
private:
static LPCWSTR SwitchFromFString(FString strName);
static const int32 MAXBUFFER = 800000;
static UTexture2D* GetLocalTexture(void* imageData, int32 length, TSharedPtr<IImageWrapper> ImageWrapperPtr);
static TArray<FColor> uint8ToFColor(const TArray<uint8> origin);
static UTexture2D* TextureFromImage(const int32 SrcWidth, const int32 SrcHeight, const TArray<FColor> &SrcData, const bool UseAlpha);
};
下面是Cpp实现文件
// Fill out your copyright notice in the Description page of Project Settings.
#include "../ShooterGame/Public/HardInfo/LoadImageFromFtp.h"
#include "UnrealMemory.h"
#include "UdpSocketReceiver.h"
#include "IImageWrapperModule.h"
#include "IImageWrapper.h"
#include "Engine/Texture2D.h"
#pragma comment(lib,"wininet.lib")
typedef int BOOL;
#define FALSE 0
#define TRUE 1
using namespace std;
UTexture2D* LoadImageFromFtp::DownLoader(FString URL, FString localPath, TSharedPtr<IImageWrapper> ImageWrapperPtr)
{
UTexture2D* Texture = nullptr;
LPCWSTR lpURL = SwitchFromFString(URL);
LPCWSTR lpLocalPath = SwitchFromFString(localPath);
DWORD dwByteRead = 0;
char szDownBuffer[1024];
memset(szDownBuffer, 0, 1024);
BOOL bIntNetReadFile = TRUE;
BOOL bWriteFile = TRUE;
DWORD dwWritten = 0;
HINTERNET hintInternetOpen = InternetOpen(NULL, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
if (!hintInternetOpen)
{
InternetCloseHandle(hintInternetOpen);
return nullptr;
}
HINTERNET hintInternetOpenUrl = InternetOpenUrl(hintInternetOpen, lpURL, NULL, 0, INTERNET_FLAG_RELOAD, 0);
if (!hintInternetOpenUrl)
{
InternetCloseHandle(hintInternetOpen);
InternetCloseHandle(hintInternetOpenUrl);
return nullptr;
}
//是否读写到本地
/*HANDLE hCreateFile = CreateFile(lpLocalPath, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
if (hCreateFile == INVALID_HANDLE_VALUE)
{
InternetCloseHandle(hintInternetOpen);
InternetCloseHandle(hintInternetOpenUrl);
return nullptr;
}*/
static int32 currLength=0;
static uint8*ImageBuffer = new uint8[MAXBUFFER];
while (bIntNetReadFile /*&& bWriteFile*/)
{
bIntNetReadFile = InternetReadFile(hintInternetOpenUrl, szDownBuffer, sizeof(szDownBuffer), &dwByteRead);
FMemory::Memcpy(ImageBuffer + currLength, szDownBuffer, sizeof(szDownBuffer));
currLength += dwByteRead;
if (!dwByteRead)
{
Texture=GetLocalTexture(ImageBuffer, currLength, ImageWrapperPtr);
currLength = 0;
break;
}
/*bWriteFile = WriteFile(hCreateFile, szDownBuffer, sizeof(szDownBuffer), &dwWritten, NULL);
if (!dwWritten)
{
break;
}*/
}
return Texture;
}
LPCWSTR LoadImageFromFtp::SwitchFromFString(FString strName)
{
UE_LOG(LogTemp, Warning, TEXT("Path.....%s"), *strName);
std::string stdStrName(TCHAR_TO_UTF8(*strName));
size_t size = stdStrName.length();
wchar_t *buffer = new wchar_t[size + 1];
MultiByteToWideChar(CP_ACP, 0, stdStrName.c_str(), size, buffer, size * sizeof(wchar_t));
buffer[size] = 0; //确保以 '0' 结尾
return buffer;
}
//通过本地图片转换成UTexture2D
#pragma region
UTexture2D* LoadImageFromFtp::GetLocalTexture(void* imageData, int32 length, TSharedPtr<IImageWrapper> ImageWrapperPtr)
{
UTexture2D* OutTex = NULL;
if (ImageWrapperPtr.IsValid() && ImageWrapperPtr->SetCompressed(imageData, length))
{
const TArray<uint8>* uncompressedRGBA = NULL;
if (ImageWrapperPtr->GetRaw(ERGBFormat::RGBA, 8, uncompressedRGBA))
{
const TArray<FColor> uncompressedFColor = uint8ToFColor(*uncompressedRGBA);
OutTex = TextureFromImage(
ImageWrapperPtr->GetWidth(),
ImageWrapperPtr->GetHeight(),
uncompressedFColor,
true);
}
}
return OutTex;
}
#pragma endregion
//将uint8数组转为颜色数组
#pragma region
TArray<FColor> LoadImageFromFtp::uint8ToFColor(const TArray<uint8> origin)
{
TArray<FColor> uncompressedFColor;
uint8 auxOrigin;
FColor auxDst;
for (int i = 0; i < origin.Num(); i++) {
auxOrigin = origin[i];
auxDst.R = auxOrigin;
i++;
auxOrigin = origin[i];
auxDst.G = auxOrigin;
i++;
auxOrigin = origin[i];
auxDst.B = auxOrigin;
i++;
auxOrigin = origin[i];
auxDst.A = auxOrigin;
uncompressedFColor.Add(auxDst);
}
return uncompressedFColor;
}
#pragma endregion
//将颜色数组赋值给Texture
#pragma region
UTexture2D* LoadImageFromFtp::TextureFromImage(const int32 SrcWidth, const int32 SrcHeight, const TArray<FColor> &SrcData, const bool UseAlpha)
{
// 创建Texture2D纹理
UTexture2D* MyScreenshot = UTexture2D::CreateTransient(SrcWidth, SrcHeight, PF_B8G8R8A8);
// 锁住他的数据,以便修改
uint8* MipData = static_cast<uint8*>(MyScreenshot->PlatformData->Mips[0].BulkData.Lock(LOCK_READ_WRITE));
// 创建纹理数据
uint8* DestPtr = NULL;
const FColor* SrcPtr = NULL;
for (int32 y = 0; y < SrcHeight; y++)
{
DestPtr = &MipData[(SrcHeight - 1 - y) * SrcWidth * sizeof(FColor)];
SrcPtr = const_cast<FColor*>(&SrcData[(SrcHeight - 1 - y) * SrcWidth]);
for (int32 x = 0; x < SrcWidth; x++)
{
*DestPtr++ = SrcPtr->B;
*DestPtr++ = SrcPtr->G;
*DestPtr++ = SrcPtr->R;
if (UseAlpha)
{
*DestPtr++ = SrcPtr->A;
}
else
{
*DestPtr++ = 0xFF;
}
SrcPtr++;
}
}
// 解锁纹理
MyScreenshot->PlatformData->Mips[0].BulkData.Unlock();
MyScreenshot->UpdateResource();
return MyScreenshot;
}
#pragma endregion
功能已经在项目中使用了,欢迎大神指导.