Ara you OK?
我看你是思想出现了偏差
哇!你认出了错别单词!恭喜你获得一次向我支付宝充值助我重返欧洲的机会!
这个页面管关不掉了,你自己看着办吧

UE4笔记-C++使用Http网络请求下载JPG图片并创建生成UTexture2D纹理示例(jpg/png/HDR等)

备忘,C++做逻辑真是又臭又长👴

P.S:UE的Http模块相对简陋,可以集成cpr库模块,进行网络请求操作.

 Note:例子没有生成Mipmap,如果用于游戏场景会有摩尔效应,生成Mipmap方法可参考:https://github.com/linqingwudiv1/QCorePlugin/blob/master/Source/QCorePlugin/Helper/ImageHelper.cpp

例子中的UCoreBPLibrary::UrlEncode函数可参考:

https://www.cnblogs.com/linqing/p/5321317.html

补充个示例用到的正则函数:

bool UCoreBPLibrary::RegexMatch(const FString& Str, const FString& Pattern, TArray<FString>& Result)
{
    FRegexPattern MatherPatter(Pattern);
    FRegexMatcher Matcher(MatherPatter, Str);

    while (Matcher.FindNext())
    {
        Result.Add(Matcher.GetCaptureGroup(0));

    }

    return Result.Num() == 0 ? false : true;
}

 

 

-------------------------------------------------------------------------------

使用示例:

因为我是放单例里用就没考虑回收的问题,可以继承下UObject.或用完手动回收一下..

 Note:这里仅演示,存在内存泄漏

    FDownloadImageHelper* helper = new FDownloadImageHelper ();

    helper->OnDownloadCompleted().AddLambda([&](bool isSuccessful, UTexture2D *t2d)
    {
        if (!isSuccessful)
        {
            return;
        }
        //your logic...
        this->t2d_basecolor = t2d;
        this->m_primaryMat->SetTextureParameterValue(FName{ TEXT("basecolor") }, t2d);
    });

    helper->Start(TEXT("http://www.wakelu.com/test中文.png"));

 

 

主要依赖模块:

"HTTP",
"Networking",
"ImageWrapper"

 

HTTP封装类:

NetAPI.h

 #pragma once


#include "CoreMinimal.h" #include "UObject/NoExportTypes.h" #include "Http.h" #include "NetAPI.generated.h" /** * */ UCLASS() class LQCOREPLUGIN_API UNetAPI : public UObject { GENERATED_BODY() public: //Setting.eg timeout/delay time/once read max buffer static FHttpModule* GetHttpModule(); static FHttpManager& GetHttpMgr(); //UFUNCTION() static TSharedRef<IHttpRequest> createRequst(FString _url, FString _method = TEXT("GET"), FString _content = TEXT(""), FString _contentType = TEXT("text/html;charset=UTF-8")); static TSharedRef<IHttpRequest> createUploadImageRequest(FString _url, TArray<uint8>& rawData); };

NetAPI.cpp:

#include "NetAPI.h"

#include "NetAPI.h"
#include "Http.h"

FHttpModule* UNetAPI::GetHttpModule()
{
    static FHttpModule* httpModule = NULL;

    if (httpModule == NULL )
    {
        httpModule = &FHttpModule::Get();
        httpModule->SetHttpTimeout( 60 );
        httpModule->SetMaxReadBufferSize( 1024 * 1024 * 50 );
        httpModule->SetHttpDelayTime( 0.001 );
        //temp_module->AddDefaultHeader(TEXT("Cache-Control"), TEXT("no-cache"));
    }
    return httpModule;
}

FHttpManager& UNetAPI::GetHttpMgr()
{
    return UNetAPI::GetHttpModule()->GetHttpManager();
}

TSharedRef<IHttpRequest> UNetAPI::createRequst(FString _url, FString _method, FString _content, FString _contentType)
{
    TSharedRef<IHttpRequest> ret_request = UNetAPI::GetHttpModule()->CreateRequest();

    ret_request->SetHeader(TEXT("Content-Type"), _contentType);
    ret_request->SetURL(_url);

    ret_request->SetVerb(_method);

    if ( _method == TEXT("POST") )
    {
        ret_request->SetContentAsString(_content);
    }

    return ret_request;
}

TSharedRef<IHttpRequest> UNetAPI::createUploadImageRequest(FString _url, TArray<uint8>& rawData)
{
    TSharedRef<IHttpRequest> ret_request = UNetAPI::GetHttpModule()->CreateRequest();

    ret_request->SetURL(_url);
    ret_request->SetHeader(TEXT("Content-Type"), TEXT("text/html;charset=UTF-8"));

    ret_request->SetVerb(TEXT("POST"));
    ret_request->SetContent(rawData);

    return ret_request;
}

 

下载图片帮助类:

DownloadImageHelper.h:

#pragma once

#include "CoreMinimal.h"
#include "IImageWrapper.h"

#include "Interfaces/IHttpRequest.h"
#include "Engine/Texture2D.h"

/**
 * 
 */
