日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > C# >内容正文

C#

C#图片处理

發(fā)布時(shí)間:2025/3/15 C# 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C#图片处理 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

通常對(duì)一幅圖片的處理包括:格式變換,縮放(Scale),翻轉(zhuǎn)(Rotate),截取(Clip),濾鏡(Filter,如高斯模糊)等。

1,圖片格式轉(zhuǎn)換

.NET中的Image類是對(duì)圖片對(duì)象的封裝,我們可以通過(guò)操作Image類的實(shí)例來(lái)處理圖片。通常我們有兩種式可以得到Image實(shí)例:

var imgPng = Image.FromFile(@"C:\temp\img\pp.png");byte[] raw = ReadFromFileOrNetwork(); var imgBmp = Image.FromStream(new MemoryStream(raw));

?

1.1判斷圖片格式

var imgJpg = Image.FromFile(@"C:\temp\img\jj.jpg"); if (imgJpg.RawFormat.Equals(ImageFormat.Jpeg)) {MessageBox.Show("Jpeg"); }

注意這里使用ImageFormat.Equals方法,而不能使用==,如果非要使用等號(hào),可以:

if (imgPng.RawFormat.Guid == ImageFormat.Png.Guid) {MessageBox.Show("Png"); }

1.2,圖片格式轉(zhuǎn)換

imgPng.Save(@"c:\temp\img\newBmp.bmp", ImageFormat.Jpeg);

?

2,圖片的縮放(Scale)

圖片的放大,縮小,拉伸可以通過(guò)Image實(shí)例的GetThumbnailImage來(lái)實(shí)現(xiàn)

//縮小 var newPng = imgPng.GetThumbnailImage(imgPng.Width / 2, imgPng.Height / 2, () => { return false; }, IntPtr.Zero); newPng.Save(@"c:\temp\img\newPng.png"); //放大 var newJpg = newPng.GetThumbnailImage(imgPng.Width * 2, imgPng.Height * 2, () => { return false; }, IntPtr.Zero); newJpg.Save(@"c:\temp\img\newJpg.jpg", ImageFormat.Jpeg); //拉伸(Stretch) var newGif = newPng.GetThumbnailImage(imgPng.Width * 2, imgPng.Height /2, () => { return false; }, IntPtr.Zero); newGif.Save(@"c:\temp\img\newGif.gif", ImageFormat.Gif);

?

3,圖片的翻轉(zhuǎn)(Rotate)

圖片的翻轉(zhuǎn)通過(guò)Image.RotateFlip方法來(lái)實(shí)現(xiàn)

//翻轉(zhuǎn) imgPng.RotateFlip(RotateFlipType.Rotate180FlipX); imgPng.Save(@"c:\temp\img\newPng.png");

可以通過(guò)RotateFlipType調(diào)整翻轉(zhuǎn)的角度

?

4,圖片的截取(Clip)

有時(shí)我們只想要圖片的一部分,比如左邊100個(gè)像素,而不是整個(gè)圖片。我們可以通過(guò)兩種方式來(lái)實(shí)現(xiàn)。

4.1,拷貝原圖片的部分像素

Rectangle rect = new Rectangle(0, 0, imgPng.Width / 2, imgPng.Height); Bitmap clipPng = new Bitmap(imgPng).Clone(rect, imgPng.PixelFormat); clipPng.Save(@"c:\temp\img\clipPng.png");

?

4.2,畫出部分圖片

Rectangle rect = new Rectangle(0, 0, imgPng.Width / 3, imgPng.Height); //target size Bitmap canvas = new Bitmap(rect.Width,rect.Height); //create canvas(width&heigh same as target)using (Graphics g = Graphics.FromImage(canvas)) {g.DrawImageUnscaledAndClipped(imgPng, rect); } canvas.Save(@"c:\temp\img\canvas.png");

?

5,濾鏡(Filter)

