氿 柒 2024-06-21 10:17 采纳率: 0%
浏览 18
已结题

unity腾讯云对象存储机型适配

我从腾讯云的对象存储中下载图片加载到unity中去显示,为什么有的机型可以正常显示(魅族),有的机型不能正常显示我的图片(华为)
代码如下,图片是png格式,同一网络下测试

using UnityEngine;
using UnityEngine.UI;
using System.IO;
using System.Threading.Tasks;
using UnityEngine.EventSystems;
using COSXML;
using COSXML.Auth;
using COSXML.Model.Object;
using COSXML.Transfer;

using System.Collections.Generic;

public class Dowlongd_show : MonoBehaviour
{
    public Button uploadButton;
    public RawImage rawImagePrefab; // 引用RawImage预制体
    public Canvas canvas;

    private CosXml cosXml;
    private List<string> imageNames = new List<string>(); // 添加一个列表存储要下载的图片名字

    public Text myText7;//测试
    public Text myText8;//测试
    public Text myText9;//测试

    void Start()
    {
        uploadButton.onClick.AddListener(OnUploadButtonClick);

        //初始化 CosXmlConfig 
        CosXmlConfig config = new CosXmlConfig.Builder()
             .IsHttps(true)  //设置默认 HTTPS 请求
            .SetRegion("ap-nanjing") // 替换为实际的COS地域简称->设置一个默认的存储桶地域
            .SetDebugLog(true)  //显示日志
            .Build();

        string secretId = "AKIDOk1C##############zKuU8ocaejo2H"; // 替换为实际的SecretId
        string secretKey = "IUrGjO8xw3###################xZChZ"; // 替换为实际的SecretKey
        long durationSecond = 600;//每次请求签名有效时长,单位为秒

        QCloudCredentialProvider qCloudCredentialProvider = new DefaultQCloudCredentialProvider(secretId, secretKey, durationSecond);

        cosXml = new CosXmlServer(config, qCloudCredentialProvider);// 初始化 CosXmlServer

        // 假设要下载以下三张图片,实际使用时请替换为您的图片名字列表
        imageNames.Add("image/Img_1(Clone)_(-196.0, -47.4)_(330.0, 80.0).png");
        imageNames.Add("image/Img_2(Clone)_(72.5, -47.4)_(125.9, 80.0).png");
        imageNames.Add("image/Img_3(Clone)_(-296.4, -182.4)_(129.2, 80.0).png");
        //myText9.text = "初始化完成";
    }

    private async void OnUploadButtonClick()//下载指定路径的对象
    {
        string bucket = "chem1-13###958"; //  //存储桶,格式:BucketName-APPID
        //string cosPath = "image/1.png"; //对象在存储桶中的位置标识符,即称对象键
        string localDir = System.IO.Path.GetTempPath();//本地文件夹
        //string localFileName = "2858.bmp"; //指定本地保存的文件名


        // 初始化 TransferConfig
        TransferConfig transferConfig = new TransferConfig();
        // 手动设置高级下载接口的分块阈值为 20MB(默认为20MB),
        transferConfig.DivisionForDownload = 20 * 1024 * 1024;
        // 手动设置高级下载接口的分块大小为 10MB(默认为5MB),不建议此处设置过小的分块值,可能导致频繁重试或下载速度不合预期
        transferConfig.SliceSizeForDownload = 10 * 1024 * 1024;


        TransferManager transferManager = new TransferManager(cosXml, transferConfig);// 初始化 TransferManager
        //myText9.text = "初始化transferManager完成";
        int i = 1;
        foreach (string imageName in imageNames)
        {
            //myText7.text = "进入循环";
            string localFileName = Path.GetFileName(imageName); // 获取图片在本地保存的文件名
                                                                // print(localFileName);
            myText9.text = "获取图片完成"+ localFileName;
            // 下载对象
            COSXMLDownloadTask downloadTask = new COSXMLDownloadTask(bucket, imageName, localDir, localFileName);
            myText7.text = "downloadTask";
            downloadTask.SetMaxTasks(10); // 手动设置高级下载接口的并发数 (默认为5)
            myText7.text = "下载接口的并发数";
            await transferManager.DownloadAsync(downloadTask);//批量下载时打开
            myText9.text = "批量下载时打开";
            // print("开始下载");

            myText7.text = "开始下载"+i;

            // 实例化RawImage预制体
            RawImage downloadedImage = Instantiate(rawImagePrefab);
            RectTransform downloadedImage_rct = downloadedImage.GetComponent<RectTransform>();
            myText8.text = "实例化完成" + i;
           // print("实例化完成");

            // 加载下载的图像到Texture2D对象
            Texture2D downloadedTexture = LoadTextureFromFilePath(Path.Combine(localDir, localFileName));
            downloadedImage_rct.SetParent(canvas.transform, false);
            downloadedImage_rct.anchoredPosition = new Vector2(0, 0);

            if (downloadedTexture != null)
            {
                // 将Texture2D赋值给RawImage的texture属性
                downloadedImage.texture = downloadedTexture;
            }
            else
            {
                Debug.LogError("Failed to load downloaded image as Texture2D.");
            }
            i=i+1;

        }
    }

