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.
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.