通常我們對(duì)圖片使用濾鏡,就是對(duì)圖片的像素點(diǎn)進(jìn)行矩陣變換(Matrix)。我們先從單個(gè)像素點(diǎn)的處理開始:

5.1,顏色反轉(zhuǎn)(Color Invert)

Color Invert是指對(duì)位圖的每個(gè)像素取其反色,Jpg和Bmp格式的顏色是以RGB(Red Green Blue)來(lái)表示的,也就是每個(gè)像素點(diǎn)由RGB三種顏色來(lái)組成。Png由于可以設(shè)置為透明,所以加了一個(gè)Alpha通道,也就是說(shuō)Png是用RGBA來(lái)表示的。

有一點(diǎn)需要注意的是,我們使用Image來(lái)獲取的顏色表示并不是RGB而是BGR,準(zhǔn)確地說(shuō)這是GD+在底層返回的就不是RGB,而是BGR這點(diǎn)需要特別注意。對(duì)于Png文件我們還可以通過(guò)Alpha通道來(lái)設(shè)置圖片的透明度。

/* Usage:InvertColor(@"C:\temp\img\colorInvert.png", @"C:\temp\img\colorInvert-1.png"); */ private static void InvertColor(string srcFileName,string destFileName) {var bitPic = new Bitmap(srcFileName);if (!(bitPic.RawFormat.Equals(ImageFormat.Bmp) || bitPic.RawFormat.Equals(ImageFormat.Jpeg) || bitPic.RawFormat.Equals(ImageFormat.Png))){MessageBox.Show("Unsuported format,only support for bmp,jpg or png");return;}Rectangle rect = new Rectangle(0, 0, bitPic.Width, bitPic.Height);var bmpData = bitPic.LockBits(rect, ImageLockMode.ReadWrite, bitPic.PixelFormat); // GDI+ still lies to us - the return format is BGR, NOT RGB. IntPtr ptr = bmpData.Scan0;// Declare an array to hold the bytes of the bitmap.int totalPixels = Math.Abs(bmpData.Stride) * bitPic.Height; //Stride tells us how wide a single line is,width*heith come up with total pixelbyte[] rgbValues = new byte[totalPixels];// Copy the RGB values into the array.Marshal.Copy(ptr, rgbValues, 0, totalPixels); //RGB=>rgbValusif (bitPic.RawFormat.Equals(ImageFormat.Bmp) || bitPic.RawFormat.Equals(ImageFormat.Jpeg)){int b = 0, g = 1, r = 2; //BGRfor (int i = 0; i < totalPixels; i += 3){rgbValues[r + i] = (byte)(255 - rgbValues[r + i]);rgbValues[g + i] = (byte)(255 - rgbValues[g + i]);rgbValues[b + i] = (byte)(255 - rgbValues[b + i]);}}else if (bitPic.RawFormat.Equals(ImageFormat.Png)){int b = 0, g = 1, r = 2, a = 3; //BGRAfor (int i = 0; i < totalPixels; i += 4){rgbValues[r + i] = (byte)(255 - rgbValues[r + i]);rgbValues[g + i] = (byte)(255 - rgbValues[g + i]);rgbValues[b + i] = (byte)(255 - rgbValues[b + i]);rgbValues[a + i] = 255; //NOTE:you can set (255*threshold) for transparency.}}Marshal.Copy(rgbValues, 0, ptr, totalPixels);bitPic.UnlockBits(bmpData);bitPic.Save(destFileName); }

對(duì)于GIF,由于他并不是按RGB的顏色來(lái)編碼,而是用另一種256色的顏色編碼,我稍后再研究:)

?

5.2,灰度圖(Grayscale)

Grayscale就是將每像素點(diǎn)的RGB值作平均,即第個(gè)像素的RGB分量值都是一樣的。這樣做的目的就因?yàn)榈戎档腞GB(R=G=B)就是從黑到白的顏色區(qū)間,我們可以通過(guò)GIMP看下:

當(dāng)每個(gè)像素點(diǎn)的組成RGB相等時(shí),該點(diǎn)必定是灰色調(diào)的。

