UE5 DownloadImage加载jpg失败的解决方法

DownloadImage加载jpg失败的解决方法

  • 现象
  • 解决方案
    • 具体方法

现象

用UE自带的 DownloadImage 无法下载成功,从 failure 引脚出来。
接入一个由监控器自动保存起的图像,有些可以正常加载成功,有些无法加载成功。
经调查问题出现在,有些由监控摄像头保存起来的图片的格式不符合UE的格式要求。有可能是没有MipMap的设置。
所以无法通过 【FImageUtils::ImportBufferAsTexture2D】将下载下来的图片二进制数据转换成Texture2D;
也无法通过将 【FFileHelper::SaveArrayToFile(ImageData, SavePath)】保存好的图片,通过
【UTexture2D
Texture = FImageUtils::ImportFileAsTexture2D(ImagePath);】导入生成 UTexture2D

解决方案

自己写一个download的方法,下载到图片的二进制数据,然后通过一个开源库 【stb_image.h】将图片重写入一个Texture2D
,重写的过程可以设定所需的一些格式。

具体方法

写一个DownloadImage的http请求,然后再写一个请求回调的方法,在请求成功后将二进制数据进行读取并写入 UTexture2D 对象

引入第三方库
在【Source】文件夹中创建第三方库文件夹,然后放入下载的库文件。只需要下载这一个文件就够了
下载地址
在这里插入图片描述
配置build.cs
在build.cs里增加一个引用文件的配置
在这里插入图片描述
在一个actor或者 UBlueprintAsyncActionBase 的子类里编写调用方法

DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FDownloadAsyncNodeResult, UTexture2D*, tex2D);
/*** */
UCLASS()
class JGF_5_API UJGF_Http : public UBlueprintAsyncActionBase
{GENERATED_BODY()UPROPERTY(BlueprintAssignable)FDownloadAsyncNodeResult OnSuccess;UPROPERTY(BlueprintAssignable)FDownloadAsyncNodeResult OnFail;FTimerHandle TimerHandle;UFUNCTION(BlueprintCallable, meta = (WorldContext = "WorldContextObject"))static UJGF_Http* CallDownloadImage(UObject* WorldContextObject,  FString url,FString path="Data/DownloadImg/");uint16 checkCount=0;UTexture2D* Text2D;void DownloadImage(const FString& ImageURL, const FString& SavePath);void OnImageDownloadComplete(FHttpRequestPtr Request, FHttpResponsePtr Response, bool bWasSuccessful, FString SavePath);};

