【问题标题】:How to make Texture2D Readable via script如何通过脚本使 Texture2D 可读
【发布时间】:2017-11-27 18:23:17
【问题描述】:

我想让用户能够解码从画廊加载的 QR 图像,我找到了一个插件来探索并将图像加载为 texture2D,但要解码该 QR 码,Texture2D 必须是可读/可写的,我检查了插件,对于 Android,它正在使用 jar 进行探索和加载,而在 IOS 平台中它使用的是打包库,所以我无法访问 lib 的代码,

我已经找到答案了,最有效的解决方案是在 Unity 检查器中更改纹理的导入设置,但由于这是由代码加载的纹理,因此没有可用的检查器设置,所以我的问题是:

有没有办法让这个加载的纹理可以通过代码读/写?无需访问 lib 代码?

谢谢

这是可以通过this plugin获取纹理的代码

void OnImageLoad(string imgPath, Texture2D tex, ImageAndVideoPicker.ImageOrientation imgOrientation)
{
    Debug.Log("Image Location : " + imgPath);
    Debug.Log("Image Loaded : " + imgPath);
    texture = tex;
    Texture2D readableText = new Texture2D(tex.width, tex.height);
    readableText.LoadImage(tex.GetRawTextureData());

    string url = QRCodeDecodeController.DecodeByStaticPic(readableText);
    StartCoroutine(GetSceneAndLoadLevel(url));
}

如你所见,我尝试了this answer 但没有成功。

这是Android显示的错误:

06-23 21:47:32.853: I/Unity(10557): (Filename: D Line: 0)
06-23 21:47:33.784: E/Unity(10557): Texture needs to be marked as Read/Write to be able to GetRawTextureData in player
06-23 21:47:33.784: E/Unity(10557): UnityEngine.Texture2D:GetRawTextureData()
06-23 21:47:33.784: E/Unity(10557): TestQR:OnImageLoad(String, Texture2D, ImageOrientation) (at D:\Unity Projects\nnkp\Assets\Scripts\QR\TestQR.cs:123)
06-23 21:47:33.784: E/Unity(10557): <LoadImage>c__Iterator0:MoveNext()
06-23 21:47:33.784: E/Unity(10557): UnityEngine.SetupCoroutine:InvokeMoveNext(IEnumerator, IntPtr) (at /Users/builduser/buildslave/unity/build/Runtime/Export/Coroutines.cs:17)
06-23 21:47:33.784: E/Unity(10557): [./artifacts/generated/common/runtime/TextureBindings.gen.cpp line 512] 

注意

Texture2D 来自一个插件,我无法从编辑器将其设置为启用读/写或使用编辑器的TextureImporter.isReadable 变量。

【问题讨论】:

  • 读取错误在哪里?贴出这行代码。
  • @Programmer,很高兴再次见到你,刚刚编辑发布日志
  • 再次阅读您的问题并决定删除旧问题。我错过了一条重要的线路,即您使用的 Texture2D.LoadImage 函数。如果现在一切正常,请告诉我。

标签: c# unity3d texture2d


【解决方案1】:

有两种方法可以做到这一点:

1.使用RenderTexture(推荐):

使用RenderTexture。将源Texture2D 放入RenderTextureGraphics.Blit 然后使用Texture2D.ReadPixels 将图像从RenderTexture 读入新的Texture2D

Texture2D duplicateTexture(Texture2D source)
{
    RenderTexture renderTex = RenderTexture.GetTemporary(
                source.width,
                source.height,
                0,
                RenderTextureFormat.Default,
                RenderTextureReadWrite.Linear);

    Graphics.Blit(source, renderTex);
    RenderTexture previous = RenderTexture.active;
    RenderTexture.active = renderTex;
    Texture2D readableText = new Texture2D(source.width, source.height);
    readableText.ReadPixels(new Rect(0, 0, renderTex.width, renderTex.height), 0, 0);
    readableText.Apply();
    RenderTexture.active = previous;
    RenderTexture.ReleaseTemporary(renderTex);
    return readableText;
}

用法

Texture2D copy = duplicateTexture(sourceTextFromPlugin);

这应该可以工作并且不会引发任何错误。


2.使用Texture2D.GetRawTextureData() + Texture2D.LoadRawTextureData()

您不能使用GetPixels32(),因为Texture2D 不可读。你非常接近使用GetRawTextureData()

当您使用Texture2D.LoadImage()GetRawTextureData() 加载时失败。

Texture2D.LoadImage()用于加载 PNG/JPG 数组字节而不是 Texture2D 数组字节。

如果你用Texture2D.GetRawTextureData()阅读,你必须用Texture2D.LoadRawTextureData()而不是Texture2D.LoadImage()写作。

Texture2D duplicateTexture(Texture2D source)
{
    byte[] pix = source.GetRawTextureData();
    Texture2D readableText = new Texture2D(source.width, source.height, source.format, false);
    readableText.LoadRawTextureData(pix);
    readableText.Apply();
    return readableText;
}

上面的代码在编辑器中不会出错,但在独立构建中应该会出错。此外,即使在独立构建中出现错误,它仍然应该可以工作。我认为这个错误更像是一个警告。

我建议您使用方法 #1 来执行此操作,因为它不会引发任何错误。

【讨论】:

  • 嗨。 byte[] pix = source.GetRawTextureData(); 行仍然出现 06-24 16:27:31.295: E/Unity(19300): Texture needs to be marked as Read/Write to be able to GetRawTextureData in player 错误
  • 检查我更新的答案。我认为您应该重新阅读我的答案。使用 #1 以免出错。
  • 通过使其不可读,它变得非常非常快。使其可读性是以内存和性能为代价的。这样做的原因是因为使其不可读会使 GPU 上的纹理。如果你让它可读,CPU 也可以访问它,从而使操作变慢。 GPU速度非常快。就是这样。我认为您应该在 Unity 中学习“计算着色器”。你会看到你可以用它做多快,因为它在 GPU 而不是 CPU 上运行。请注意,这是一个高级主题。这类似于使 Texture2D 不可读。
  • @sahithi 如果第一个有问题,您可能应该尝试解决方案 2
  • 太棒了! 1 解决方案就像一个魅力。你是我的英雄:D
猜你喜欢
  • 2014-09-30
  • 1970-01-01
  • 1970-01-01
  • 2019-06-14
  • 1970-01-01
  • 2021-06-18
  • 2022-12-18
  • 1970-01-01
相关资源
最近更新 更多