Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make Texture2D Readable via script

I want to make user able to decode the QR image loaded from the gallery, I have found a plugin to explore and load the image as a texture2D, but to decode that QR code, the Texture2D has to be readable/writable, And I checked the plugin, for Android it's doing the exploring and loading stuff with a jar and in IOS platform it's using a packaged library, so I have no access to the code of the lib,

I have searched for the answer, the most solution was to change the importing setting of texture in the Unity inspector, but since this is a texture loaded by code, there is not an inspector setting available for that, So my question is:

Is there any way to make this loaded texture read/writeable by code? without having to access the lib code?

Thanks

Here is the code that could get the texture by 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));
}

As you can see, I have tried this answer But got no luck.

And here is the error that showed by 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] 

Note:

The source Texture2D is coming from a plugin, I can't set it to Read/Write Enabled from the Editor or use the Editor's TextureImporter.isReadable variable.

like image 474
armnotstrong Avatar asked Jun 24 '17 07:06

armnotstrong


People also ask

How to make a texture readable unity?

To toggle this, use the Read/Write Enabled setting in the Texture Import Settings, or set TextureImporter. isReadable. By default, this is true when you create a texture from a script. Note: Readable textures use more memory than non-readable textures.

How to make texture readable in unity runtime?

If you have the files in your project, you can select the texture in the inspector, set the texture type to "Advanced," then set "Read and write enabled" to true.

What is Rendertexture?

Render textures are textures that can be rendered to. They can be used to implement image based rendering effects, dynamic shadows, projectors, reflections or surveillance cameras. One typical usage of render textures is setting them as the "target texture" property of a Camera (Camera.


1 Answers

There are two ways to do this:

1.Use RenderTexture (Recommended):

Use RenderTexture. Put the source Texture2D into RenderTexture with Graphics.Blit then use Texture2D.ReadPixels to read the image from RenderTexture into the new 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;
}

Usage:

Texture2D copy = duplicateTexture(sourceTextFromPlugin);

This should work and should not throw any error.


2.Use Texture2D.GetRawTextureData() + Texture2D.LoadRawTextureData():

You can't use GetPixels32() because the Texture2D is not readable. You were so close about using GetRawTextureData().

You failed when you used Texture2D.LoadImage() to load from GetRawTextureData().

Texture2D.LoadImage() is only used to load PNG/JPG array bytes not Texture2D array byte.

If you read with Texture2D.GetRawTextureData(), you must write with Texture2D.LoadRawTextureData() not 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;
}

There will be no error with the code above in the Editor but there should be an error in standalone build. Besides, it should still work even with the error in the standalone build. I think that error is more like a warning.

I recommend you use method #1 to do this as it will not throw any error.

like image 118
Programmer Avatar answered Sep 17 '22 10:09

Programmer