Converting Bitmap to Texture2D crashes unity - unity3d

I tried many ways to do this, Want to show a bitmap in a Unity image(UI) tried all the ways I can find. I can do it by saving the file to disk and then reading it but that's too costly as it needs to be done in every frame.
I checked image is loaded correctly but the problem is in converting to Texture2D and also saving it to memory stream and reading the file also crashes unity, I tried in Unity 2017 2018 2019 all crashes
tried all this ,this
*Only need to make this work in desktop Build if it helps
Bitmap bitmap = new Bitmap(#"C: \image1.jpg");
final = UnmanagedImage.FromManagedImage(bitmap);
Texture2D convertedTx;
convertedTx = Texture2D.CreateExternalTexture(final.Width, final.Height, TextureFormat.ARGB32, false, false, final.ImageData);
//Convert UnmanagedImage to Texture
convertedTx.UpdateExternalTexture(final.ImageData);
display.texture = convertedTx;

I think you didn't put this code in an enumeration, so its run on the main thread and cause unity crash

Related

How can I make assets accessible to players for modding?

My game includes image files and json configuration files that I would like to make accessible in the deployed game's folder structure so that players can easily edit or swap them out.
I have considered/tried the following approaches:
My initial approach was to use the Resources folder and code
such as Resources.Load<TextAsset>("Rules.json"). Of course,
this did not work as the resources folder is compiled during builds.
I investigated the Addressables and AssetBundle features, but they do not seem aimed at solving this problem.
After asking around, I went for using .NET's own file methods, going
for code like File.ReadAllText(Application.dataPath + Rules.json). This seems like it will work, but such files are still not deployed automatically and would have to manually be copied over.
It seems that the StreamingAssets folder exists for this, since the manual advertises that its contents are copied verbatim on the target machine. I assume that its contents should be read as in the previous point, with non-Unity IO calls like File.ReadAllText(Application.streamingAssetsPath + Rules.json)?
So yeah, what is the 'canonical' approach for this? And with that approach, is it still possible to get the affected files as assets (e.g. something similar to Resources.Load<Sprite>(path)), or is it necessary to use .NET IO methods to read the files and then manually turn them into Unity objects?
After asking the same question on the Unity forums, I was advised to use the StreamingAssets folder and told that it is necessary to use .NET IO methods with it.
An example for how to load sprites as files using standard IO can be seen here: https://forum.unity.com/threads/generating-sprites-dynamically-from-png-or-jpeg-files-in-c.343735/
static public Sprite LoadSpriteFromFile(
string filename,
float PixelsPerUnit = 100.0f,
SpriteMeshType type = SpriteMeshType.FullRect)
{
// Load a PNG or JPG image from disk to a Texture2D, assign this texture to a new sprite and return its reference
Texture2D SpriteTexture = LoadTexture(filename);
Sprite NewSprite = Sprite.Create(
SpriteTexture,
new Rect(0,
0,
SpriteTexture.width,
SpriteTexture.height),
new Vector2(0, 0),
PixelsPerUnit,
0,
type);
return NewSprite;
}
static private Texture2D LoadTexture(string FilePath)
{
// Load a PNG or JPG file from disk to a Texture2D
// Returns null if load fails
Texture2D Tex2D;
byte[] FileData;
if (File.Exists(FilePath))
{
FileData = File.ReadAllBytes(FilePath);
Tex2D = new Texture2D(2, 2);
// If the image is blurrier than what you get with a manual Unity import, try tweaking these two lines:
Tex2D.wrapMode = TextureWrapMode.Clamp;
Tex2d.filterMode = FilterMode.Bilinear;
// Load the imagedata into the texture (size is set automatically)
if (Tex2D.LoadImage(FileData))
{
return Tex2D; // If data = readable -> return texture
}
}
return null;
}

Androidx RenderScript not run android api<19

I have use androidx with blur image, but when run android api< 19 crash app.
When i run with android>19, i run normal,not crash app and if i use android normal with "android.support.v8.renderscript" no crash app.
At build.gradle. I have add :
renderscriptTargetApi 18
renderscriptSupportModeEnabled true
Code app:
public static Bitmap blurBitmap(Bitmap bitmap,
float radius) { //Create renderscript
RenderScript
rs = RenderScript.create(MyApplication.getInstance());
//Create allocation from Bitmap
Allocation allocation = Allocation.createFromBitmap(rs,
bitmap);
Type t = allocation.getType();
//Create allocation with the same type
Allocation blurredAllocation = Allocation.createTyped(rs,
t);
//Create script
ScriptIntrinsicBlur blurScript = ScriptIntrinsicBlur.create(rs, Element.U8(rs));
//Set blur radius (maximum 25.0)
blurScript.setRadius(radius);
//Set input for script
blurScript.setInput(allocation);
//Call script for output allocation
blurScript.forEach(blurredAllocation);
//Copy script result into bitmap
blurredAllocation.copyTo(bitmap);
//Destroy everything to free memory
allocation.destroy();
blurredAllocation.destroy();
blurScript.destroy();
t.destroy();
rs.destroy();
return bitmap;
}
Edit:
This issue is now fixed in the latest build tools. I've verified this by upgrading compile sdk to API 29 and build tools to 29.0.2.
This has nothing to do with your implementation. It's a bug in the androidx library and in fact, it happens for me even on API 21 so it might have a bigger impact than you've experienced.
Someone has already filed issues here and here. I've been following on the issue for quite sometime unfortunately there isn't much progress going on. This is currently a showstopper for me to migrate to AndroidX for many of my projects.
The Element.U8 argument for ScriptIntrinsicBlur.create() is not correct.
The ScriptIntrinsicBlur is expecting an Allocation with elements of type Element.U8, but a Bitmap-backed Allocation has elements of type Element.RGBA_8888 (a.k.a Element.U8_4).
try:
ScriptIntrinsicBlur.create(rs, Element.RGBA_8888(rs))
or in general:
ScriptIntrinsicBlur.create(rs, allocation.getElement())

tex2D(s,t,ddx,ddy) not working in fullscreen in unity

i'm trying to make full screen custom post effect.
with script added to main cam, with one line: blit(src,dst,mat) in void OnRenderImage(src,dst). I wrote the shader with _MainTex so it'll work in "Blit". I done it(many times) all correctlly like in tuts. if i assign this shader to any object (with texture) it works well, but the problem is when i assign that shader(in material) to script (blit(,,mat)) it ignores the ddx,ddy part,it works like tex2D(tex,uv). WHY? how can I fix it?
here is the fragment code.
fixed3 frag(vout v):sv_target
{
fixed3 c;
float2 cddx=float2(
pow(abs(0.5-v.uv.x),1.6)*_xy,
-pow(abs(0.5-v.uv.y),1.6)*_xy);
float2 cddy=float2(
-pow(abs(0.5-v.uv.x),1.6)*_xy,
pow(abs(0.5-v.uv.y),1.6)*_xy);
c=tex2D(_MainTex,v.uv,cddx,cddy);
return c*0.5;
}
I found an answer. tex2D(sampler2D,uv,ddx,ddy) and tex2Dgrad(...) methods use mipmaps. when i tried to pass "screen" texture to the shader in blit(src,dst,mat) I noticed that src has no mipmaps, only the original texture. so, I thought that I'll simply add mipmaps with src.GenerateMips() and it'll work. but there is a catch: if i try to do that the editor throws me exceptions that the rendertexture is created, that generating mips is unsuported in created rendertexture and other stuff... finally i found the recipy:
one time
create another temp renderTexture
turn off auto generate mipmaps
useMips=true
every frame (OnRenderImage(...))
blit src to temp
generate mipmaps in temp
blit(temp,dst,mat)
it generates mipmaps on new render texture and passes it to the shader without any errors.
one last thing, if someone knows how to specify mipmap count that i want to generate, tell me please.
I hope it'll be helpful to newbies in shaders like me.

UnloadUnusedAssets doesn't appear to be freeing memory

I'm working on a game in Unity where a sprite is imported using Resources.Load(), and as expected, the memory increases.
But the problem is, I can't seem to figure out how to free the memory.
I know I need to use Resources.UnloadUnusedAssets(), but even when I remove every reference to the sprite that I can think of, the memory doesn't go back down.
Here's my code right now:
Loading the sprite (works fine):
map = Resources.Load <Sprite> ("Map7");
spRend = this.GetComponent<SpriteRenderer>();
spRend.sprite = map;
Unloading the sprite (memory isn't freed):
spRend.sprite = null;
map = null;
Resources.UnloadUnusedAssets();
UPDATE:
After further research, I found this on the Unity wiki:
When not used anymore, you can free the memory it took up by calling Object.Destroy on the object, followed by Resources.UnloadUnusedAssets
But the problem is when I try to destroy 'map', I get the following error:
Destroying assets is not permitted to avoid data loss.
If you really want to remove an asset use DestroyImmediate (theObject, true);

Unity3D trying to load a texture resource after build

I have a material that is using a texture (image) located in the Resources directory under Assets. Using Resources.load works while in the editor. The texture also loads properly on a build, but I would like to replace that image after the build by placing a different image (with the same name) in the built Resources directory.
On Windows, I think that directory is buildname_Data>Resources and on Mac I'm thinking it's Contents>Resources (after opening Package Contents). This works for a text file I'm using to load some data at startup, but the process is a bit different there as I'm not using Resources.load in that case.
The problem I'm having is that just placing a new image in the (i think) proper location does not override the image that the app was built with. I'm still seeing the original image. I've been scratching my head over this for the past couple days, and the Documentation (as well as various google searches) have not yielded insight into a solution (although it's likely staring me right in the face).
var MyTexture : Texture = Resources.Load("colorPatch");
var wbpLineRenderer : LineRenderer = someGameObject.AddComponent(LineRenderer);
wbpLineRenderer.material = new Material (Shader.Find("Particles/Alpha Blended"));
wbpLineRenderer.material = Resources.Load("curveLine") as Material;
wbpLineRenderer.material.mainTexture = MyTexture;
curveLine is a material in the Assets/Resources directory of the Editor.
colorPatch is an image file named colorPatch.png in the Assets/Resources directory of the Editor
Can someone please screw my head on straight about this? Can I actually swap an image used on a texture after build?
After a good breakfast and a bit more googling I have (re)discovered the solution, detailed here.
my implementation is as follows:
var textureURL : String = "file://" + Application.dataPath + "/Resources/colorPatch.png";
var www : WWW = new WWW(textureURL);
var tempTexture : Texture2D = new Texture2D(2, 2); //doesn't have to be the actual size
www.LoadImageIntoTexture(tempTexture); //image loads at 100% not 2x2 specified above
var wbpLineRenderer : LineRenderer = wellBorePath.AddComponent(LineRenderer);
wbpLineRenderer.material = new Material (Shader.Find("Particles/Alpha Blended"));
wbpLineRenderer.material = Resources.Load("curveLine") as Material;
wbpLineRenderer.material.mainTexture = tempTexture;
Once the app is built, place an image named colorPatch.png in the location:
Windows - appname_Data/Resources
Mac - Contents/Resources (after opening Package Contents).
Switching out the image colorPatch.png with another image (but still titled colorPatch.png) then launching the app, displays the new image as the texture.