class LQCOREPLUGIN_API FDownloadImageHelper 
{
public:
    FDownloadImageHelper();
    ~FDownloadImageHelper();
    void Start(const FString &Url);
    void Start(const FString &Url, UObject *target,void(UObject::* bindfunc)(bool, UTexture2D *));
public:
    DECLARE_EVENT_TwoParams(FString, FOnDownloadCompleted, bool, UTexture2D*);
    FOnDownloadCompleted& OnDownloadCompleted() 
    {
        return Event_OnDownloadCompleted;
    }

protected:

#pragma region Http Event Handle
    void Http_HandleCompleted(FHttpRequestPtr Req, FHttpResponsePtr Res, bool bConnectedSuccessfully);
#pragma endregion

protected:
    FOnDownloadCompleted Event_OnDownloadCompleted;

};

 

DownloadImageHelper.cpp:

#include "DownloadImageHelper.h"

#include "CoreBPLibrary.h"

#include "API/NetAPI.h"
#include "Modules/ModuleManager.h"
#include "IImageWrapperModule.h"

FDownloadImageHelper::FDownloadImageHelper()
{

}

FDownloadImageHelper::~FDownloadImageHelper()
{
}

void FDownloadImageHelper::Start(const FString &Url)
{
    FString encodeUrl = UCoreBPLibrary::UrlEncode(Url);

    //中文转码
    auto req = UNetAPI::createRequst(encodeUrl, TEXT("GET"), TEXT("application/octet-stream;image/png;image/jpeg;"));

    req->OnProcessRequestComplete().BindRaw(this, &FDownloadImageHelper::Http_HandleCompleted);

    if (!req->ProcessRequest())
    {
        UE_LOG(LogHttp, Error, TEXT("----------------------- request Process Request invaild"));
    }
}

void FDownloadImageHelper::Start(const FString & Url, UObject *target, void(UObject::* bindfunc)(bool, UTexture2D *))
{
    this->OnDownloadCompleted().AddUObject(target, bindfunc);
    this->Start(Url);
}

void FDownloadImageHelper::Http_HandleCompleted(FHttpRequestPtr Req, FHttpResponsePtr Res, bool bConnectedSuccessfully)
{
    FString Url = Req->GetURL();
    if (!bConnectedSuccessfully || !Res.IsValid() || Res->GetResponseCode() != 200)
    {
        UE_LOG( LogHttp, Error, TEXT("-------- : req occur error from Url {%s} : error info: {%s}."), *Url, *(Res->GetContentAsString()) );
        this->OnDownloadCompleted().Broadcast(false, nullptr);
        return;
    }



#pragma region 从Url判断图片类型/NOte:也可以从Content-Type中判断
    EImageFormat ImageFormat = EImageFormat::JPEG;
    {


        TArray<FString> arr_regex;

        bool isJPG = UCoreBPLibrary::RegexMatch(Url, TEXT(".\\.jpg$|.\\.jpeg$|.\\.jpe$"), arr_regex);
        arr_regex.Empty();
        bool isPNG = UCoreBPLibrary::RegexMatch(Url, TEXT(".\\.png$"), arr_regex);
        arr_regex.Empty();
        bool isHDR = UCoreBPLibrary::RegexMatch(Url, TEXT(".\\.exr$|.\\.hdr$"), arr_regex);
        arr_regex.Empty();

        if (isPNG)
        {
            ImageFormat = EImageFormat::PNG;
        }

        if (isJPG)
        {
            ImageFormat = EImageFormat::JPEG;
        }

        if (isHDR)
        {
            ImageFormat = EImageFormat::EXR;
        }
    }

#pragma endregion


    TArray<uint8> binarayData = Res->GetContent();
    IImageWrapperModule& ImageWrapperModule = FModuleManager::LoadModuleChecked<IImageWrapperModule>(FName("ImageWrapper"));
    TSharedPtr<IImageWrapper> ImageWrapper = ImageWrapperModule.CreateImageWrapper(ImageFormat);

    if (!ImageWrapper.IsValid() ||
        !ImageWrapper->SetCompressed(binarayData.GetData(), binarayData.Num()))
    {
        UE_LOG(LogHttp, Error, TEXT("ImageWrapper can't Set Compressed or ImageWrapper is InValid"));
        this->OnDownloadCompleted().Broadcast(false, nullptr);
        return;
    }

    const TArray<uint8>* rawData = nullptr;
    UTexture2D* LoadedT2D = nullptr;
    void* TextureData = nullptr;

    if (!ImageWrapper->GetRaw(ERGBFormat::BGRA, 8, rawData))
    {
        UE_LOG(LogTemp, Warning, TEXT("can't get Raw temp_unCompressedRGBA"));
        this->OnDownloadCompleted().Broadcast(false, nullptr);
        return;
    }

#pragma region 创建T2D
    int32 w = ImageWrapper->GetWidth();
    int32 h = ImageWrapper->GetHeight();
    LoadedT2D = UTexture2D::CreateTransient(w, h, PF_B8G8R8A8);
#pragma endregion

#pragma region 内存拷贝
    TextureData = LoadedT2D->PlatformData->Mips[0].BulkData.Lock(LOCK_READ_WRITE);
    FMemory::Memcpy(TextureData, rawData->GetData(), rawData->Num());
#pragma endregion

#pragma region 更新T2D
    LoadedT2D->PlatformData->Mips[0].BulkData.Unlock();
    LoadedT2D->UpdateResource();
#pragma endregion
    this->OnDownloadCompleted().Broadcast( true, LoadedT2D);
}

 

posted @ 2015-12-29 08:57  林清  阅读(6568)  评论(0编辑  收藏  举报