/// <summary> /// 拖曳滑鼠 /// </summary> private void fun_拖曳圖片() { while (bool_程式運行中) { Thread.Sleep(10); if (bool_允許拖曳瀏覽 == false) { continue; } C_adapter.fun_UI執行緒(() => { func_隱藏局部高清_移動時(); var int_top = m_top + (m_y - fun_取得滑鼠().Y) * double_keen; var int_left = m_left + (m_x - fun_取得滑鼠().X) * double_keen; //當拖曳超出捲軸最大之時,則重新抓取拖動前記錄的坐標,這樣就不用返回到原點才能往回拖曳 if (int_top < 0) { m_y = fun_取得滑鼠().Y; m_top = 0; } if (int_top >= scrollviewer_1.ScrollableHeight) { m_y = fun_取得滑鼠().Y; m_top = scrollviewer_1.ScrollableHeight; } if (int_left < 0) { m_x = fun_取得滑鼠().X; m_left = 0; } if (int_left >= scrollviewer_1.ScrollableWidth) { m_x = fun_取得滑鼠().X; m_left = scrollviewer_1.ScrollableWidth; } //修改捲軸位置 scrollviewer_1.ScrollToVerticalOffset(int_top); scrollviewer_1.ScrollToHorizontalOffset(int_left); }); }//while }
/// <summary> /// /// </summary> /// <param name="s_type"></param> private void fun_執行搜圖(String s_type) { try { String s_當前目錄 = M.ar_path[M.int_目前圖片位置]; int img_width = M.int_img_w; int img_height = M.int_img_h; bool bool_需要縮小 = false; //換算後的圖片size int img_w2 = 1200; int img_h2 = 1200; //(350*50)/(100*100) //以面積限制圖片大小 double b = (img_width * img_height) / (1600f * 1600f); if (s_type == "bing") { b = (img_width * img_height) / (600f * 600f); } b = Math.Sqrt(b); img_w2 = (int)(img_width / b); img_h2 = (int)(img_height / b); //MessageBox.Show(img_w2 + " " + img_h2); //MessageBox.Show(img_w2 + " " + img_h2); //換算後如果比原圖還大,就是用原本的size if (img_w2 >= img_width) { img_w2 = img_width; img_h2 = img_height; } else { bool_需要縮小 = true; } int max_size = 7500; if (s_type == "bing") { max_size = 2000; } //限制圖片的寬度與長度,都不可以超過7500 if (img_w2 > max_size || img_w2 > max_size) //寬度或高度太大 { bool_需要縮小 = true; if (img_width > img_height) { img_w2 = max_size; img_h2 = (int)((1.0f * img_w2 / img_width) * img_height); } else { img_h2 = max_size; img_w2 = (int)((1.0f * img_h2 / img_height) * img_width); } } if (M.c_影像.fun_判斷檔案大小_MB(s_當前目錄) > 5) //如果檔案超過5M { bool_需要縮小 = true; } BitmapImage bitmapImage = null; BitmapEncoder encoder = null; //可能是jpg或png或gif if (M.stackPlanel_動圖工具.Visibility == Visibility.Visible) //動圖 { encoder = new PngBitmapEncoder(); encoder.Frames.Add(BitmapFrame.Create(M.c_P網.fun_取得第一張圖片())); } /*else if (M.s_img_type_附檔名 == "SVG") {//SVG * * MessageBox.Show("SVG圖片 無法線上搜圖"); * return; * * }*/ else if (M.s_img_type_顯示類型 == "MOVIE") //MMOVIE //影片的話,就透過截圖的方式來處理 //如果影片大於視窗,就先縮小後再截圖 { if (M.scrollviewer_1.ScrollableHeight > 0 || M.scrollviewer_1.ScrollableWidth > 0) { M.fun_圖片全滿(); new Thread(() => {//50毫秒後重新執行這個function Thread.Sleep(50); C_adapter.fun_UI執行緒(() => { fun_執行搜圖(s_type); }); }).Start(); return; } else { encoder = new PngBitmapEncoder(); encoder.Frames.Add(BitmapFrame.Create(M.SaveTo(M.img_voide))); } } else //靜態圖 { String ss = M.s_img_type_附檔名.ToUpper(); /*if (M.s_img_type_附檔名 == "PNG"|| M.s_img_type_附檔名 == "SVG"|| M.s_img_type_附檔名 == "AI") { * encoder = new PngBitmapEncoder(); * } else if (M.s_img_type_附檔名 == "GIF") { * encoder = new GifBitmapEncoder(); * } else { * encoder = new JpegBitmapEncoder(); * }*/ try { using (var im = M.c_影像.c_Magick.getImg(s_當前目錄, M.s_img_type_附檔名)) { if (bool_需要縮小) { im.Scale(img_w2, img_h2); } if (im.IsOpaque) { encoder = new JpegBitmapEncoder(); } else { encoder = new PngBitmapEncoder(); } encoder.Frames.Add(BitmapFrame.Create(im.ToBitmapSource())); } } catch { bool_需要縮小 = true; encoder = new PngBitmapEncoder(); encoder.Frames.Add(BitmapFrame.Create(M.c_影像.BitmapToBitmapSource(M.c_影像.func_作業系統圖示(s_當前目錄)))); } //一般格式 /*if (ss == "JPG" || ss == "JPEG" || ss == "BMP" || ss == "PNG" || ss == "GIF" || ss == "TIF") { * * using (BinaryReader reader = new BinaryReader(File.Open(s_當前目錄, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))) { * FileInfo fi = new FileInfo(s_當前目錄); * byte[] bytes = reader.ReadBytes((int)fi.Length); * reader.Close(); * bitmapImage = new BitmapImage(); * bitmapImage.BeginInit(); * bitmapImage.StreamSource = new MemoryStream(bytes); * * if (bool_需要縮小) { * if (img_width > img_height) { * bitmapImage.DecodePixelWidth = img_w2; * } else { * bitmapImage.DecodePixelHeight = img_h2; * } * } * * bitmapImage.EndInit(); * bitmapImage.CacheOption = BitmapCacheOption.None; * } * * //依照檔案類型來初始化 * if (M.s_img_type_附檔名 == "PNG") { * encoder = new PngBitmapEncoder(); * } else if (M.s_img_type_附檔名 == "GIF") { * encoder = new GifBitmapEncoder(); * } else { * encoder = new JpegBitmapEncoder(); * } * * * * //encoder.Frames.Add(BitmapFrame.Create(bitmapImage)); * * using (var im = M.c_影像.c_Magick.getImg(s_當前目錄, M.s_img_type_附檔名)) { * if (bool_需要縮小) { * im.Scale(img_w2, img_h2); * } * encoder.Frames.Add(BitmapFrame.Create(im.ToBitmapSource())); * * } * * } else { * * encoder = new JpegBitmapEncoder(); * try { * * using (var im = M.c_影像.c_Magick.getImg(s_當前目錄, M.s_img_type_附檔名)) { * if (bool_需要縮小) { * im.Scale(img_w2, img_h2); * } * encoder.Frames.Add(BitmapFrame.Create(im.ToBitmapSource())); * * } * * * } catch { * encoder.Frames.Add(BitmapFrame.Create(M.c_影像.BitmapToBitmapSource(M.c_影像.func_作業系統圖示(s_當前目錄)))); * * * } * * }*/ } if (bool_需要縮小) { String s_path_soom = M.func_取得暫存路徑(); if (Directory.Exists(s_path_soom) == false) //避免資料夾不存在 { Directory.CreateDirectory(s_path_soom); } s_當前目錄 = Path.Combine(s_path_soom, "gs.jpg"); using (MemoryStream ms = new MemoryStream()) { encoder.Save(ms); //byte[] temp = memoryStream.ToArray(); //Clipboard.SetDataObject(temp); //base64String = "data:image/jpeg;base64," + Convert.ToBase64String(temp); ms.Seek(0, SeekOrigin.Begin); using (FileStream file = new FileStream(s_當前目錄, FileMode.Create)) { ms.CopyTo(file); file.Flush(); } } } //執行() var psi = new System.Diagnostics.ProcessStartInfo(); psi.FileName = M.fun_執行檔路徑() + "/data/graphSearch/graphSearch.exe"; //執行檔路徑 psi.UseShellExecute = false; psi.WorkingDirectory = M.fun_執行檔路徑() + "/data/graphSearch"; //設定執行檔鎖定的資料夾 psi.CreateNoWindow = false; psi.Arguments = "\"" + s_type + "\"" + " " + "\"" + s_當前目錄 + "\""; System.Diagnostics.Process.Start(psi); //清理圖片 if (encoder.Frames.Count > 0 && encoder.Frames[0] != null) { encoder.Frames[0].Freeze(); } if (bitmapImage != null) { bitmapImage.Freeze(); } /* * using (FileStream st = new FileStream("11.jpg", FileMode.Create)) { * byte[] temp = memoryStream.ToArray(); * st.Write(temp, 0, temp.Length); * }*/ } catch (Exception e3) { MessageBox.Show(e3.ToString()); } }
/// <summary> /// /// </summary> public void fun_複製影像() { /* * //印出剪貼簿裡面所有的格式 * IDataObject data = Clipboard.GetDataObject(); * foreach (var item in data.GetFormats()) { * System.Console.WriteLine("----------------------------++++ " + item); * }*/ BitmapSource bs = null; BitmapEncoder encoder = null;//可能是jpg或png或gif if (M.stackPlanel_動圖工具.Visibility == Visibility.Visible) //動圖 { bs = M.c_P網.fun_取得目前圖片(); if (bs != null) { Clipboard.Clear(); Clipboard.SetImage(bs); } } /*else if (M.s_img_type_附檔名 == "SVG") {//SVG * * MessageBox.Show("SVG圖片 無法複製影像"); * * }*/ /*else if (M.s_img_type_附檔名 == "PSD") {// * * String s_當前目錄 = M.ar_path[M.int_目前圖片位置]; * if (File.Exists(s_當前目錄)) { * * * try { * encoder = new PngBitmapEncoder(); * BitmapDecoder bd = null; * * //用串流方式讀取圖片(避免圖片因為資源被暫用導致無法刪除 * using (BinaryReader reader = new BinaryReader(File.Open(s_當前目錄, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))) { * FileInfo fi = new FileInfo(s_當前目錄); * byte[] bytes = reader.ReadBytes((int)fi.Length); * * MemoryStream ms = new MemoryStream(bytes); * bd = BitmapDecoder.Create(ms, BitmapCreateOptions.DelayCreation, BitmapCacheOption.None); * reader.Close(); * reader.Dispose(); * } * * //把圖片轉成PNG類型 * encoder.Frames.Add(bd.Frames[0]); * * //把PNG儲存回 BitmapDecoder ,這樣才能正常複製PSD檔案 * using (MemoryStream memoryStream = new MemoryStream()) { * encoder.Save(memoryStream); * bd = BitmapDecoder.Create(memoryStream, BitmapCreateOptions.DelayCreation, BitmapCacheOption.None); * Clipboard.Clear(); * Clipboard.SetImage(bd.Frames[0]); * } * * //釋放資源 * encoder.Frames[0].Freeze(); * bd.Frames[0].Freeze(); * * } catch (Exception) { * * * //如果作業系統內沒有PSD的解碼器,就改用程式內建的 * SimplePsd.CPSD psd = new SimplePsd.CPSD(); * psd.Load(s_當前目錄); * System.Drawing.Bitmap fromHbitmap = System.Drawing.Image.FromHbitmap(psd.GetHBitmap()); * System.Windows.Forms.Clipboard.SetImage(fromHbitmap); * * * } * * * * * }//if 檔案存在 * * * } */ else if (M.s_img_type_顯示類型 == "MOVIE") //MMOVIE //影片無法直接複製印象,所以用截圖的方式 //如果影片超過視窗範圍,就先縮小影片 { if (M.scrollviewer_1.ScrollableHeight > 0 || M.scrollviewer_1.ScrollableWidth > 0) { //全滿 M.fun_圖片全滿(); //50毫秒後重新執行這個函數 new Thread(() => { Thread.Sleep(50); C_adapter.fun_UI執行緒(() => { fun_複製影像(); }); }).Start(); return; } else { //圖片處於全滿狀狀態,使用截圖來複製影像 encoder = new PngBitmapEncoder(); var img56 = M.SaveTo(M.img_voide); if (img56 != null) { encoder.Frames.Add(BitmapFrame.Create(img56)); bs = encoder.Frames[0]; Clipboard.Clear(); Clipboard.SetImage(bs); bs.Freeze(); } else { MessageBox.Show("無法在影片旋轉後複製影像"); } } } else //靜態圖 //使用 Forms 的剪貼簿物件,使用WPF的話,PNG會因為剪貼簿無法儲存透明資訊,導致嚴重破圖 { try { String s_當前目錄 = M.ar_path[M.int_目前圖片位置]; String ss = M.s_img_type_附檔名.ToUpper(); //一般格式 if (ss == "JPG" || ss == "JPEG" || ss == "BMP" || ss == "PNG" || ss == "GIF" || ss == "TIF") { if (File.Exists(s_當前目錄)) { System.Drawing.Bitmap bm_transparent = new System.Drawing.Bitmap(s_當前目錄); System.Windows.Forms.Clipboard.SetImage(bm_transparent); bm_transparent.Dispose(); } } else //特殊格式 { System.Drawing.Bitmap bm_transparent = null; try { using (var mi = M.c_影像.c_Magick.getImg(s_當前目錄, M.s_img_type_附檔名)) { bm_transparent = mi.ToBitmap(); } } catch (Exception) { bm_transparent = M.c_影像.func_作業系統圖示(s_當前目錄); } System.Windows.Forms.Clipboard.SetImage(bm_transparent); bm_transparent.Dispose(); } } catch { } } //if } //function
//public DateTime s_局部高清_處理方式 = DateTime.Now; /// <summary> /// /// </summary> public void func_局部高清_初始化() { String s_path = ""; //圖片路徑 double d_倍率 = 1; //縮放倍率 double d_倍率_old = 1; //超過500毫秒沒有進行縮放才重新算圖 double d_x = 1; //圖片位置 double d_y = 1; double d_window_w = 1; //視窗寬度 double d_window_h = 1; int int_旋轉角度 = 0; bool bool_剪裁 = false; DateTime time_避免捲動中算圖 = DateTime.Now;// //------------- new Thread(() => { while (bool_程式運行中) { //------------- Thread.Sleep(100); if (u_大量瀏覽模式 != null) { s_path = ""; continue; } if (bool_啟動局部高清 == false) { s_path = ""; continue; } //在程式預設開啟的資料夾不啟用 if (int_目前圖片位置 < ar_path.Count) { if (ar_path[int_目前圖片位置].IndexOf(fun_執行檔路徑() + "\\data\\imgs") == 0) { s_path = ""; continue; } } /* * if (this.Visibility != Visibility.Visible) { * //s_path = ""; * Thread.Sleep(100); * continue; * }*/ /* * if (s_img_type_附檔名 == "PNG" || s_img_type_附檔名 == "JPG" || * s_img_type_附檔名 == "TIF" || s_img_type_附檔名 == "BMP" || * image_局部高清 != null) { * * } else { * continue; * }*/ bool bool_重新繪製 = false; bool bool_新圖片 = false; bool bool_不剪裁且不重新繪製 = false; C_adapter.fun_UI執行緒(() => { try { if (d_倍率 == img.ActualWidth && bool_剪裁 == false) { //System.Console.WriteLine("不剪裁且不重新繪製: " + ar_path[int_目前圖片位置]); bool_不剪裁且不重新繪製 = true; } if (s_path != ar_path[int_目前圖片位置]) { //System.Console.WriteLine("新圖片: " + ar_path[int_目前圖片位置]); s_path = ar_path[int_目前圖片位置]; bool_新圖片 = true; bool_不剪裁且不重新繪製 = false; bool_重新繪製 = true; //讓新圖片一定能立即運算 d_倍率 = 0.123456; d_倍率_old = img.ActualWidth; } if (d_倍率_old == img.ActualWidth) { //bool_重新繪製 = false; if (d_倍率 != img.ActualWidth || d_x != scrollviewer_1.ContentHorizontalOffset || d_y != scrollviewer_1.ContentVerticalOffset || d_window_w != this.ActualWidth || d_window_h != this.ActualHeight || int_旋轉角度 != c_旋轉.int_旋轉) { d_倍率 = img.ActualWidth; d_x = scrollviewer_1.ContentHorizontalOffset; d_y = scrollviewer_1.ContentVerticalOffset; d_window_w = this.ActualWidth; d_window_h = this.ActualHeight; int_旋轉角度 = c_旋轉.int_旋轉; bool_重新繪製 = true; } } if (((TimeSpan)(DateTime.Now - time_避免捲動中算圖)).TotalMilliseconds < 800) //連點低於400毫秒 { } else { d_倍率_old = img.ActualWidth; time_避免捲動中算圖 = DateTime.Now; } } catch { s_path = ""; bool_重新繪製 = false; return; } }); if (bool_不剪裁且不重新繪製) { continue; } if (bool_重新繪製 == false) { continue; } if (bool_新圖片) { try { if (File.Exists(ar_path[int_目前圖片位置])) { if (image_局部高清 == null) { var im5 = new ImageMagick.MagickImage((ar_path[int_目前圖片位置])); // //如果讀取完圖片後,使用者已經切換到其他圖片,就不要寫入到「image_局部高清」,直接解析新圖片 if (int_目前圖片位置 < 0 || int_目前圖片位置 >= ar_path.Count || s_path != ar_path[int_目前圖片位置]) { image_局部高清 = null; s_path = null; im5 = null; continue; } else { image_局部高清 = im5; } //System.Console.WriteLine("一般 " + s_path); } else { //image_局部高清 = new ImageMagick.MagickImage((ar_path[int_目前圖片位置])); //System.Console.WriteLine("特殊 " + s_path); } //https://www.smashingmagazine.com/2015/06/efficient-image-resizing-with-imagemagick/ //不使用 漸進式渲染 image_局部高清.Interlace = Interlace.NoInterlace; //剝離所有配置文件和註釋的圖像。 image_局部高清.Strip(); //雙線性插值 //image_局部高清.FilterType = FilterType.Hann; } else { s_path = ""; continue; } } catch { s_path = ""; System.Console.WriteLine("*******局部高清 失敗"); continue; } } //避免已經切換到其他圖片 if (int_目前圖片位置 < 0 || int_目前圖片位置 >= ar_path.Count) { continue; } if (d_倍率 != img.ActualWidth || s_path != ar_path[int_目前圖片位置]) { continue; } if (bool_啟動局部高清 == false) { s_path = ""; continue; } double w03 = 1; double h03 = 1; double l03 = 1; double t03 = 1; double d_縮放倍率 = 1; C_adapter.fun_UI執行緒(() => { w03 = scrollviewer_1.ViewportWidth; h03 = scrollviewer_1.ViewportHeight; l03 = scrollviewer_1.ContentHorizontalOffset; t03 = scrollviewer_1.ContentVerticalOffset; if (c_旋轉.bool_垂直鏡像) { t03 = scrollviewer_1.ScrollableHeight - t03; } if (c_旋轉.bool_水平鏡像) { l03 = scrollviewer_1.ScrollableWidth - l03; } if (c_旋轉.int_旋轉 == 0) { if (w03 > grid_img.ActualWidth) { w03 = grid_img.ActualWidth; } if (h03 > grid_img.ActualHeight) { h03 = grid_img.ActualHeight; } } if (c_旋轉.int_旋轉 == 180) { if (w03 > grid_img.ActualWidth) { w03 = grid_img.ActualWidth; } if (h03 > grid_img.ActualHeight) { h03 = grid_img.ActualHeight; } l03 = scrollviewer_1.ScrollableWidth - l03; t03 = scrollviewer_1.ScrollableHeight - t03; } if (c_旋轉.int_旋轉 == 90) { if (w03 > grid_img.ActualWidth) { h03 = grid_img.ActualHeight; } else { h03 = scrollviewer_1.ViewportWidth; } if (h03 > grid_img.ActualHeight) { w03 = grid_img.ActualWidth; } else { w03 = scrollviewer_1.ViewportHeight; } var zzz2 = scrollviewer_1.ScrollableWidth - l03; l03 = t03; t03 = zzz2; } if (c_旋轉.int_旋轉 == 270) { if (w03 > grid_img.ActualWidth) { h03 = grid_img.ActualHeight; } else { h03 = scrollviewer_1.ViewportWidth; } if (h03 > grid_img.ActualHeight) { w03 = grid_img.ActualWidth; } else { w03 = scrollviewer_1.ViewportHeight; } var zzz2 = l03; l03 = scrollviewer_1.ScrollableHeight - t03; t03 = zzz2; } }); w03 += 50; h03 += 50; //避免圖片還沒完全載入 Thread.Sleep(30); //複製物件 ImageMagick.IMagickImage ii = null; try { /*if (image_局部高清_50 != null && img.ActualWidth < int_img_w / 2) { * ii = image_局部高清_50.Clone(); * } else {*/ if (image_局部高清 == null) { continue; } ii = image_局部高清.Clone(); //} //計算縮放比例 if (img.ActualWidth > img.ActualHeight) { d_縮放倍率 = img.ActualWidth / ii.Width; } else { d_縮放倍率 = img.ActualHeight / ii.Height; } bool_剪裁 = false; if (d_縮放倍率 * int_img_w > 5000 || d_縮放倍率 * int_img_h > 5000) { bool_剪裁 = true; //剪裁 ii.Crop(new MagickGeometry( (int)(l03 / d_縮放倍率), (int)(t03 / d_縮放倍率), (int)(w03 / d_縮放倍率), (int)(h03 / d_縮放倍率)) ); } //縮放 var mg = new ImageMagick.MagickGeometry(); mg.Height = (int)(ii.Height * d_縮放倍率); mg.Width = (int)(ii.Width * d_縮放倍率); DateTime time_start = DateTime.Now;//計時開始 取得目前時間 if (int_高品質成像模式 == 1 || int_高品質成像模式 == 4) { ii.Resize(mg);//縮放圖片-快 if (d_縮放倍率 < 1) { ii.UnsharpMask(0.8, 0.8);//銳化-快速 } //System.Console.WriteLine($"111111111"); } if (int_高品質成像模式 == 2) { ii.Resize(mg);//縮放圖片-快 if (d_縮放倍率 < 1) { ii.RemoveWriteMask(); //沒有獨立顯卡的電腦,必須用這個語法來延遲,避免圖片顯示不出來 ii.UnsharpMask(0.8, 0.8); //銳化-快速 } //System.Console.WriteLine($"2222222"); } if (int_高品質成像模式 == 3 || int_高品質成像模式 == 3) { ii.Scale(mg);//縮放圖片-慢 if (d_縮放倍率 < 1) { ii.Sharpen();//銳化-慢 } //System.Console.WriteLine($"3333333"); } DateTime time_end = DateTime.Now; //計時結束 取得目前時間 string result2 = ((TimeSpan)(time_end - time_start)).TotalMilliseconds.ToString(); //後面的時間減前面的時間後 轉型成TimeSpan即可印出時間差 System.Console.WriteLine("+++++++++++++++++++++++++++++++++++" + result2 + " 毫秒"); //ii.Sample(ii.Width,ii.Height);//品質差,速度極快 //ii.Extent(mg);//意義不明 //ii.Thumbnail(mg.Width, mg.Height);//某些情況下會很慢 //縮小圖片後進行銳化 /*if (d_縮放倍率 < 1) { * //ii.RemoveWriteMask(); * //ii.UnsharpMask(0.8, 0.8); * //ii.UnsharpMask(0.25, 0.25,8,0.065); * }*/ //System.Console.WriteLine($"mg {mg.Width} ii {ii.Width}"); //避免已經切換到其他圖片 if (int_目前圖片位置 < 0 || int_目前圖片位置 >= ar_path.Count) { continue; } if (d_倍率 != img.ActualWidth || s_path != ar_path[int_目前圖片位置]) { continue; } if (bool_啟動局部高清 == false) { s_path = ""; continue; } C_adapter.fun_UI執行緒(() => { if (bool_剪裁) { img_局部高清.Margin = new Thickness( ((int)(l03 / d_縮放倍率)) * d_縮放倍率, ((int)(t03 / d_縮放倍率)) * d_縮放倍率, -((int)(l03 / d_縮放倍率)) * d_縮放倍率 - 5000, -((int)(t03 / d_縮放倍率)) * d_縮放倍率 - 5000 ); img_局部高清.Width = mg.Width; img_局部高清.Height = mg.Height; img_局部高清.Source = ii.ToBitmapSource(); } else { img.Source = ii.ToBitmapSource(); } }); } catch (Exception e) { C_adapter.fun_UI執行緒(() => { MessageBox.Show("局部高清 錯誤 \n" + e.ToString()); }); } Thread.Sleep(1); C_adapter.fun_UI執行緒(() => { //避免已經切換到其他圖片 if (int_目前圖片位置 < 0 || int_目前圖片位置 >= ar_path.Count) { return; } if (d_倍率 != img.ActualWidth || s_path != ar_path[int_目前圖片位置]) { return; } if (bool_啟動局部高清 == false) { s_path = ""; return; } if (bool_剪裁) { img_局部高清.Visibility = Visibility.Visible; if (ii.IsOpaque == false) { img.Visibility = Visibility.Hidden; //System.Console.WriteLine($"透明"); } //System.Console.WriteLine($"剪裁"); } else { //System.Console.WriteLine($"原圖"); img_局部高清.Visibility = Visibility.Collapsed; img.Visibility = Visibility.Visible; } }); ii.Dispose(); } }).Start(); }
/// <summary> /// /// </summary> /// <param name="path"></param> private void fun_顯示圖片_核心(String path) { lab_title.ToolTip = path; //取消文字框的焦點 if (stackPlanel_動圖工具.Visibility == Visibility.Visible) { fun_主視窗取得焦點(); } int int_svg_w = 0; int int_svg_h = 0; c_旋轉.fun_初始化旋轉(0); //DateTime time_start = DateTime.Now;//計時開始 取得目前時間 //避免某些檔案已經被刪除 if (File.Exists(path) == false && Directory.Exists(path) == false) { ar_path = new List <string>(); ar_path = fun_取得圖片名單(path); //避免超出陣列 if (int_目前圖片位置 >= ar_path.Count) { int_目前圖片位置 = ar_path.Count - 1; } //如果資料夾是空的 if (ar_path.Count == 0) { fun_載入圖片或資料夾(fun_執行檔路徑() + "\\data\\imgs\\start.png"); return; } fun_顯示圖片(ar_path[int_目前圖片位置]); return; } if (ar_path == null) { fun_載入圖片或資料夾(fun_執行檔路徑() + "\\data\\imgs\\start.png"); return; } //設定title String name = path.Substring(path.LastIndexOf("\\") + 1); lab_title.Text = "『" + (int_目前圖片位置 + 1) + "/" + ar_path.Count + "』 " + name; Title = lab_title.Text; t_選單_資料夾名稱.Text = Directory.GetParent(path).Name; //判斷類型與檔案大小 s_img_type_顯示類型 = c_影像.fun_取得附檔名(path); s_img_type_附檔名 = s_img_type_顯示類型; String file_size = "???"; if (s_img_type_附檔名 == "GIF") { /*if (path.Substring(path.Length - 3).ToUpper().Equals("GIF") == false) { * * //因為IE無法解析附檔名不是GIF的GIF,所以如果附檔名不是GIF,就不要用IE * * } else */ if (e_GIF_Type == E_GIF_type.WPF && c_影像.fun_判斷檔案大小_MB(path) < 50) { //用WPF渲染,且檔案小於50M int int_幀數 = new GifBitmapDecoder(new Uri(path), BitmapCreateOptions.None, BitmapCacheOption.Default).Frames.Count; if (int_幀數 >= 600) //如果幀數太多,使用wpf渲染會無法顯示 { if (w_web == null) { c_web.fun_web初始化(path); return; } s_img_type_顯示類型 = "WEB"; } } else { //使用webbrowser來顯示 if (w_web == null) { c_web.fun_web初始化(path); return; } s_img_type_顯示類型 = "WEB"; } }//gif try { file_size = c_影像.fun_判斷檔案大小(path); } catch { } if (s_img_type_附檔名 == "PNG") { if (c_apng.fun_載入並判斷是否APNG(path)) { s_img_type_顯示類型 = "APNG"; s_img_type_附檔名 = "APNG"; } } //如果是EXE if (s_img_type_附檔名 == "EXE" || s_img_type_附檔名 == "LNK") { //類型與時間 text_imgType.Text = "EXE" + "\n" + file_size; text_imgTime.Text = File.GetLastWriteTime(path).ToString("yyyy/MM/dd\nHH:mm:ss"); c_P網.fun_播放_EXE(path); //顯示jpg物件 img.Visibility = Visibility.Visible; fun_切換_隱藏web(); fun_切換_隱藏gif(); fun_切換_隱藏voide(); //fun_切換_隱藏jpg(); fun_顯示背景顏色(); return; } //如果是ICO if (s_img_type_附檔名 == "ICO") { //類型與時間 text_imgType.Text = "ICO" + "\n" + file_size; text_imgTime.Text = File.GetLastWriteTime(path).ToString("yyyy/MM/dd\nHH:mm:ss"); c_P網.fun_播放_ICON(path); //顯示jpg物件 img.Visibility = Visibility.Visible; fun_切換_隱藏web(); fun_切換_隱藏gif(); fun_切換_隱藏voide(); //fun_切換_隱藏jpg(); fun_顯示背景顏色(); return; } //如果是APNG if (s_img_type_顯示類型 == "APNG") { //類型與時間 text_imgType.Text = "APNG" + "\n" + file_size; text_imgTime.Text = File.GetLastWriteTime(path).ToString("yyyy/MM/dd\nHH:mm:ss"); c_P網.fun_播放_APNG(path); s_img_type_顯示類型 = "JPG"; //顯示jpg物件 img.Visibility = Visibility.Visible; fun_切換_隱藏web(); fun_切換_隱藏gif(); fun_切換_隱藏voide(); //fun_切換_隱藏jpg(); fun_顯示背景顏色(); return; } //如果是資料夾,就當做是 P網 連續圖來播放 if (Directory.Exists(path)) { //類型與時間 text_imgType.Text = "pixiv動圖" + "\n" + file_size; text_imgTime.Text = File.GetLastWriteTime(path).ToString("yyyy/MM/dd\nHH:mm:ss"); c_P網.fun_播放(path); //顯示寬高 String s_連續圖的第一張 = new DirectoryInfo(path).GetFiles()[0].FullName; var bitimg2 = c_影像.func_get_BitmapImage_JPG(s_連續圖的第一張); var img_width2 = (int)bitimg2.PixelWidth; var img_height2 = (int)bitimg2.PixelHeight; fun_設定顯示圖片size(img_width2, img_height2);//顯示寬高 s_img_type_顯示類型 = "JPG"; //顯示jpg物件 img.Visibility = Visibility.Visible; fun_切換_隱藏web(); fun_切換_隱藏gif(); fun_切換_隱藏voide(); //fun_切換_隱藏jpg(); fun_圖片全滿(true); fun_顯示背景顏色(); return; } ///如果是ZIP的話,就當做 P網 連續圖來播放 if (s_img_type_附檔名 == "ZIP") { //類型與時間 text_imgType.Text = "pixiv動圖" + "\n" + file_size; text_imgTime.Text = File.GetLastWriteTime(path).ToString("yyyy/MM/dd\nHH:mm:ss"); //判斷是否為可以解析的P網動態圖 bool bool_無法解析zip = false; try { using (var x = ZipFile.OpenRead(path)) { foreach (var item2 in x.Entries) { if (item2.FullName.Equals("animation.json")) { bool_無法解析zip = true; break; } } //foreach } //suing } catch { } if (bool_無法解析zip == false) //無法解析就離開 { text_imgType.Text = "zip" + "\n" + file_size; fun_顯示錯誤圖片(path); return; } else //可以解析就播放 { c_P網.fun_播放_zip(path); } s_img_type_顯示類型 = "JPG"; //顯示jpg物件 img.Visibility = Visibility.Visible; fun_切換_隱藏web(); fun_切換_隱藏gif(); fun_切換_隱藏voide(); //fun_切換_隱藏jpg(); fun_顯示背景顏色(); return; } //------------------------- c_P網.fun_暫停(); text_imgType.Text = s_img_type_附檔名 + "\n" + file_size; text_imgTime.Text = File.GetLastWriteTime(path).ToString("yyyy/MM/dd\nHH:mm:ss"); try { //載入圖片 BitmapSource bitimg = null; //顯示寬高 int img_width = 500; int img_height = 500; if (s_img_type_附檔名 == "SVG") { if (w_web == null) { c_web.fun_web初始化(path); return; } s_img_type_顯示類型 = "WEB"; text_imgSize.Text = " ??? \n ??? "; //判斷SVG的長寬 int[] ar_wh = func_get_svg_size(path); int_svg_w = ar_wh[0]; int_svg_h = ar_wh[1]; fun_設定顯示圖片size(int_svg_w, int_svg_h); } else if (s_img_type_附檔名 == "AVI" || s_img_type_附檔名 == "MP4" || s_img_type_附檔名 == "WEBM" || s_img_type_附檔名 == "MKV" || s_img_type_附檔名 == "MTS" || s_img_type_附檔名 == "MPG") { s_img_type_顯示類型 = "MOVIE"; text_imgSize.Text = " ??? \n ??? "; } else { bitimg = c_影像.func_get_BitmapImage_更新界面(path, ref img_width, ref img_height); //顯示寬高 //img_width = (int)bitimg.PixelWidth; //img_height = (int)bitimg.PixelHeight; fun_設定顯示圖片size(img_width, img_height); //顯示寬高 } //如果圖片太大,就改用web瀏覽 /*if (s_img_type_顯示類型 == "PNG" || s_img_type_顯示類型 == "JPG" || s_img_type_顯示類型 == "BMP") { * if (img_width > 7000 || img_height > 7000) { * s_img_type_顯示類型 = "WEB"; * } * }*/ /*if (file_size.Contains("MB")) { * if (double.Parse(file_size.Replace("MB", "")) > 3) { * s_img_type = "MOVIE"; * } * }*/ if (s_img_type_顯示類型 == "WEB") { //隱藏exif視窗 c_影像.c_exif.fun_初始化exif資訊(); c_影像.c_exif.fun_顯示或隱藏視窗(); if (w_web == null) { c_web.fun_web初始化(path); return; } w_web.Left = (int)((b.PointToScreen(new Point(0, 0)).X + 5)); w_web.Top = (int)((b.PointToScreen(new Point(0, 0)).Y)); w_web.Width = (int)((b2.ActualWidth - 10) * d_解析度比例_x); w_web.Height = (int)((b.ActualHeight - 5) * d_解析度比例_y); if (img_web.Visible == false) { w_web.Visible = true; } fun_主視窗取得焦點(); new Thread(() => {//延遲載入,避免顯示不出東西 Thread.Sleep(10); C_adapter.fun_UI執行緒(() => { //如果只是一般圖片,就直接傳入SZIE,在第一時將圖片定位 if (int_svg_w == 0 && int_svg_h == 0) { int_svg_w = img_width; int_svg_h = img_height; } fun_主視窗取得焦點(); String s_url_path = "http://localhost:" + c_localhost.port + "/img_path/" + Uri.EscapeDataString(path) + "*" + DateTime.Now.ToString("yyyyMMddHHmmssffff"); img_web.Document.InvokeScript("fun_open_imgbox", new Object[] { s_url_path, int_svg_w.ToString(), int_svg_h.ToString() }); //img_web.Document.Focus(); Log.print(s_url_path); }); }).Start(); //fun_切換_隱藏web(); fun_切換_隱藏gif(); fun_切換_隱藏voide(); fun_切換_隱藏jpg(); //text_imgSize.Focus(); } else if (s_img_type_顯示類型 == "GIF") { //隱藏exif視窗 c_影像.c_exif.fun_初始化exif資訊(); c_影像.c_exif.fun_顯示或隱藏視窗(); WpfAnimatedGif.ImageBehavior.SetAutoStart(img_gif, true); img_gif.Visibility = Visibility.Visible; WpfAnimatedGif.ImageBehavior.SetAnimatedSource(img_gif, bitimg); fun_切換_隱藏web(); //fun_切換_隱藏gif(); fun_切換_隱藏voide(); fun_切換_隱藏jpg(); } else if (s_img_type_顯示類型 == "MOVIE") { //隱藏exif視窗 c_影像.c_exif.fun_初始化exif資訊(); c_影像.c_exif.fun_顯示或隱藏視窗(); fun_切換_隱藏web(); fun_切換_隱藏gif(); //fun_切換_隱藏voide(); fun_切換_隱藏jpg(); img_voide.Visibility = Visibility.Visible; String path_v = func_取得影片檔案路徑(path); img_voide.Source = new Uri(path_v); img_voide.LoadedBehavior = MediaState.Play; //MessageBox.Show(s_url_path); } else //一般圖片 { img.Visibility = Visibility.Visible; //顯示圖片 /*if (img_width > 9999 && (s_img_type_顯示類型 == "PNG")) {//縮小圖片後在載入 * img.Source = c_影像.fun_get_BitmapImage_max(path, "w", 9999); * } else if (img_height > 9999 && s_img_type_顯示類型 == "PNG") { * img.Source = c_影像.fun_get_BitmapImage_max(path, "h", 9999); * } else { * img.Source = bitimg;//直接顯示 * }*/ //如果圖片太大,就把圖片縮小到視窗範圍的size if (s_img_type_附檔名 == "PNG" || s_img_type_附檔名 == "JPG" || s_img_type_附檔名 == "TIF" || s_img_type_附檔名 == "BMP") { if (img_width > scrollviewer_1.ViewportWidth || img_height > scrollviewer_1.ViewportHeight) //縮小圖片後在載入 //2500 { var w03 = scrollviewer_1.ViewportWidth; var h03 = scrollviewer_1.ViewportHeight; try { if (img_width / w03 > img_height / h03) { img.Source = c_影像.fun_get_BitmapImage_max(path, "w", (int)w03); } else { img.Source = c_影像.fun_get_BitmapImage_max(path, "h", (int)h03); } } catch { img.Source = bitimg;//直接顯示 } } else { img.Source = bitimg;//直接顯示 } } else { img.Source = bitimg;//直接顯示 } fun_切換_隱藏web(); fun_切換_隱藏gif(); fun_切換_隱藏voide(); //fun_切換_隱藏jpg(); bool_啟動局部高清 = true; } } catch (Exception e) { //MessageBox.Show("fdf\n"+e.ToString()); fun_顯示錯誤圖片(path); } fun_圖片全滿(true); fun_顯示背景顏色(); }
/// <summary> /// /// </summary> /// <param name="s_type"></param> private void fun_執行搜圖(String s_type) { if (s_type == "iqdb") { fun_寫入搜圖input(s_type, M.ar_path[M.int_目前圖片位置]); return; } try { var img_width = M.int_img_w; var img_height = M.int_img_h; bool bool_需要縮小 = img_width > 1000 || img_height > 1000; bool_需要縮小 = false; BitmapImage bitmapImage = null; BitmapEncoder encoder = null; //可能是jpg或png或gif if (M.stackPlanel_動圖工具.Visibility == Visibility.Visible) //動圖 { encoder = new PngBitmapEncoder(); encoder.Frames.Add(BitmapFrame.Create(M.c_P網.fun_取得第一張圖片())); } /*else if (M.s_img_type_附檔名 == "SVG") {//SVG * * MessageBox.Show("SVG圖片 無法線上搜圖"); * return; * * }*/ else if (M.s_img_type_顯示類型 == "MOVIE") //MMOVIE //影片的話,就透過截圖的方式來處理 //如果影片大於視窗,就先縮小後再截圖 { if (M.scrollviewer_1.ScrollableHeight > 0 || M.scrollviewer_1.ScrollableWidth > 0) { M.fun_圖片全滿(); new Thread(() => {//50毫秒後重新執行這個function Thread.Sleep(50); C_adapter.fun_UI執行緒(() => { fun_執行搜圖(s_type); }); }).Start(); return; } else { encoder = new PngBitmapEncoder(); encoder.Frames.Add(BitmapFrame.Create(M.SaveTo(M.img_voide))); } } else //靜態圖 { String s_當前目錄 = M.ar_path[M.int_目前圖片位置]; /*if ( M.s_img_type_附檔名 == "PSD") {//PSD 使用內建的解碼器 * * encoder = new PngBitmapEncoder(); * * //var im = M.fun_get_BitmapImage_s(s_當前目錄); * * BitmapSource bitimg = null; * SimplePsd.CPSD psd = new SimplePsd.CPSD(); * psd.Load(s_當前目錄); * System.Drawing.Bitmap fromHbitmap = System.Drawing.Image.FromHbitmap(psd.GetHBitmap()); * bitimg = M.c_apng.BitmapToBitmapSource(fromHbitmap); * fromHbitmap.Dispose(); * * * encoder.Frames.Add(BitmapFrame.Create(bitimg)); * * } else*/ String ss = M.s_img_type_附檔名.ToUpper(); //一般格式 if (ss == "JPG" || ss == "JPEG" || ss == "BMP" || ss == "PNG" || ss == "GIF" || ss == "TIF") { using (BinaryReader reader = new BinaryReader(File.Open(s_當前目錄, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))) { FileInfo fi = new FileInfo(s_當前目錄); byte[] bytes = reader.ReadBytes((int)fi.Length); reader.Close(); bitmapImage = new BitmapImage(); bitmapImage.BeginInit(); bitmapImage.StreamSource = new MemoryStream(bytes); if (bool_需要縮小) { if (img_width > img_height) { bitmapImage.DecodePixelWidth = 1000; } else { bitmapImage.DecodePixelHeight = 1000; } } bitmapImage.EndInit(); bitmapImage.CacheOption = BitmapCacheOption.None; } //依照檔案類型來初始化 if (M.s_img_type_附檔名 == "PNG") { encoder = new PngBitmapEncoder(); } else if (M.s_img_type_附檔名 == "GIF") { encoder = new GifBitmapEncoder(); } else { encoder = new JpegBitmapEncoder(); } encoder.Frames.Add(BitmapFrame.Create(bitmapImage)); } else { encoder = new JpegBitmapEncoder(); try { using (var im = M.c_影像.c_Magick.getImg(s_當前目錄, M.s_img_type_附檔名)) { encoder.Frames.Add(BitmapFrame.Create(im.ToBitmapSource())); } } catch { encoder.Frames.Add(BitmapFrame.Create(M.c_影像.BitmapToBitmapSource(M.c_影像.func_作業系統圖示(s_當前目錄)))); } } } string base64String = ""; using (MemoryStream memoryStream = new MemoryStream()) { encoder.Save(memoryStream); byte[] temp = memoryStream.ToArray(); //Clipboard.SetDataObject(temp); base64String = "data:image/jpeg;base64," + Convert.ToBase64String(temp); fun_寫入搜圖input(s_type, base64String); } //清理圖片 if (encoder.Frames.Count > 0 && encoder.Frames[0] != null) { encoder.Frames[0].Freeze(); } if (bitmapImage != null) { bitmapImage.Freeze(); } /* * using (FileStream st = new FileStream("11.jpg", FileMode.Create)) { * byte[] temp = memoryStream.ToArray(); * st.Write(temp, 0, temp.Length); * }*/ } catch (Exception e3) { MessageBox.Show(e3.ToString()); } }
/// <summary> /// /// </summary> public void fun_web初始化(String s_path) { if (M.Topmost == true) { M.Topmost = false; //初始化web M.w_web = new F_web(M); M.img_web = M.w_web.webBrowser1; SetOwner(M.w_web, M); M.Topmost = true; } else { //初始化web M.w_web = new F_web(M); M.img_web = M.w_web.webBrowser1; SetOwner(M.w_web, M); } bool bool_移動中 = false; //改變視窗size時隱藏web,避免拖曳速度很慢 M.SizeChanged += (sender, e) => { if (M.s_img_type_顯示類型 == "WEB") { //img_web_box.Visibility = Visibility.Collapsed; //img_web.Visible = false; //w_web.Visibility = Visibility.Collapsed; //w_web.Visible = false; bool_移動中 = true; } }; //改變視窗size時,不要立即變動web size new Thread(() => { int nn = 0; while (M.bool_程式運行中) { nn++; Thread.Sleep(30); if (M.s_img_type_顯示類型 == "WEB") { //讓web視窗跟著主視窗移動 C_adapter.fun_UI執行緒(() => { if (M.bool_程式運行中) { M.w_web.Left = (int)((M.b.PointToScreen(new Point(0, 0)).X + 5)); M.w_web.Top = (int)(M.b.PointToScreen(new Point(0, 0)).Y); } }); //每90毫秒修改一次視窗size if (nn >= 3) { nn = 0; //避免快速瀏覽的視窗已經隱藏了,但是web視窗還沒隱藏 if (M.Visibility != Visibility.Visible) { C_adapter.fun_UI執行緒(() => { M.fun_載入圖片或資料夾(M.fun_執行檔路徑() + "/data/imgs/space.png"); }); } C_adapter.fun_UI執行緒(() => { int bw = (int)((M.b2.ActualWidth - 10) * M.d_解析度比例_x); int bh = (int)((M.b.ActualHeight - 5) * M.d_解析度比例_y); if (bw <= 10) { bw = 10; } if (bh <= 10) { bh = 10; } if (M.w_web.Width != bw || M.w_web.Height != bh) { M.w_web.Width = bw; M.w_web.Height = bh; } else { if (bool_移動中) { //如果大小跟視窗一樣,才顯示回來 bool_移動中 = false; //w_web.Visible = true; M.img_web.Document.InvokeScript("eval", new Object[] { "setTimeout(function () { fun_imgSizeChange(); fun_beyond();}, 50);" });//重新調整圖片位置 M.fun_主視窗取得焦點(); } } }); } } }//while }).Start(); //初始網頁 this.path = s_path; M.img_web.Navigated += Img_web_Navigated; M.img_web.Navigate(M.fun_執行檔路徑() + "/data/img.html"); //載入 M.img_web.ObjectForScripting = new C_web呼叫javaScript(M); //讓網頁允許存取C# M.img_web.Navigating += (sender2, e2) => { M.fun_Zoom(M.img_web, 100);//網頁比例100% M.fun_載入圖片或資料夾(e2.Url.ToString()); e2.Cancel = true; }; }
/// <summary> /// 網頁載入完成後,才載入GIF /// </summary> private void Img_web_Navigated(object sender123, System.Windows.Forms.WebBrowserNavigatedEventArgs e123) { C_滑鼠偵測_滾動.MouseWheel += C_滑鼠偵測_滾動_MouseWheel; //M.w_web.MouseWheel += C_滑鼠偵測_滾動_MouseWheel; /* * M.w_web.MouseWheel += (sernder, e) => { * MessageBox.Show("" + e.Delta); * };*/ //web的選單 M.img_web.Document.ContextMenuShowing += (object sender, System.Windows.Forms.HtmlElementEventArgs e) => { M.func_開啟右鍵選單(); }; //雙擊web 全螢幕 用的全域變數 DateTime time_雙擊web全螢幕 = DateTime.Now;// System.Drawing.Point point_雙擊web全螢幕 = M.fun_取得滑鼠(); //讓web也能拖曳視窗 M.img_web.Document.MouseDown += ((sender2, e2) => { M.img_web.Document.Focus(); if (e2.MouseButtonsPressed == System.Windows.Forms.MouseButtons.Left) { //雙擊web 全螢幕 if (((TimeSpan)(DateTime.Now - time_雙擊web全螢幕)).TotalMilliseconds < 400) //連點低於400毫秒 { if (M.grid_換頁按鈕_下.Visibility == Visibility.Visible && M.fun_取得滑鼠().Y > M.PointToScreen(new Point(0, 0)).Y + M.Height - 100 && M.fun_取得滑鼠().Y < M.PointToScreen(new Point(0, 0)).Y + M.Height - 20 && M.fun_取得滑鼠().X > M.PointToScreen(new Point(0, 0)).X + 20 && M.fun_取得滑鼠().X < M.PointToScreen(new Point(0, 0)).X + M.ActualWidth - 20) { return; } if (point_雙擊web全螢幕 == M.fun_取得滑鼠())//同一個點 { if (M.WindowState != WindowState.Maximized) { M.WindowState = WindowState.Maximized; } else { M.WindowState = WindowState.Normal; } } time_雙擊web全螢幕 = DateTime.Now.AddHours(-5);//避免連點3下又跑回來 } else { time_雙擊web全螢幕 = DateTime.Now; } point_雙擊web全螢幕 = M.fun_取得滑鼠(); try { if (M.fun_判斷滑鼠是否在右下角()) //讓右下角可以拖曳改變視窗大小 { if (M.WindowState != WindowState.Maximized) { M.c_視窗改變大小.ResizeWindow(ResizeDirection.BottomRight); } } else { //如果網頁沒有捲軸,就拖曳視窗 String x = (String)M.img_web.Document.InvokeScript("fun_bool_movie", new Object[] { });//用js判斷目前是否有捲軸 if (x.ToString().Equals("true")) { if (M.WindowState != WindowState.Maximized) //不是全螢幕 { M.c_視窗改變大小.ResizeWindow(ResizeDirection.Move); //拖曳視窗 } } } } catch { } } }); //延遲載入,避免GIF無法顯示 new Thread(() => { Thread.Sleep(1); C_adapter.fun_UI執行緒(() => { M.c_set.fun_套用setting設定(); M.fun_載入圖片或資料夾(path); }); }).Start(); }