This is the third day of my participation in the August More text Challenge. For details, see:August is more challenging

An overview of the

This article will show you how to view a local image file, load it untiy, and display it in Unity. Basically, there are two steps: browse the local file, load the local file (other formats file principle is the same)

Thought analysis

The whole idea is:

  1. Call the file window of the system (open the resource manager to browse the image resources)
  2. Image path obtained through resource manager, and the image is loaded out

How to load local images:

  • Image loading using WWW (this method works with older Unity versions)
  • Image loading using Unity WebreQuest (this method is used with higher versions of Unity)
  • Load the image in IO mode

Function implementation

Call the system file window

Reference comDlg32. DLL system class library, call the GetOpenFileName method to achieve the window open function. The specific implementation code is as follows:

public class WindowDll { [DllImport("Comdlg32.dll", SetLastError = true, ThrowOnUnmappableChar = true, CharSet = CharSet.Auto)] public static extern bool GetOpenFileName([In, Out] OpenFileName ofn); public static bool GetOpenFileName1([In, Out] OpenFileName ofn) { return GetOpenFileName(ofn); }}Copy the code

This code alone is not enough. You also need to declare the prototype, set the parameters, create the OpenFileName class, and declare a class member for each structure element. Specific can refer to Microsoft official. NET framework advanced development documentation, this article uses the following parameters:

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public class OpenFileName
{
    public int structSize = 0;
    public IntPtr dlgOwner = IntPtr.Zero;
    public IntPtr instance = IntPtr.Zero;
    public String filter = null;
    public String customFilter = null;
    public int maxCustFilter = 0;
    public int filterIndex = 0;
    public String file = null;
    public int maxFile = 0;
    public String fileTitle = null;
    public int maxFileTitle = 0;
    public String initialDir = null;
    public String title = null;
    public int flags = 0;
    public short fileOffset = 0;
    public short fileExtension = 0;
    public String defExt = null;
    public IntPtr custData = IntPtr.Zero;
    public IntPtr hook = IntPtr.Zero;
    public String templateName = null;
    public IntPtr reservedPtr = IntPtr.Zero;
    public int reservedInt = 0;
    public int flagsEx = 0;
}
Copy the code

At this point, call system file window file is implemented.

Open a window to obtain the file path

Now that we’ve written the open window method above, we need to write a button click event. Using the button, we call the above method to open the image to load and get its location:

OpenFileName ofn = new OpenFileName(); ofn.structSize = Marshal.SizeOf(ofn); Ofn. filter = "image file (*.jpg*.png)\0*.jpg; *.png"; ofn.file = new string(new char[256]); ofn.maxFile = ofn.file.Length; ofn.fileTitle = new string(new char[64]); ofn.maxFileTitle = ofn.fileTitle.Length; / / the default path string path = Application. StreamingAssetsPath; path = path.Replace('/', '\\'); ofn.initialDir = path; ofn.title = "Open Project"; ofn.defExt = "JPG"; / / pay attention to the project is not necessarily to future generations But 0 x00000008 items don't lack ofn. The flags = 0 x00080000 | 0 x00001000 | 0 x00000800 | 0 x00000200 | 0 x00000008; / / on a single line of code corresponding to the following / / OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_ALLOWMULTISELECT | OFN_NOCHANGEDIR / / click Windows window began to load the Selected image if (WindowDll. GetOpenFileName (ofn)) {Debug. The Log (" Selected file with full path: "+ ofn. The file). }Copy the code

In the above code, there are several main parameters:

  • Ofn. initialDir: is the default path of the open window
  • Ofn. defExt: The type of file to display in the open window
  • Ofn. file: this is the main, this is the path parameter returned by the selected image, including path + filename all together.

The other parameters are easy to understand, as long as they are set to the corresponding parameters.

Image loading method one – use WWW to load

This method is used with earlier versions of Unity. Higher versions of Unity can be used, but will be warned of obsolescence. The WWW loading method mainly loads the image as Texture2D. And we’re going to display the Image on an Image, which uses a Sprite, so we need to convert the Image to a Sprite and assign a value to the Image. The following method is to load the image as Texture2D.

IEnumerator Load(string path) { WWW www = new WWW("file:///" + path); yield return www; if (www ! = null && string.isnullorempty (www.error)) {// Get Texture Texture2D Texture = www.texture; }}Copy the code

After obtaining the texture, create a Sprite based on the obtained texture

Sprite Sprite = sprite.create (texture, new Rect(0, 0, texture.width, texture.height), new Vector2(0.5f, 0.5f));Copy the code

Then you can assign the Image to the Image, sometimes the Image will be larger or smaller than the Image, it is possible that someone needs to use the original Image size, it is necessary to set the Image size to the original size

image.SetNativeSize();

Image loading method two – use UnityWebRequest to load

The first method to load local image files is to load them via WWW, but higher versions of Unity no longer support this API and use a more advanced API. According to the official document, UnityWebRequest is adopted instead. The namespace is also NetWorking. It is almost the same as WWW loading, but the code is slightly different. The specific method is as follows

IEnumerator Load(string path) { UnityWebRequest request = UnityWebRequestTexture.GetTexture(path); yield return request.SendWebRequest(); if (request.isHttpError || request.isNetworkError) { Debug.Log(request.error); } else { Texture tt = DownloadHandlerTexture.GetContent(request); Sprite = sprite.create ((Texture2D)tt, new Rect(0, 0, tt.width, tt.height), New Vector2 (0.5 f) 0.5 f); Image. Sprite = Sprite; // Set the image to its original size image.setnativesize (); }}Copy the code

Loading image method three – read the file in IO mode

Stream: The definition of stream: stream is in memory to open up memory address, and then the data in the file into the stream, in memory (stream) to change the text content, and then save back to the file. The keyword for a stream is FileStream. To apply FileStream to a stream, you first need to reference the namespace using System.IO; using System.IO.Compression; The specific code is:

Private void LoadByIo(string URL) {// create file read stream FileStream FileStream = new FileStream(url, filemode.open, FileAccess.Read); Byte [] bytes = new byte[filestream.length]; // Create file Length buffer byte[] bytes = new byte[filestream.length]; Filestream. Read(bytes, 0, (int) filestream.length); // Release the file read stream filestream.close (); Filestream.dispose (); fileStream = null; // Create Texture int width = 300; int height = 372; Texture2D texture = new Texture2D(width, height); texture.LoadImage(bytes); Sprite = sprite.create (texture, new Rect(0, 0, texture.width, texture.height), new Vector2(0.5f), 0.5 f)); Image. Sprite = Sprite; // Set the image to its original size image.setnativesize (); }Copy the code

Note: If you Read the contents of the file and assign it to the Syte array, it will be stored in the stream, and if you write the same contents to the stream, it will double the contents of the original file, So by reading the data in the stream, you can write the new data into the stream and write both the data in the file and the new data from the stream to the file.

Results show

All three loading methods have the same effect

Write in the last

All the shared content are the author in the daily development process used a variety of small function points, share out also in a disguised review, if there is a bad place to write also please give advice. The source code of the Demo will be sorted out and shared later.