    // 用于从文件路径加载图像到Texture2D对象
    private Texture2D LoadTextureFromFilePath(string filePath)
    {
        if (!File.Exists(filePath))
        {
            Debug.LogError($"File not found: {filePath}");
            return null;
        }

        byte[] imageBytes = File.ReadAllBytes(filePath);
        Texture2D texture = new Texture2D(2, 2);
        if (texture.LoadImage(imageBytes))
        {
            return texture;
        }
        else
        {
            Debug.LogError($"Failed to load image from bytes: {filePath}");
            return null;
        }
    }
}

腾讯云的sdk指导链接如下
正常效果

img


bug效果

img

  • 写回答

25条回答 默认 最新

  • 专家-赤兔[在线] 优质创作者: 编程框架技术领域 2024-06-21 10:21
    关注
    获得0.45元问题酬金

    引自免费微信小程序:皆我百晓生

    从你提供的代码和描述来看,你的程序主要负责从腾讯云对象存储下载图片并显示在Unity中的RawImage组件上。部分设备上无法正常显示图片的问题可能由多种因素引起,包括但不限于图片格式兼容性、内存管理、纹理压缩格式以及Unity资源加载机制等。下面是一些建议和潜在解决方案:

    1. 图片格式与兼容性检查

    确保所有图片格式都是广泛支持的,如.jpg.png等。虽然大多数现代设备都支持这些格式,但不同设备和操作系统可能对某些格式或编码细节的支持存在差异。

    2. 文件路径与权限

    确认下载到的本地文件路径对Unity应用是可访问的,并且没有权限问题。在Android上,使用System.IO.Path.GetTempPath()通常是安全的,但确保应用有读写外部存储的权限。

    3. 纹理压缩格式

    不同的硬件平台支持不同的纹理压缩格式。Unity允许你在构建设置中指定纹理压缩格式,确保这些设置与目标设备兼容。可以在Unity编辑器的Project Settings > Player > Other Settings > Texture Compression中检查和调整。

    4. 内存管理与资源加载

    • 确保在加载大纹理时没有触发内存溢出。可以考虑在加载前检查或限制纹理尺寸。
    • 使用Resources.UnloadUnusedAssets()定期清理不再使用的资源,尤其是对于内存敏感的设备。
    • 考虑异步加载纹理以减轻主线程压力,尽管你的代码已使用了异步下载,但确保在加载到RawImage后也妥善处理资源。

    5. 组件与UI更新

    确保UI元素正确绑定并且在更新UI文本时Unity UI系统没有异常。尽管这不太可能是图片显示问题的直接原因,但UI更新的逻辑错误可能会影响调试信息的准确性。

    6. 错误处理与日志

    增强错误处理逻辑,特别是在LoadTextureFromFilePath函数中,增加详细的错误日志输出,比如文件读取失败的具体原因。

    代码优化建议

    这里提供一些基于现有代码的优化建议,特别是针对资源管理和错误处理:

    private async void OnUploadButtonClick()
    {
        // ... 其他初始化代码不变 ...
    
        foreach (string imageName in imageNames)
        {
            string localFileName = Path.GetFileName(imageName);
            myText9.text = $"获取图片完成: {localFileName}";
    
            COSXMLDownloadTask downloadTask = new COSXMLDownloadTask(bucket, imageName, localDir, localFileName);
            downloadTask.SetMaxTasks(10);
            
            try
            {
                await transferManager.DownloadAsync(downloadTask);
                myText9.text = "批量下载时打开";
    
                // 加载并显示图片
                await LoadAndDisplayImageAsync(localDir, localFileName, i++);
            }
            catch (Exception ex)
            {
                Debug.LogError($"下载或显示图片时发生错误: {ex.Message}");
            }
        }
    }
    
    private async Task LoadAndDisplayImageAsync(string localDir, string localFileName, int index)
    {
        // 实例化RawImage预制体
        RawImage downloadedImage = Instantiate(rawImagePrefab);
        RectTransform downloadedImage_rct = downloadedImage.GetComponent<RectTransform>();
    
        // 加载下载的图像到Texture2D对象
        Texture2D downloadedTexture = await LoadTextureAsync(localDir, localFileName);
    
        if (downloadedImage != null && downloadedTexture != null)
        {
            downloadedImage_rct.SetParent(canvas.transform, false);
            downloadedImage_rct.anchoredPosition = Vector2.zero;
            downloadedImage.texture = downloadedTexture;
            myText8.text = $"实例化完成: {index}";
        }
        else
        {
            Debug.LogError("Failed to instantiate RawImage or load texture.");
            Destroy(downloadedImage);
        }
    }
    
    private async Task<Texture2D> LoadTextureAsync(string filePath, string fileName)
    {
        if (!File.Exists(Path.Combine(filePath, fileName)))
        {
            Debug.LogError($"File not found: {fileName}");
            return null;
        }
    
        byte[] imageBytes = await File.ReadAllBytesAsync(Path.Combine(filePath, fileName));
        Texture2D texture = new Texture2D(2, 2);
        if (texture.LoadImage(imageBytes))
        {
            return texture;
        }
        else
        {
            Debug.LogError($"Failed to load image from bytes: {fileName}");
            return null;
        }
    }
    

    结论

    通过上述建议和代码调整,你可以进一步诊断问题所在,可能是特定设备上的资源限制、纹理格式不兼容或加载过程中的异常处理不足导致的。记得在不同设备上进行充分测试,并利用Unity的Profiler工具来监控应用运行时的内存和性能状况。

    评论 编辑记录

报告相同问题?

问题事件

  • 系统已结题 6月29日
  • 修改了问题 6月21日
  • 创建了问题 6月21日