如何通过脚本使Texture2D可读

问题描述 投票:0回答:2

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

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

有什么方法可以让这个加载的纹理可以通过代码读取/写入吗?无需访问库代码?

谢谢

这是可以通过这个插件获取纹理的代码

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));
}

如你所见,我已经尝试过这个答案但没有运气。

这是 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
变量。

c# unity-game-engine texture2d
2个回答
32
投票

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

1。使用

RenderTexture
(推荐):

使用

RenderTexture
。使用
Texture2D
将源
RenderTexture
放入
Graphics.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来执行此操作,因为它不会抛出任何错误。


0
投票

第一种方法非常好。然而,生成的图像可能存在色差。修改方法为: RenderTextureReadWrite.Linear,修改为RenderTextureReadWrite.Default,这样生成的图像就没有色差了

© www.soinside.com 2019 - 2024. All rights reserved.