Exemplo n.º 1
0
        /// <summary>
        /// Decodes the GIF file at the provided filepath into an array to textures.
        /// If framesToRead is smaller than 1 or bigger than the total number of frames in the GIF, the whole file will be read.
        /// Otherwise, only the number of frames determined by framesToRead will be decoded.
        /// </summary>
        /// <param name="filepath"></param>
        /// <param name="framesToRead"></param>
        /// <param name="threadPriority"></param>
        /// <param name="completeCallback"></param>
        public static void DecodeGif(string filepath, int framesToRead, System.Threading.ThreadPriority threadPriority, Action <Texture[]> completeCallback)
        {
#if UNITY_EDITOR
            Debug.LogWarning("DecodeGif is not supported in Unity editor. Please test on an iOS or Android device.");
#elif UNITY_IOS
            // Read the GIF partially.
            iOSNativeGif.DecodeGif(curDecodeId++, filepath, framesToRead, threadPriority,
                                   (int taskId, GifMetadata gifMetadata, GifFrameMetadata[] gifFrameMetadata, Color32[][] imageData) =>
            {
                if (completeCallback != null)
                {
                    completeCallback(ToTextureArray(gifMetadata, gifFrameMetadata, imageData));
                }
            });
#elif UNITY_ANDROID
            // Read the GIF partially.
            AndroidNativeGif.DecodeGif(curDecodeId++, filepath, framesToRead, threadPriority,
                                       (int taskId, GifMetadata gifMetadata, GifFrameMetadata[] gifFrameMetadata, Color32[][] imageData) =>
            {
                if (completeCallback != null)
                {
                    completeCallback(ToTextureArray(gifMetadata, gifFrameMetadata, imageData));
                }
            });
#endif
        }
Exemplo n.º 2
0
        internal static void ExportGif(GifExportTask exportTask)
        {
            var instance = new AndroidNativeGif(exportTask);
            var worker   = new Thread(instance.DoExportGif);

            worker.Priority = exportTask.workerPriority;
            worker.Start();
        }
Exemplo n.º 3
0
        /// <summary>
        /// Decodes the GIF file at the provided filepath into an <see cref="AnimatedClip"/> object.
        /// If framesToRead is smaller than 1 or bigger than the total number of frames in the GIF, the whole file will be read.
        /// Otherwise, only the number of frames determined by framesToRead will be decoded.
        /// </summary>
        /// <param name="filepath"></param>
        /// <param name="framesToRead"></param>
        /// <param name="threadPriority"></param>
        /// <param name="completeCallback"></param>
        public static void DecodeGif(string filepath, int framesToRead, System.Threading.ThreadPriority threadPriority, Action <AnimatedClip> completeCallback)
        {
#if UNITY_EDITOR
            EM_3DI70R_GIF.DecodeRequest request = new EM_3DI70R_GIF.DecodeRequest(filepath)
            {
                frameToRead    = framesToRead,
                threadPriority = threadPriority
            };
            request.Completed += () => {
                if (completeCallback != null)
                {
                    completeCallback(request.AnimatedClip);
                }
            };
            request.Request();
            // Debug.LogWarning("DecodeGif is not supported in Unity editor. Please test on an iOS or Android device.");
#elif UNITY_IOS
            // Read the GIF partially.
            iOSNativeGif.DecodeGif(curDecodeId++, filepath, framesToRead, threadPriority,
                                   (int taskId, GifMetadata gifMetadata, GifFrameMetadata[] gifFrameMetadata, Color32[][] imageData) =>
            {
                if (completeCallback != null)
                {
                    completeCallback(ToAnimatedClip(gifMetadata, gifFrameMetadata, imageData));
                }
            });
#elif UNITY_ANDROID
            // Read the GIF partially.
            AndroidNativeGif.DecodeGif(curDecodeId++, filepath, framesToRead, threadPriority,
                                       (int taskId, GifMetadata gifMetadata, GifFrameMetadata[] gifFrameMetadata, Color32[][] imageData) =>
            {
                if (completeCallback != null)
                {
                    completeCallback(ToAnimatedClip(gifMetadata, gifFrameMetadata, imageData));
                }
            });
#endif
        }