我們的代碼也有調(diào)整,這次使用Bitmap.GetPixel來(lái)得到圖片的RGB值,這樣就不需要對(duì)圖片的格式進(jìn)行特別處理了。不過(guò)還是不可以處理Gif等使用Indexed Color的圖片。

private void Grayscale(string srcFileName, string destFileName) {var bitPic = new Bitmap(srcFileName);if (!(bitPic.RawFormat.Equals(ImageFormat.Bmp) ||bitPic.RawFormat.Equals(ImageFormat.Jpeg) ||bitPic.RawFormat.Equals(ImageFormat.Png))){MessageBox.Show("Unsuported format,only support for bmp,jpg or png");return;}int rgb;Color c;for (int y = 0; y < bitPic.Height; y++){for (int x = 0; x < bitPic.Width; x++){c = bitPic.GetPixel(x, y);rgb = (int)((c.R + c.G + c.B) / 3); //We can adjust this calc as needed, such as Max(r,g,b),Min(r,g,b),(.299*r +.587*g.+ .114*b)bitPic.SetPixel(x, y, Color.FromArgb(rgb, rgb, rgb));}}bitPic.Save(destFileName); }

?

5.3,明亮度(Brightness)

計(jì)算機(jī)中顏色(Color)是用RGB來(lái)表示的,但我們?nèi)搜蹖?duì)色彩的認(rèn)識(shí)的模式是HSV(純度Hue,飽和度Saturation,亮度Value或Luminance)。我們可以使得RGB的每個(gè)分量的值增大來(lái)讓圖片變亮,也可以使每個(gè)分量變小來(lái)讓圖片變暗。而HSV模式的明暗設(shè)置就更簡(jiǎn)單了,只需改V分量值即可以改變圖片的明暗。關(guān)于RGB到HSL/HSV的轉(zhuǎn)換算法可以看Wikipedia。有一點(diǎn)需要注意的就是.net中Color類的GetHue,GetSaturation,GetBrightness獲取的是HSL值而不是HSV值。

3.1,通過(guò)RGB來(lái)改變明暗度

private void Brightness(string srcFileName, string destFileName, float grain) {var bitPic = new Bitmap(srcFileName);if (!(bitPic.RawFormat.Equals(ImageFormat.Bmp) ||bitPic.RawFormat.Equals(ImageFormat.Jpeg) ||bitPic.RawFormat.Equals(ImageFormat.Png))){MessageBox.Show("Unsuported format,only support for bmp,jpg or png");return;}Color c;Func<int, int> notOver255 = (x) => { return x > 255 ? 255 : x; };for (int y = 0; y < bitPic.Height; y++){for (int x = 0; x < bitPic.Width; x++){c = bitPic.GetPixel(x, y);Color brightColor = Color.FromArgb(notOver255((int)(c.R * grain)), notOver255((int)(c.G * grain)), notOver255((int)(c.B * grain)));bitPic.SetPixel(x, y, brightColor);}}bitPic.Save(destFileName); }

?

3.2通過(guò)HSV中V分量來(lái)改變圖片明暗度

稍后研究,還有個(gè)問題就是改變圖片的明暗度后,Png和Jpg圖片的大小產(chǎn)生了變化,換個(gè)說(shuō)法就是RGB分量值會(huì)影響Png和Jpg壓縮。

?

?


Reference:

1,http://www.codeproject.com/Articles/1989/Image-Processing-for-Dummies-with-C-and-GDI-Part-1

2,http://en.wikipedia.org/wiki/HSL_and_HSV

3,http://stackoverflow.com/questions/359612/how-to-change-rgb-color-to-hsv

4,http://www.cnblogs.com/sndnnlfhvk/archive/2012/02/27/2370643.html

轉(zhuǎn)載于:https://www.cnblogs.com/Jerry-Chou/archive/2012/03/21/2409590.html

總結(jié)

以上是生活随笔為你收集整理的C#图片处理的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。