Exemple #1
0
        /// <summary>
        /// 以Unity方式壓上浮水印
        /// </summary>
        /// <param name="pngData"></param>
        /// <param name="token"></param>
        /// <returns></returns>
        internal static byte[] MakeWatermarkPic(byte[] pngData, string token, bool zip)
        {
            Texture2D png = new Texture2D(1, 1);

            _ = ImageConversion.LoadImage(png, pngData);

            Texture2D watermark;

            if (zip)
            {
                watermark = ImageHelper.LoadDllResourceToTexture2D($"SaveLoadCompression.Resources.zip_watermark.png");
            }
            else
            {
                watermark = ImageHelper.LoadDllResourceToTexture2D($"SaveLoadCompression.Resources.unzip_watermark.png");
            }
            float scaleTimes = new PngCompression.PngCompression().GetScaleTimes(token);

            watermark = watermark.Scale(Convert.ToInt32(png.width * scaleTimes), Convert.ToInt32(png.width * scaleTimes));
            png       = png.OverwriteTexture(
                watermark,
                0,
                png.height - watermark.height
                );
            Extension.Logger.LogDebug($"Add Watermark: zip");
            return(png.EncodeToPNG());
        }
Exemple #2
0
        public static void Save(string path, string token)
        {
            //這裡用cleanedPath作"_compressed"字串清理
            string cleanedPath = path;

            while (cleanedPath.Contains("_compressed"))
            {
                cleanedPath = cleanedPath.Replace("_compressed", "");
            }

            string compressedPath = cleanedPath;

            if (!SaveLoadCompression.DeleteTheOri.Value)
            {
                compressedPath = cleanedPath.Substring(0, cleanedPath.Length - 4) + "_compressed.png";
            }

            //Update Cache
            string decompressCacheDirName = SaveLoadCompression.CacheDirectory.CreateSubdirectory("Decompressed").FullName;

            if (!SaveLoadCompression.Enable.Value || !SaveLoadCompression.Notice.Value)
            {
                //Clear cache and out
                File.Delete(Path.Combine(decompressCacheDirName, Path.GetFileName(path)));
                File.Delete(Path.Combine(decompressCacheDirName, Path.GetFileName(cleanedPath)));
                File.Delete(Path.Combine(decompressCacheDirName, Path.GetFileName(compressedPath)));
                return;
            }
            File.Copy(path, Path.Combine(decompressCacheDirName, Path.GetFileName(compressedPath)), true);

            if (cleanedPath != path)
            {
                File.Copy(path, cleanedPath, true);
                Logger.LogDebug($"Clean Path: {cleanedPath}");
            }

            byte[] pngData      = MakeWatermarkPic(ImageHelper.LoadPngBytes(path), token, true);
            byte[] unzipPngData = MakeWatermarkPic(ImageHelper.LoadPngBytes(path), token, false);

            //New Thread, No Freeze
            Thread newThread = new Thread(saveThread);

            newThread.Start();

            void saveThread()
            {
                Logger.LogInfo("Start Compress");
                long   newSize      = 0;
                long   originalSize = 0;
                float  startTime    = Time.time;
                string TempPath     = Path.Combine(SaveLoadCompression.CacheDirectory.CreateSubdirectory("Compressed").FullName, Path.GetFileName(path));

                SaveLoadCompression.Progress = "";
                try
                {
                    originalSize = new FileInfo(path).Length;

                    newSize = new PngCompression.PngCompression().Save(
                        path,
                        TempPath,
                        token: token,
                        pngData: pngData,
                        compressProgress: (decimal progress) => SaveLoadCompression.Progress = $"Compressing: {progress:p2}",
                        doComapre: !SaveLoadCompression.SkipSaveCheck.Value,
                        compareProgress: (decimal progress) => SaveLoadCompression.Progress = $"Comparing: {progress:p2}");

                    //複製或刪除檔案
                    if (newSize > 0)
                    {
                        LogLevel logLevel = SaveLoadCompression.DisplayMessage.Value ? (LogLevel.Message | LogLevel.Info) : LogLevel.Info;
                        Logger.LogInfo($"Compression test SUCCESS");
                        Logger.Log(logLevel, $"Compression finish in {Time.time - startTime:n2} seconds");
                        Logger.Log(logLevel, $"Size compress from {originalSize} bytes to {newSize} bytes");
                        Logger.Log(logLevel, $"Compress ratio: {Convert.ToDecimal(originalSize) / newSize:n3}/1, which means it is now {Convert.ToDecimal(newSize) / originalSize:p3} big.");

                        //寫入壓縮結果
                        File.Copy(TempPath, compressedPath, true);
                        Logger.LogDebug($"Write to: {compressedPath}");

                        //如果壓縮路徑未覆寫,將原始圖檔加上unzip浮水印
                        if (cleanedPath != compressedPath)
                        {
                            ChangePNG(cleanedPath, unzipPngData);
                            Logger.LogDebug($"Overwrite unzip watermark: {cleanedPath}");
                        }

                        //如果原始路徑和上二存檔都不相同,刪除之
                        //因為File.Delete()不是立即執行完畢,不能有「砍掉以後立即在同位置寫入」的操作,所以是這個邏輯順序
                        //如果相同的話,上方就已經覆寫了;不同的話此處再做刪除
                        if (path != compressedPath && path != cleanedPath)
                        {
                            File.Delete(path);
                            Logger.LogDebug($"Delete Original File: {path}");
                        }
                    }
                    else
                    {
                        Logger.LogError($"Compression FAILED");
                    }
                }
                catch (Exception e)
                {
                    if (e is IOException && newSize > 0)
                    {
                        //覆寫時遇到讀取重整會IOException: Sharing violation on path,這在Compress太快時會發生
                        //Retry
                        try
                        {
                            if (File.Exists(TempPath))
                            {
                                if (SaveLoadCompression.DeleteTheOri.Value)
                                {
                                    File.Copy(TempPath, path, true);
                                }
                            }
                        }
                        catch (Exception)
                        {
                            //Copy to a new name if failed twice
                            File.Copy(TempPath, path.Substring(0, path.Length - 4) + "_compressed2.png");
                            Logger.LogError("Overwrite was FAILED twice. Fallback to use the '_compressed2' path.");
                        }
                    }
                    else
                    {
                        Logger.Log(LogLevel.Error | LogLevel.Message, $"An unknown error occurred. If your files are lost, please find them at %TEMP%/{SaveLoadCompression.GUID}");
                        throw;
                    }
                }
                finally
                {
                    SaveLoadCompression.Progress = "";
                    if (File.Exists(TempPath))
                    {
                        File.Delete(TempPath);
                    }
                }
            }
        }