Exemplo n.º 4
0
Arquivo: Gif.cs Projeto: akil03/bx
        // GIF exporting coroutine: preprocess the image data then send it to native code (mobile) or a worker thread (other platforms) to export GIF file.
        static IEnumerator CRExportGif(AnimatedClip clip, string filename, int loop, int quality, System.Threading.ThreadPriority threadPriority, Action <AnimatedClip, float> exportProgressCallback, Action <AnimatedClip, string> exportCompletedCallback)
        {
            // The encoder don't want loop to be < -1
            if (loop < -1)
            {
                loop = -1;
            }

            // Compute the NeuQuant sample factor from the inverse of the quality value.
            // Note that NeuQuant prefers values in range [1,30] so we'll also scale the factor to that range.
            int sampleFac = Mathf.RoundToInt(Mathf.Lerp(30, 1, (float)(Mathf.Clamp(quality, 1, 100)) / 100));

            // Construct filepath
            string folder;

            #if UNITY_EDITOR
            folder = Application.dataPath; // Assets folder
            #else
            folder = Application.persistentDataPath;
            #endif

            string filepath = System.IO.Path.Combine(folder, filename + ".gif");

            // Construct a new export task
            var exportTask = new GifExportTask();
            exportTask.taskId    = curExportId++; // assign this task a unique id
            exportTask.clip      = clip;
            exportTask.imageData = null;
            exportTask.filepath  = filepath;
            exportTask.loop      = loop;
            exportTask.sampleFac = sampleFac;
            exportTask.exportProgressCallback  = exportProgressCallback;
            exportTask.exportCompletedCallback = exportCompletedCallback;
            exportTask.workerPriority          = threadPriority;
            exportTask.isExporting             = true;
            exportTask.isDone   = false;
            exportTask.progress = 0;

            // Add task to the list with its unique id key
            gifExportTasks.Add(exportTask.taskId, exportTask);

            yield return(null);

            // Create a temporary texture to read RenderTexture data
            Texture2D temp = new Texture2D(clip.Width, clip.Height, TextureFormat.RGB24, false);
            temp.hideFlags  = HideFlags.HideAndDontSave;
            temp.wrapMode   = TextureWrapMode.Clamp;
            temp.filterMode = FilterMode.Bilinear;
            temp.anisoLevel = 0;

            // On iOS and Android, the GIF encoding is done in native code.
            // In Unity editor (and other platforms), we use Moments encoder for testing purpose.
            #if UNITY_EDITOR || (!UNITY_IOS && !UNITY_ANDROID)
            // Converts to GIF frames
            List <GifFrame> frames = new List <GifFrame>(clip.Frames.Length);
            for (int i = 0; i < clip.Frames.Length; i++)
            {
                RenderTexture source = clip.Frames[i];
                RenderTexture.active = source;
                temp.ReadPixels(new Rect(0, 0, source.width, source.height), 0, 0);
                temp.Apply();
                RenderTexture.active = null;

                GifFrame frame = new GifFrame()
                {
                    Width = temp.width, Height = temp.height, Data = temp.GetPixels32()
                };
                frames.Add(frame);

                OnGifPreProcessing(exportTask.taskId, (float)i / clip.Frames.Length);
                yield return(null);
            }

            // Setup a worker thread and let it do its magic
            GifEncoder encoder = new GifEncoder(loop, sampleFac);
            encoder.SetDelay(Mathf.RoundToInt(1000f / clip.FramePerSecond));
            Worker worker = new Worker(
                exportTask.taskId,
                threadPriority,
                frames,
                encoder,
                filepath,
                OnGifExportProgress,
                OnGifExportCompleted);

            worker.Start();
            #else
            // Allocate an array to hold the serialized image data
            exportTask.imageData = new Color32[clip.Frames.Length][];

            // Construct the serialized image data, note that texture data is layered down-top, so flip it
            for (int i = 0; i < clip.Frames.Length; i++)
            {
                var source = clip.Frames[i];
                RenderTexture.active = source;
                temp.ReadPixels(new Rect(0, 0, source.width, source.height), 0, 0);
                temp.Apply();
                RenderTexture.active = null;

                // Get the frame's pixel data
                exportTask.imageData[i] = temp.GetPixels32();

                // Call the preprocessing handler directly
                float progress = (float)i / clip.Frames.Length;
                OnGifPreProcessing(exportTask.taskId, progress);

                yield return(null);
            }

            #if UNITY_IOS
            iOSNativeGif.ExportGif(exportTask);
            #elif UNITY_ANDROID
            AndroidNativeGif.ExportGif(exportTask);
            #endif
            #endif  // UNITY_EDITOR || (!UNITY_IOS && !UNITY_ANDROID)

            // Dispose the temporary texture
            Destroy(temp);
        }