// Fill out your copyright notice in the Description page of Project Settings.#include "UtilityComponents/Http/JGF_Http.h"#include "HttpModule.h"
#include "ImageUtils.h"
#include "Interfaces/IHttpResponse.h"
#include "Kismet/GameplayStatics.h"
#include "ThirdParty/stb_image/stb_image.h"UJGF_Http* UJGF_Http::CallDownloadImage(UObject* WorldContextObject, FString url, FString path)
{auto node=NewObject<UJGF_Http>();FString FileName = FPaths::ConvertRelativePathToFull(FPaths::ProjectDir());FileName = FileName.Append(path);node ->DownloadImage(url,FileName);auto check=[node,WorldContextObject,url](){if(node->Text2D!=nullptr){node->OnSuccess.Broadcast(node->Text2D);WorldContextObject->GetWorld()->GetTimerManager().ClearTimer(node->TimerHandle);}else{node->checkCount++;if(node->checkCount>100){node->OnFail.Broadcast(nullptr);WorldContextObject->GetWorld()->GetTimerManager().ClearTimer(node->TimerHandle);}}};WorldContextObject->GetWorld()->GetTimerManager().SetTimer(node->TimerHandle,FTimerDelegate::CreateLambda(check),0.1f,true);return  node;
}void UJGF_Http::DownloadImage(const FString& ImageURL, const FString& SavePath)
{// 创建 HTTP 请求对象TSharedRef<IHttpRequest> HttpRequest = FHttpModule::Get().CreateRequest();HttpRequest->OnProcessRequestComplete().BindUObject(this, &UJGF_Http::OnImageDownloadComplete, SavePath);HttpRequest->SetURL(ImageURL);HttpRequest->SetVerb("GET");HttpRequest->SetHeader(TEXT("Content-Type"), TEXT("image/jpeg"));HttpRequest->ProcessRequest();
}void UJGF_Http::OnImageDownloadComplete(FHttpRequestPtr Request, FHttpResponsePtr Response, bool bWasSuccessful,FString SavePath)
{if (bWasSuccessful){// 获取图片数据const TArray<uint8>& ImageData = Response->GetContent();// 将数据转换为 `stb_image` 支持的格式int32 Width, Height, Channels;unsigned char* ImageData_1 = stbi_load_from_memory(ImageData.GetData(), ImageData.Num(), &Width, &Height, &Channels, 0);if (!ImageData_1){return;}UTexture2D* Texture = UTexture2D::CreateTransient(Width, Height);if (Texture){// 锁定 BulkData 以便修改FTexture2DMipMap& Mip = Texture->PlatformData->Mips[0];void* TextureData = Mip.BulkData.Lock(LOCK_READ_WRITE);// 根据图片通道数处理图像数据FColor* Pixels = new FColor[Width * Height];int32 PixelIndex = 0;for (int32 y = 0; y < Height; ++y){for (int32 x = 0; x < Width; ++x){int32 Index = (y * Width + x) * Channels;// 确保按照正确的通道顺序进行复制if (Channels == 4)  // RGBA{Pixels[PixelIndex++] = FColor(ImageData_1[Index + 0], ImageData_1[Index + 1], ImageData_1[Index + 2], ImageData_1[Index + 3]);}else if (Channels == 3)  // RGB, 默认 alpha = 255{Pixels[PixelIndex++] = FColor(ImageData_1[Index + 0], ImageData_1[Index + 1], ImageData_1[Index + 2], 255);}}}// 将像素数据复制到纹理中FMemory::Memcpy(TextureData, Pixels, Width * Height * sizeof(FColor));// 解锁 BulkDataMip.BulkData.Unlock();// 释放临时图像数据和像素数据stbi_image_free(ImageData_1);delete[] Pixels;// 更新纹理资源Texture->UpdateResource();}if(Texture)Text2D=Texture;//Text2D= FImageUtils::ImportBufferAsTexture2D(ImageData);// 保存到本地文件//FFileHelper::SaveArrayToFile(ImageData, *SavePath);// 调用处理和加载图片的函数//ProcessAndLoadImage(SavePath);}else{UE_LOG(LogTemp, Warning, TEXT("Image download failed"));}
}

代码说明
在这里插入图片描述

注 【SavePath】参数暂时无用,并没有保存到本地
在actor中调用【CallDownloadImage】进行下载
在进而调用了【DownloadImage】进行http下载文件
完成后回调到【OnImageDownloadComplete】,进行数据处理
处理过程中,直接将二进制图片数据通过stb_image库重新转化一遍成 char* ,写入 FColor 再在写入 UTexture2D 对象RGB

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/475826.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Elasticsearch 中的热点以及如何使用 AutoOps 解决它们

作者&#xff1a;来自 Elastic Sachin Frayne 探索 Elasticsearch 中的热点以及如何使用 AutoOps 解决它。 Elasticsearch 集群中出现热点的方式有很多种。有些我们可以控制&#xff0c;比如吵闹的邻居&#xff0c;有些我们控制得较差&#xff0c;比如 Elasticsearch 中的分片分…

Statsmodels之OLS回归

目录 Statsmodels基本介绍OLS 回归实战实战1&#xff1a;实战2&#xff1a; Statsmodels基本介绍 Statsmodels 是 Python 中一个强大的统计分析包&#xff0c;包含了回归分析、时间序列分析、假设检验等等的功能。Statsmodels 在计量的简便性上是远远不及 Stata 等软件的&…

【接口封装】—— 1、加载样式表

函数定义 static void loadStyleSheet(QWidget* widget, const QString &fileName,const QString& otherStyleQString());&#xff08;头文件&#xff09;&#xff1a; #include <qfile.h> #include <QWidget> 源文件: void CommonUtils::loadStyleSheet(…

AI、VR与空间计算:教育和文旅领域的数字转型力量

在这个数字技术高速发展的时代&#xff0c;AI、VR技术及大空间计算技术&#xff0c;已成为推动多个行业革新的强劲动力。近日&#xff0c;世优科技推出了最新研发的VR大空间产品《山海经》&#xff0c;这一全新的沉浸式体验项目不仅重新定义了观展方式&#xff0c;还为文化旅游…

AWTK 最新动态:支持鸿蒙系统(HarmonyOS Next)

HarmonyOS是全球第三大移动操作系统&#xff0c;有巨大的市场潜力&#xff0c;在国产替代的背景下&#xff0c;机会多多&#xff0c;AWTK支持HarmonyOS&#xff0c;让AWTK开发者也能享受HarmonyOS生态的红利。 AWTK全称为Toolkit AnyWhere&#xff0c;是ZLG倾心打造的一套基于C…

数据库、数据仓库、数据湖、数据中台、湖仓一体的概念和区别

数据库、数据仓库、数据湖、数据中台和湖仓一体是数据管理和分析领域的不同概念&#xff0c;各自有不同的特点和应用场景。以下是它们的主要区别&#xff1a; 1. 数据库&#xff08;Database&#xff09; 定义&#xff1a;结构化的数据存储系统&#xff0c;用于高效地存储、检…

Linux运维篇-iscsi存储搭建

目录 概念实验介绍环境准备存储端软件安装使用targetcli来管理iSCSI共享存储 客户端软件安装连接存储 概念 iSCSI是一种在Internet协议上&#xff0c;特别是以太网上进行数据块传输的标准&#xff0c;它是一种基于IP Storage理论的存储技术&#xff0c;该技术是将存储行业广泛…

Django一分钟:django中收集关联对象关联数据的方法

场景&#xff1a;我有一个模型&#xff0c;被其它多个模型关联&#xff0c;我配置了CASCADE级联删除&#xff0c;我想要告知用户删除该实例之后&#xff0c;哪些关联数据将会被一同删除。 假设我们当前有这样一组模型&#xff1a; class Warehouse(models.Model):""…

iPhone 17 Air看点汇总:薄至6mm 刷新苹果轻薄纪录

我们姑且将这款iPhone 17序列的超薄SKU称为“iPhone 17 Air”&#xff0c;Jeff Pu在报告中提到&#xff0c;我同意最近关于 iPhone 17超薄机型采用6 毫米厚度超薄设计的传言。 如果这一测量结果被证明是准确的&#xff0c;那么将有几个值得注意的方面。 首先&#xff0c;iPhone…

Tcp协议Socket编程

&#x1f30e; Tcp协议Socket编程 本次socket编程需要使用到 日志文件&#xff0c;此为具体日志编写过程。以及 线程池&#xff0c;线程池原理比较简单&#xff0c;看注释即可。 文章目录&#xff1a; Tcp协议Socket编程 TCP Socket API简介 构建Tcp_echo_server      …

嵌入式系统中QT实现网络通信方法

大家好,今天主要给大家分享一下,如何使用QT中的网络编程实现。 第一:QT网络编程基本简介 QT中网络模块为提供了可以使用TCP/IP客户端与服务器的类。它提供了较低级别的类,例如代表低级网络概念的 QTcpSocket, QTcpServer 和 QUdpSocket,以及诸如 QNetworkRequest, QNetw…

【卡尔曼滤波】数据预测Prediction观测器的理论推导及应用 C语言、Python实现(Kalman Filter)

【卡尔曼滤波】数据预测Prediction观测器的理论推导及应用 C语言、Python实现&#xff08;Kalman Filter&#xff09; 更新以gitee为准&#xff1a; 文章目录 数据预测概念和适用方式线性系统的适用性 数据预测算法和卡尔曼滤波公式推导状态空间方程和观测器先验估计后验估计…

大模型时代的具身智能系列专题(十三)

迪士尼研究中心 瑞士苏黎世迪斯尼研究中心致力于不同领域的业务活动&#xff0c;其中包括电影、电视、公园和度假村以及消费产品。我们针对所有这些领域进行科研工作。我们开发能使我们将后道生产元素整合到前级生产中的技术。由此可节省许多昂贵的效果&#xff0c;这些效果最…

IDEA2023设置控制台日志输出到本地文件

1、Run->Edit Configurations 2、选择要输出日志的日志&#xff0c;右侧&#xff0c;IDEA2023的Logs在 Modify option 里 选中就会展示Logs栏。注意一定要先把这个日志文件创建出来&#xff0c;不然不会自动创建日志文件的 IDEA以前版本的Logs会直接展示出来 3、但是…

o1的风又吹到多模态,直接吹翻了GPT-4o-mini

开源LLaVA-o1&#xff1a;一个设计用于进行自主多阶段推理的新型VLM。与思维链提示不同&#xff0c;LLaVA-o1独立地参与到总结、视觉解释、逻辑推理和结论生成的顺序阶段。 LLaVA-o1超过了一些更大甚至是闭源模型的性能&#xff0c;例如Gemini-1.5-pro、GPT-4o-mini和Llama-3.…

AJAX的基本使用

AJAX的基本使用 &#x1f389;&#x1f389;&#x1f389;欢迎来到我的博客,我是一名自学了2年半前端的大一学生,熟悉的技术是JavaScript与Vue.目前正在往全栈方向前进, 如果我的博客给您带来了帮助欢迎您关注我,我将会持续不断的更新文章!!!&#x1f64f;&#x1f64f;&#x…

DDei在线设计器V1.2.43版发布

2024-11-21-----V1.2.43 一、bug 修复 1. 修复只读情况下&#xff0c;连线依然可以通过特殊点调整的 bug 2. 修复了同一页面多个实例时&#xff0c;部分方法只会引用最后一个实例的问题 3. 修复了组合控件和容器控件改变容器后没有清理的问题&#xff0c;优化了容器的实现 4. …

C++进阶:哈希表实现

目录 一:哈希表的概念 1.1直接定址法 1.2哈希冲突 1.3负载因子 1.4实现哈希函数的方法 1.4.1除法散列法/除留余数法 1.4.2乘法散列法 1.4.3全域散列法 1.5处理哈希冲突 1.5.1开放地址法 线性探测 二次探测 ​编辑 双重散列 1.5.2链地址法 二.代码实现 2.1开放地址…

鸿蒙NEXT开发案例:血型遗传计算

【引言】 血型遗传计算器是一个帮助用户根据父母的血型预测子女可能的血型的应用。通过选择父母的血型&#xff0c;应用程序能够快速计算出孩子可能拥有的血型以及不可能拥有的血型。这个过程不仅涉及到了简单的数据处理逻辑&#xff0c;还涉及到UI设计与交互体验的设计。 【…

(十八)JavaWeb后端开发案例——会话/yml/过滤器/拦截器

目录 1.业务逻辑实现 1.1 登录校验技术——会话 1.1.1Cookie 1.1.2session 1.1.3JWT令牌技术 2.参数配置化 3.yml格式配置文件 4.过滤器Filter 5.拦截器Interceptor 1.业务逻辑实现 Day10-02. 案例-部门管理-查询_哔哩哔哩_bilibili //Controller层/*** 新增部门*/Pos…