(商店版引擎的实用方案,源码版的去改源码实现更快)
1.准备工作:
-
UE4C++项目中创建新的C++异步任务类继承自:BlueprintAsyncActionBase
2.添加模块并编写代码:
- 项目Build.cs中添加模块:HTTP,ImageWrapper,RHI(未使用可不添加)
.h头文件中:
#pragma once
#include "CoreMinimal.h"
#include "UObject/ObjectMacros.h"
#include "Interfaces/IHttpRequest.h"
#include "Kismet/BlueprintAsyncActionBase.h"
#include "Modules/ModuleManager.h"
#include "Engine/Texture2D.h"
#include "Engine/Texture2DDynamic.h"
#include "IImageWrapper.h"
#include "IImageWrapperModule.h"
#include "RuntimeOnlineHTTPPublicInterfacesIHttpResponse.h"
#include "RuntimeOnlineHTTPPublicHttpModule.h"
#include "RuntimeEngineClassesKismetKismetStringLibrary.h"
#include
#include
#include "BAATask.generated.h"
class UTexture2DDynamic;//useless
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FDownloadImageDelegateMY, UTexture2D*, Texture);
UCLASS()
class CQSHUILINEW_API UBAATask : public UBlueprintAsyncActionBase
{
GENERATED_BODY()
public:
UBAATask(const FObjectInitializer& ObjectInitializer);
UFUNCTION(BlueprintCallable, meta = (BlueprintInternalUseOnly = "true"))
static UBAATask* DownloadImage(FString URL,FString Token);
public:
UPROPERTY(BlueprintAssignable)
FDownloadImageDelegateMY Success;
UPROPERTY(BlueprintAssignable)
FDownloadImageDelegateMY Fail;
public:
FString IMGurl="";
void Start(FString URL,FString Token);
UTexture2D* GetTexture(TSharedPtr ImageWrapper, FHttpResponsePtr HttpResponse);
void HandleImageRequest(FHttpRequestPtr HttpRequest, FHttpResponsePtr HttpResponse, bool bSucceeded);
};
- .cpp中:
#include "BAATask.h"
#include
#include
#include
#include
using namespace std;
UBAATask::UBAATask(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
{
if (HasAnyFlags(RF_ClassDefaultObject) == false)
{
AddToRoot();
}
}
UBAATask* UBAATask::DownloadImage(FString URL,FString Token)
{
UBAATask* DownloadTask = NewObject();
DownloadTask->Start(URL,Token);
return DownloadTask;
}
void UBAATask::Start(FString URL,FString Token)
{
#if !UE_SERVER
TSharedRef HttpRequest = FHttpModule::Get().CreateRequest();
HttpRequest->OnProcessRequestComplete().BindUObject(this, &UBAATask::HandleImageRequest);
FString Lurl="";
FString Rurl="";
FString Unuse="";//useless value
UKismetStringLibrary::Split(URL, "/", Lurl, Rurl, ESearchCase::IgnoreCase, ESearchDir::FromEnd);
UKismetStringLibrary::Split(Rurl, "/", Unuse, Rurl, ESearchCase::IgnoreCase, ESearchDir::FromEnd);
//URL encode For Chinese(UTF-8)
ostringstream escaped;
escaped.fill('0');
escaped << hex;
string vaule= TCHAR_TO_UTF8(*Rurl);
for (string::const_iterator i = vaule.begin(), n = vaule.end(); i != n; ++i) {
string::value_type c = (*i);
if (isalnum(c) || c == '-' || c == '_' || c == '.' || c == '~') {
escaped << c;
continue;
}
escaped << uppercase;
escaped << '%' << setw(2) << int((unsigned char)c);
escaped << nouppercase;
}
HttpRequest->SetURL(Lurl + "/" + FString(escaped.str().c_str()));//urlencode2fstring
IMGurl =URL;//For bool if jpg or png
HttpRequest->SetVerb(TEXT("GET"));
HttpRequest->SetHeader(TEXT("X-Access-Token"), Token);//in Token
HttpRequest->ProcessRequest();
#else
RemoveFromRoot();
#endif
}
void UBAATask::HandleImageRequest(FHttpRequestPtr HttpRequest, FHttpResponsePtr HttpResponse, bool bSucceeded)
{
UTexture2D* Texture = nullptr;//create Texture2D
IImageWrapperModule& module = FModuleManager::LoadModuleChecked(FName("ImageWrapper"));
if(UKismetStringLibrary::Contains(*IMGurl,TEXT(".jpg"),ESearchCase::IgnoreCase,ESearchDir::FromStart)|| UKismetStringLibrary::Contains(*IMGurl, TEXT(".jpeg"), ESearchCase::IgnoreCase, ESearchDir::FromStart))
{
TSharedPtr ImageWrapper = module.CreateImageWrapper(EImageFormat::JPEG);
Texture = GetTexture(ImageWrapper,HttpResponse);
Success.Broadcast(Texture);//success return texture2d
return;
}else if(UKismetStringLibrary::Contains(*IMGurl, TEXT(".png"), ESearchCase::IgnoreCase, ESearchDir::FromStart))
{
TSharedPtr ImageWrapper = module.CreateImageWrapper(EImageFormat::PNG);
Texture = GetTexture(ImageWrapper, HttpResponse);
Success.Broadcast(Texture);//success return texture2d
return;
}
Fail.Broadcast(nullptr);//fail nullptr
}
UTexture2D* UBAATask::GetTexture(TSharedPtr ImageWrapper, FHttpResponsePtr HttpResponse)
{
if (ImageWrapper->SetCompressed(HttpResponse->GetContent().GetData(), HttpResponse->GetContentLength()))
{
TArray UncompressedRGBA;
if (ImageWrapper->GetRaw(ERGBFormat::RGBA, 8, UncompressedRGBA))
{
UTexture2D* Texture = UTexture2D::CreateTransient(ImageWrapper->GetWidth(), ImageWrapper->GetHeight(), PF_R8G8B8A8);
if (Texture != nullptr)
{
//int OutWidth = ImageWrapper->GetWidth();//w&h
//int OutHeight = ImageWrapper->GetHeight();
void* TextureData = Texture->PlatformData->Mips[0].BulkData.Lock(LOCK_READ_WRITE);
FMemory::Memcpy(TextureData, UncompressedRGBA.GetData(), UncompressedRGBA.Num());
Texture->PlatformData->Mips[0].BulkData.Unlock();
Texture->UpdateResource();
return Texture;
}
}
}
return nullptr;
}
3.编译后蓝图传入地址与Token处理成功设置笔刷:
后言:考虑到验证访问地址图片时URL中带有中文时需要urlencode进行转码后转回Fstring才能正常访问地址,把图片处理单独写成一个函数便于处理不同格式的图片; - 希望这篇文章能帮到你!
UE4C++项目中创建新的C++异步任务类继承自:BlueprintAsyncActionBase
#include "BAATask.h" #include3.编译后蓝图传入地址与Token处理成功设置笔刷:#include #include #include using namespace std; UBAATask::UBAATask(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer) { if (HasAnyFlags(RF_ClassDefaultObject) == false) { AddToRoot(); } } UBAATask* UBAATask::DownloadImage(FString URL,FString Token) { UBAATask* DownloadTask = NewObject (); DownloadTask->Start(URL,Token); return DownloadTask; } void UBAATask::Start(FString URL,FString Token) { #if !UE_SERVER TSharedRef HttpRequest = FHttpModule::Get().CreateRequest(); HttpRequest->OnProcessRequestComplete().BindUObject(this, &UBAATask::HandleImageRequest); FString Lurl=""; FString Rurl=""; FString Unuse="";//useless value UKismetStringLibrary::Split(URL, "/", Lurl, Rurl, ESearchCase::IgnoreCase, ESearchDir::FromEnd); UKismetStringLibrary::Split(Rurl, "/", Unuse, Rurl, ESearchCase::IgnoreCase, ESearchDir::FromEnd); //URL encode For Chinese(UTF-8) ostringstream escaped; escaped.fill('0'); escaped << hex; string vaule= TCHAR_TO_UTF8(*Rurl); for (string::const_iterator i = vaule.begin(), n = vaule.end(); i != n; ++i) { string::value_type c = (*i); if (isalnum(c) || c == '-' || c == '_' || c == '.' || c == '~') { escaped << c; continue; } escaped << uppercase; escaped << '%' << setw(2) << int((unsigned char)c); escaped << nouppercase; } HttpRequest->SetURL(Lurl + "/" + FString(escaped.str().c_str()));//urlencode2fstring IMGurl =URL;//For bool if jpg or png HttpRequest->SetVerb(TEXT("GET")); HttpRequest->SetHeader(TEXT("X-Access-Token"), Token);//in Token HttpRequest->ProcessRequest(); #else RemoveFromRoot(); #endif } void UBAATask::HandleImageRequest(FHttpRequestPtr HttpRequest, FHttpResponsePtr HttpResponse, bool bSucceeded) { UTexture2D* Texture = nullptr;//create Texture2D IImageWrapperModule& module = FModuleManager::LoadModuleChecked (FName("ImageWrapper")); if(UKismetStringLibrary::Contains(*IMGurl,TEXT(".jpg"),ESearchCase::IgnoreCase,ESearchDir::FromStart)|| UKismetStringLibrary::Contains(*IMGurl, TEXT(".jpeg"), ESearchCase::IgnoreCase, ESearchDir::FromStart)) { TSharedPtr ImageWrapper = module.CreateImageWrapper(EImageFormat::JPEG); Texture = GetTexture(ImageWrapper,HttpResponse); Success.Broadcast(Texture);//success return texture2d return; }else if(UKismetStringLibrary::Contains(*IMGurl, TEXT(".png"), ESearchCase::IgnoreCase, ESearchDir::FromStart)) { TSharedPtr ImageWrapper = module.CreateImageWrapper(EImageFormat::PNG); Texture = GetTexture(ImageWrapper, HttpResponse); Success.Broadcast(Texture);//success return texture2d return; } Fail.Broadcast(nullptr);//fail nullptr } UTexture2D* UBAATask::GetTexture(TSharedPtr ImageWrapper, FHttpResponsePtr HttpResponse) { if (ImageWrapper->SetCompressed(HttpResponse->GetContent().GetData(), HttpResponse->GetContentLength())) { TArray UncompressedRGBA; if (ImageWrapper->GetRaw(ERGBFormat::RGBA, 8, UncompressedRGBA)) { UTexture2D* Texture = UTexture2D::CreateTransient(ImageWrapper->GetWidth(), ImageWrapper->GetHeight(), PF_R8G8B8A8); if (Texture != nullptr) { //int OutWidth = ImageWrapper->GetWidth();//w&h //int OutHeight = ImageWrapper->GetHeight(); void* TextureData = Texture->PlatformData->Mips[0].BulkData.Lock(LOCK_READ_WRITE); FMemory::Memcpy(TextureData, UncompressedRGBA.GetData(), UncompressedRGBA.Num()); Texture->PlatformData->Mips[0].BulkData.Unlock(); Texture->UpdateResource(); return Texture; } } } return nullptr; }
后言:考虑到验证访问地址图片时URL中带有中文时需要urlencode进行转码后转回Fstring才能正常访问地址,把图片处理单独写成一个函数便于处理不同格式的图片;



