C#如何實(shí)現(xiàn)圖片查看器
這篇文章將簡單介紹下如何使用C#來實(shí)現(xiàn)一個(gè)圖片查看器的功能的,該工具保存的功能有:
1、 可以通過“上一張” “下一張”這樣的按鈕來輪換瀏覽圖片
2、實(shí)現(xiàn)對(duì)圖片的旋轉(zhuǎn)
3、實(shí)現(xiàn)對(duì)旋轉(zhuǎn)后圖片的保存功能。本程序不僅提供旋轉(zhuǎn)90/180/270這樣的實(shí)現(xiàn),同時(shí)提供一個(gè)方法來完成旋轉(zhuǎn)任意角度的實(shí)現(xiàn)
4、該程序未實(shí)現(xiàn)Windows圖片查看圖片縮放的功能,這部分的功能主要要點(diǎn)是改變圖片在PictureBox控件中的高度和寬度就可以的
二、實(shí)現(xiàn)思路
2.1 圖片輪換瀏覽功能的實(shí)現(xiàn)
首先分析下第一個(gè)功能點(diǎn)的實(shí)現(xiàn),要實(shí)現(xiàn)圖片的輪換瀏覽,我們可以根據(jù)下面的思路來實(shí)現(xiàn):
第一步、獲得目錄下所有圖片的集合,此時(shí)使用Directory.GetFiles()來獲得目錄下所有文件,然后再對(duì)該集合進(jìn)行篩選,篩選出是圖片的文件,代碼用擴(kuò)展名進(jìn)行篩選的
第二步、獲得所有圖片集合之后,實(shí)現(xiàn)圖片輪換就需要改變這個(gè)集合的索引就可以實(shí)現(xiàn)上一張和下一張的功能了
第三步、需要考慮到最后一張或者第一張的情況下,再點(diǎn)擊下一張或上一張圖片來輪換成第一張或最后一張
思路就是上面的,有了上面的思路之后,就讓我們看看具體的代碼來對(duì)照理解下:
// 第一步 // 獲得預(yù)覽圖片文件路徑下的圖片集合 public static List<string> GetImgCollection(string path) { string[] imgarray = Directory.GetFiles(path); var result = from imgstring in imgarray where imgstring.EndsWith("jpg", StringComparison.OrdinalIgnoreCase) || imgstring.EndsWith("png", StringComparison.OrdinalIgnoreCase)|| imgstring.EndsWith("bmp", StringComparison.OrdinalIgnoreCase) select imgstring; return result.ToList(); } // 第二步 // 獲得打開圖片在圖片集合中的索引 private int GetIndex(string imagepath) { int index = 0; for (int i = 0; i < imgArray.Count; i++) { if (imgArray[i].Equals(imagepath)) { index = i; break; } } return index; } // 切換圖片的方法 private void SwitchImg(int index) { newbitmap = Image.FromFile(imgArray[index]); picBoxView.Image = newbitmap; imgPath = imgArray[index]; } // 第三步 // 上一張圖片 private void btnPre_Click(object sender, EventArgs e) { int index = GetIndex(imgPath); // 釋放上一張圖片的資源,避免保存的時(shí)候出現(xiàn)ExternalException異常 newbitmap.Dispose(); if (index == 0) { SwitchImg(imgArray.Count - 1); } else { SwitchImg(index - 1); } } // 下一張圖片 private void btnNext_Click(object sender, EventArgs e) { int index = GetIndex(imgPath); // 釋放上一張圖片的資源,避免保存的時(shí)候出現(xiàn)ExternalException異常 // 經(jīng)常在調(diào)用Save方法的時(shí)候都會(huì)出現(xiàn) 一個(gè)GDI一般性錯(cuò)誤,主要原因是文件沒有被釋放,當(dāng)保存到原位置時(shí),就會(huì)出現(xiàn)該異常,要避免這個(gè)錯(cuò)誤就要釋放圖片占有的資源 newbitmap.Dispose(); if (index != imgArray.Count - 1) { SwitchImg(index + 1); } else { SwitchImg(0); } }
2.2 圖片旋轉(zhuǎn)功能的實(shí)現(xiàn)
上面的代碼實(shí)現(xiàn)了第一個(gè)功能點(diǎn)的問題了,下面就解釋下如何實(shí)現(xiàn)第二個(gè)功能點(diǎn)——圖片旋轉(zhuǎn)的問題:
對(duì)于Windows自帶的圖片查看器,它旋轉(zhuǎn)的角度只能順時(shí)針旋轉(zhuǎn)90或逆時(shí)針旋轉(zhuǎn)90度,這個(gè)功能實(shí)現(xiàn)起來可以說非常簡單,只需要使用Image.RotateFlip(RotateFlipType)方法就可以完成的,有些朋友也想對(duì)圖片實(shí)現(xiàn)旋轉(zhuǎn)任意角度,對(duì)于這個(gè)問題源碼中也有具體的實(shí)現(xiàn),大家可以從文章的最后下載源碼進(jìn)行查看,這里就不貼出具體代碼的,下面就看看如何實(shí)現(xiàn)Windows自帶的圖片查看器的旋轉(zhuǎn)功能的代碼:
// 順時(shí)針旋轉(zhuǎn)90度旋轉(zhuǎn)圖片 private void btnRotate_Click(object sender, EventArgs e) { picBoxView.SizeMode = PictureBoxSizeMode.Zoom; // 順時(shí)針旋轉(zhuǎn)90度的另外一種實(shí)現(xiàn) newbitmap.RotateFlip(RotateFlipType.Rotate90FlipNone); picBoxView.Image = newbitmap; isRotate = true; //newbitmap = (Image)ImageManager.RotateImg(bitmap, 90f, Color.Transparent); ; //bitmap.Dispose(); //picBoxView.Image = newbitmap; } // 逆時(shí)針旋轉(zhuǎn)90度 private void btncounterclockwiseRotate_Click(object sender, EventArgs e) { picBoxView.SizeMode = PictureBoxSizeMode.Zoom; // 逆時(shí)針旋轉(zhuǎn)90度的另外實(shí)現(xiàn) newbitmap.RotateFlip(RotateFlipType.Rotate270FlipNone); picBoxView.Image = newbitmap; isRotate = true; // 下面是旋轉(zhuǎn)任意角度的代碼 //newbitmap = (Image)ImageManager.RotateImg(bitmap, 360f-90f, Color.Transparent); ; //bitmap.Dispose(); //picBoxView.Image = newbitmap; }
2.3 對(duì)旋轉(zhuǎn)圖片的保存功能的實(shí)現(xiàn)
最后就是針對(duì)旋轉(zhuǎn)圖片保存的實(shí)現(xiàn)了,此時(shí)我參考了Windows自帶圖片查看器的實(shí)現(xiàn)方式,因?yàn)槲矣肳indows自帶圖片查看器瀏覽圖片的實(shí)現(xiàn),當(dāng)我旋轉(zhuǎn)圖片時(shí),它并不是實(shí)時(shí)地保存到旋轉(zhuǎn)的圖片的,而是當(dāng)我關(guān)閉Windows自帶圖片查看器的時(shí)候,旋轉(zhuǎn)的圖片才保存到文件中的,有了這個(gè)思路之后,我就把我保存的代碼邏輯放在窗體的關(guān)閉的事件處理程序中來實(shí)現(xiàn)的,此時(shí)保存的功能我們只需要調(diào)用Image.Save(path)方法就可以完成對(duì)圖片的保存,下面就看看具體代碼的實(shí)現(xiàn)的:
// 關(guān)閉窗體后保存旋轉(zhuǎn)后的圖片到文件中 private void Form1_FormClosed(object sender, FormClosedEventArgs e) { if (imgPath == null || isRotate == false) { return; } // 保存旋轉(zhuǎn)后的圖片 switch (Path.GetExtension(imgPath).ToLower()) { case ".png": newbitmap.Save(imgPath, ImageFormat.Png); newbitmap.Dispose(); break; case ".jpg": newbitmap.Save(imgPath); newbitmap.Dispose(); break; default: newbitmap.Save(imgPath, ImageFormat.Bmp); newbitmap.Dispose(); break; } }
三、實(shí)現(xiàn)效果
上面已經(jīng)介紹了實(shí)現(xiàn)該程序的一個(gè)思路的,朋友是不是迫不及待的想看到到底自定義圖片查看器是什么樣子的呢?下面就通過一個(gè)動(dòng)畫來讓大家更形象地看到程序的運(yùn)行效果的:
四、小結(jié)
到這里該文章的內(nèi)容就介紹結(jié)束了,希望大家如果遇到類似的問題可以很快從這篇文章中得到解決。
相關(guān)文章
C#多線程處理多個(gè)隊(duì)列數(shù)據(jù)的方法
這篇文章主要介紹了C#多線程處理多個(gè)隊(duì)列數(shù)據(jù)的方法,涉及C#線程與隊(duì)列的相關(guān)操作技巧,需要的朋友可以參考下2015-07-07asp.net core項(xiàng)目mvc權(quán)限控制:分配權(quán)限
學(xué)習(xí)的最好方法就是動(dòng)手去做,這里以開發(fā)一個(gè)普通的權(quán)限管理系統(tǒng)的方式來從零體驗(yàn)和學(xué)習(xí)Asp.net Core。項(xiàng)目的整體規(guī)劃大致如下2017-02-02C# AE之返回上一級(jí)和下一級(jí)的實(shí)戰(zhàn)操作
這篇文章主要介紹了C# AE之返回上一級(jí)和下一級(jí)的實(shí)戰(zhàn)操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2021-01-01C# Redis學(xué)習(xí)系列(二)Redis基本設(shè)置
這篇文章主要為大家分享了C# Redis學(xué)習(xí)系列教程第二篇, Redis基本設(shè)置,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-05-05C#對(duì)WPF數(shù)據(jù)綁定的菜單插入Seperator分隔
這篇文章介紹了C#對(duì)WPF數(shù)據(jù)綁定的菜單插入Seperator分隔的方法,文中通過示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-06-06C#實(shí)現(xiàn)金額轉(zhuǎn)換成中文大寫金額
這篇文章主要為大家詳細(xì)介紹了C#實(shí)現(xiàn)金額轉(zhuǎn)換成中文大寫金額,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-08-08