WPF图片(Image)处理相关 您所在的位置:网站首页 metafile和bitmap存为哪个 WPF图片(Image)处理相关

WPF图片(Image)处理相关

2023-12-08 19:47| 来源: 网络整理| 查看: 265

图片相关类常见的类

关系

image-20230627122520503

Image和Bitmap

继承关系

System.Object System.MarshalByRefObject System.Drawing.Image System.Drawing.Bitmap

Image

为源自 Bitmap 和 Metafile 的类提供功能的抽象基类。

123456// Create image.Image newImage = Image.FromFile("SampImag.jpg");// Create Point for upper-left corner of image.Point ulCorner = new Point(100, 100);// Draw image to screen.e.Graphics.DrawImage(newImage, ulCorner);

Bitmap

封装 GDI+ 位图,此位图由图形图像及其属性的像素数据组成。

Bitmap 是用于处理由像素数据定义的图像的对象。

位图由图形图像及其属性的像素数据组成。

有许多标准格式可用于将位图保存到文件。

GDI+ 支持以下文件格式: BMP、GIF、EXIF、JPG、PNG 和 TIFF。

有关支持的格式的详细信息,请参阅位图类型。

您可以通过使用 Bitmap 构造函数之一,从文件、流和其他源创建图像,并使用 Save 方法将它们保存到流或文件系统。

使用 Graphics 对象的 DrawImage 方法将图像绘制到屏幕或内存。

Bitmap是从Image类继承的一个图像类,它封装了Windows位图操作的常用功能。

例如:Bitmap::SetPixel和Bitmap::GetPixel分别用来对位图进行读写像素操作,从而可以为图像的柔化和锐化处理提供一种可能。

示例

12Image img = this.pictureBox1.Image;Bitmap map = new Bitmap(img); GetHbitmap

Bitmap的GetHbitmap()方法

官方文档

此方法创建 GDI 位图对象的图柄。

官方示例方法

1234567891011[System.Runtime.InteropServices.DllImport("gdi32.dll")]public static extern bool DeleteObject(IntPtr hObject);private void DemonstrateGetHbitmap(){ Bitmap bm = new Bitmap("Picture.jpg"); IntPtr hBitmap = bm.GetHbitmap(); // Do something with hBitmap. DeleteObject(hBitmap);} Image和ImageSource

从源码中可以看出

我们加载图片的组件Image设置的是ImageSource

1234567namespace System.Windows.Controls{ public class Image : FrameworkElement, IUriContext, IProvidePropertyFallback { public ImageSource Source { get; set; } }} ImageSource/BitmapSource/BitmapImage

继承关系

ImageSource=>BitmapSource=>BitmapImage

ImageSource

ImageSource表示具有宽度、高度和 ImageMetadata 的对象类型,这是一个抽象类。

BitmapSource

BitmapSource 也是一个抽象类。

BitmapSource 是 Windows Presentation Foundation (WPF) 图像处理管道的基本构建基块,从概念上讲,以特定大小和分辨率指定一组固定的像素。 BitmapSource 可以是解码器提供的图像文件中的单个帧,也可以是操作自身 BitmapSource 的转换的结果。 BitmapSource 不用于表示多帧图像或动画。

BitmapImage

BitmapImage从图像文件创建位图,并将其用作 Image 控件的源

12345678910111213// Create the image element.Image simpleImage = new Image(); simpleImage.Width = 200;simpleImage.Margin = new Thickness(5);// Create source.BitmapImage bi = new BitmapImage();// BitmapImage.UriSource must be in a BeginInit/EndInit block.bi.BeginInit();bi.UriSource = new Uri(@"/sampleImages/cherries_larger.jpg",UriKind.RelativeOrAbsolute);bi.EndInit();// Set the image source.simpleImage.Source = bi; RenderTargetBitmap

主要作用为保存页面组件为图片

其中myview为其它组件的名称

XAML

123456789

C#

1234RenderTargetBitmap bitmap = new RenderTargetBitmap();await bitmap.RenderAsync(myview);// 把图片展现出来img.Source = bitmap; RenderTargetBitmap和BitmapImage

RenderTargetBitmap和BitmapImage都是用于表示位图的类,但是两者有不同的用途和区别:

目标渲染位图(RenderTargetBitmap)是一个用于创建位图的WPF元素,它可以在屏幕上渲染一个WPF视觉对象,并将其转换为位图。它通常用于将WPF视觉元素转换为图片,如截图等操作。 位图图像(BitmapImage)是一个预定义的位图图像,它可以从本地文件或网络中加载。它通常用于显示图像,如在Image控件中显示图片。

因此,如果需要从WPF视觉元素创建位图,则使用RenderTargetBitmap;如果需要从本地或网络中加载位图,则使用BitmapImage。

图片转换Bitmap BitmapImage12345678910111213141516171819202122232425262728293031323334/// /// Bitmap --> BitmapImage/// /// /// public static BitmapImage BitmapToBitmapImage(Bitmap bitmap){ using (MemoryStream stream = new MemoryStream()) { bitmap.Save(stream, ImageFormat.Png); stream.Position = 0; BitmapImage bitmapImage = new BitmapImage(); bitmapImage.BeginInit(); bitmapImage.CacheOption = BitmapCacheOption.OnLoad; bitmapImage.StreamSource = stream; bitmapImage.EndInit(); bitmapImage.Freeze(); return bitmapImage; }}// BitmapImage --> Bitmappublic static Bitmap BitmapImageToBitmap(BitmapImage bitmapImage){ using (MemoryStream outStream = new MemoryStream()) { BitmapEncoder enc = new BmpBitmapEncoder(); enc.Frames.Add(BitmapFrame.Create(bitmapImage)); enc.Save(outStream); Bitmap bitmap = new Bitmap(outStream); return new Bitmap(bitmap); }} ImagePath => BitmapImage12345678910111213141516public static BitmapImage GetImage(string imagePath){ BitmapImage bi = new BitmapImage(); if (File.Exists(imagePath)) { bi.BeginInit(); bi.CacheOption = BitmapCacheOption.OnLoad; using (Stream ms = new MemoryStream(File.ReadAllBytes(imagePath))) { bi.StreamSource = ms; bi.EndInit(); bi.Freeze(); } } return bi;} Bitmap ImageSource12345678910111213141516171819202122[DllImport("gdi32.dll", SetLastError = true)]private static extern bool DeleteObject(IntPtr hObject);/// /// 从bitmap转换成ImageSource/// /// /// public static ImageSource ChangeBitmapToImageSource(Bitmap bitmap){IntPtr hBitmap = bitmap.GetHbitmap();ImageSource wpfBitmap = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap( hBitmap, IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());if (!DeleteObject(hBitmap))//记得要进行内存释放。否则会有内存不足的报错。{ throw new System.ComponentModel.Win32Exception();}return wpfBitmap;} Bitmap => BitmapSource1234567891011121314151617181920212223/// /// 从Bitmap转换成BitmapSource/// /// /// public static BitmapSource ChangeBitmapToBitmapSource(Bitmap bmp){ BitmapSource returnSource; try { returnSource = Imaging.CreateBitmapSourceFromHBitmap( bmp.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions() ); } catch { returnSource = null; } return returnSource;} Icon => ImageSource1234567891011/// /// 从Icon到ImageSource的转换/// public ImageSource ChangeIconToImageSource(Icon icon){ImageSource imageSource = System.Windows.Interop.Imaging.CreateBitmapSourceFromHIcon( icon.Handle, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());return imageSource;} RenderTargetBitmap => BitmapImage123456789101112131415161718// RenderTargetBitmap --> BitmapImagepublic static BitmapImage ConvertRenderTargetBitmapToBitmapImage(RenderTargetBitmap wbm){ BitmapImage bmp = new BitmapImage(); using (MemoryStream stream = new MemoryStream()) { BmpBitmapEncoder encoder = new BmpBitmapEncoder(); encoder.Frames.Add(BitmapFrame.Create(wbm)); encoder.Save(stream); bmp.BeginInit(); bmp.CacheOption = BitmapCacheOption.OnLoad; bmp.CreateOptions = BitmapCreateOptions.PreservePixelFormat; bmp.StreamSource = new MemoryStream(stream.ToArray()); //stream; bmp.EndInit(); bmp.Freeze(); } return bmp;} BitmapImage byte[]123456789101112131415161718192021222324252627282930313233343536373839// BitmapImage --> byte[]public static byte[] BitmapImageToByteArray(BitmapImage bmp){ byte[] bytearray = null; try { Stream smarket = bmp.StreamSource; ; if (smarket != null && smarket.Length > 0) { //设置当前位置 smarket.Position = 0; using (BinaryReader br = new BinaryReader(smarket)) { bytearray = br.ReadBytes((int)smarket.Length); } } } catch (Exception ex) { Console.WriteLine(ex); } return bytearray;}// byte[] --> BitmapImagepublic static BitmapImage ByteArrayToBitmapImage(byte[] array){ using (var ms = new System.IO.MemoryStream(array)) { var image = new BitmapImage(); image.BeginInit(); image.CacheOption = BitmapCacheOption.OnLoad; // here image.StreamSource = ms; image.EndInit(); image.Freeze(); return image; }} byte[] Bitmap123456789101112131415161718192021222324252627282930313233public static System.Drawing.Bitmap ConvertByteArrayToBitmap(byte[] bytes){ System.Drawing.Bitmap img = null; try { if (bytes != null && bytes.Length != 0) { MemoryStream ms = new MemoryStream(bytes); img = new System.Drawing.Bitmap(ms); } } catch (Exception ex) { Console.WriteLine(ex); } return img;}/// /// Bitmap转byte[]/// /// /// public static byte[] BitmapToBytes(Bitmap bitmap){ MemoryStream stream = new MemoryStream(); bitmap.Save(stream, ImageFormat.Jpeg); byte[] data = new byte[stream.Length]; stream.Seek(0, SeekOrigin.Begin); stream.Read(data, 0, Convert.ToInt32(stream.Length)); stream.Dispose(); return data;} 图片保存Bitmap保存1Bitmap img = ZScreenUtil.CaptureScreen();

保存

123var filePath = "E:\123.jpg";img.Save(filePath, System.Drawing.Imaging.ImageFormat.Jpeg);img.Dispose();

保存设置压缩质量

1234567891011121314151617181920public static string CaptureScreenSave(string filePath){ ImageCodecInfo myImageCodecInfo = GetEncoderInfo("image/jpeg"); EncoderParameters myEncoderParameters = new EncoderParameters(1); EncoderParameter myEncoderParameter = new EncoderParameter(Encoder.Quality, 60L); myEncoderParameters.Param[0] = myEncoderParameter; img.Save(filePath, myImageCodecInfo, myEncoderParameters); img.Dispose();}private static ImageCodecInfo GetEncoderInfo(String mimeType){ ImageCodecInfo[] encoders = ImageCodecInfo.GetImageEncoders(); for (int j = 0; j < encoders.Length; ++j) { if (encoders[j].MimeType == mimeType) return encoders[j]; } return null;} BitmapSource保存

Bitmap=>BitmapSource

BitmapSource=>写文件

123456789101112131415161718192021222324252627282930313233343536373839float factor = Graphics.FromHwnd(IntPtr.Zero).DpiX / 96;int imageW = Convert.ToInt32(pwidth * factor);int imageH = Convert.ToInt32(pHeight * factor);using ( Bitmap image = new Bitmap( imageW, imageH, System.Drawing.Imaging.PixelFormat.Format32bppArgb )){ using (Graphics g = Graphics.FromImage(image)) { g.CopyFromScreen( 0, 0, 0, 0, new System.Drawing.Size(imageW, imageH), CopyPixelOperation.SourceCopy ); IntPtr intPtr = image.GetHbitmap(); BitmapSource bitmapSource = Imaging.CreateBitmapSourceFromHBitmap( intPtr, IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions() ); //BitmapSource=>写文件 string filepath = getImagePath(); using (FileStream file = new FileStream(filepath, FileMode.Create, FileAccess.Write)) { JpegBitmapEncoder encoder = new JpegBitmapEncoder(); encoder.QualityLevel = 90; encoder.Frames.Add(BitmapFrame.Create(bitmapSource)); encoder.Save(file); } ImageHelper.DeleteObject(intPtr); }}

注意

上面的这种保存图片的方式是没有意义的,只是为了展示怎么把BitmapSource保存为图片文件。

BitmapSource=>写文件

123456789101112131415161718192021222324252627282930313233/// /// 保存图片到文件/// /// 图片数据/// 保存路径private void SaveImageToFile(BitmapSource image, string filePath){ BitmapEncoder encoder = GetBitmapEncoder(filePath); encoder.Frames.Add(BitmapFrame.Create(image)); using (var stream = new FileStream(filePath, FileMode.Create)) { encoder.Save(stream); }}/// /// 根据文件扩展名获取图片编码器/// /// 文件路径/// 图片编码器private BitmapEncoder GetBitmapEncoder(string filePath){ var extName = Path.GetExtension(filePath).ToLower(); if (extName.Equals(".png")) { return new PngBitmapEncoder(); } else { return new JpegBitmapEncoder(); }} 组件转图片

RenderTargetBitmap=>Bitmap

示例:获取组件的Bitmap

12345678910111213141516171819202122232425262728293031323334353637383940414243444546public static Bitmap SaveUi2Bitmap(FrameworkElement element){ // 获取FrameworkElement的大小 int width = (int)element.ActualWidth; int height = (int)element.ActualHeight; // 创建RenderTargetBitmap对象,并将FrameworkElement渲染到其中 RenderTargetBitmap bitmap = new RenderTargetBitmap ( width, height, 96, 96, PixelFormats.Pbgra32 ); bitmap.Render(element); // 创建Bitmap对象,并将RenderTargetBitmap的像素复制到其中 Bitmap bmp = new Bitmap ( width, height, System.Drawing.Imaging.PixelFormat.Format32bppPArgb ); BitmapData bmpData = bmp.LockBits ( new Rectangle ( 0, 0, bmp.Width, bmp.Height ), ImageLockMode.WriteOnly, bmp.PixelFormat ); bitmap.CopyPixels ( Int32Rect.Empty, bmpData.Scan0, bmpData.Height * bmpData.Stride, bmpData.Stride ); bmp.UnlockBits(bmpData); return bmp;} 组件转文件1234567891011121314151617181920public static void SaveUI2JpegFile(FrameworkElement frameworkElement, int width, int height, string filepath){ using (FileStream outStream = new FileStream(filepath, FileMode.Create, FileAccess.Write)) { RenderTargetBitmap bmp = new RenderTargetBitmap( (int)frameworkElement.ActualWidth, (int)frameworkElement.ActualHeight, 96, 96, PixelFormats.Default ); bmp.Render(frameworkElement); JpegBitmapEncoder encoder = new JpegBitmapEncoder { QualityLevel = 80 }; encoder.Frames.Add(BitmapFrame.Create(bmp)); encoder.Save(outStream); }} 组件转BitmapImage123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869public static Bitmap SaveUi2Bitmap(FrameworkElement element){ // 获取FrameworkElement的大小 int width = (int)element.ActualWidth; int height = (int)element.ActualHeight; // 创建RenderTargetBitmap对象,并将FrameworkElement渲染到其中 RenderTargetBitmap bitmap = new RenderTargetBitmap ( width, height, 96, 96, PixelFormats.Pbgra32 ); bitmap.Render(element); // 创建Bitmap对象,并将RenderTargetBitmap的像素复制到其中 Bitmap bmp = new Bitmap ( width, height, System.Drawing.Imaging.PixelFormat.Format32bppPArgb ); BitmapData bmpData = bmp.LockBits ( new Rectangle ( 0, 0, bmp.Width, bmp.Height ), ImageLockMode.WriteOnly, bmp.PixelFormat ); bitmap.CopyPixels ( Int32Rect.Empty, bmpData.Scan0, bmpData.Height * bmpData.Stride, bmpData.Stride ); bmp.UnlockBits(bmpData); return bmp;}// Bitmap --> BitmapImagepublic static BitmapImage BitmapToBitmapImage(Bitmap bitmap){ using (MemoryStream stream = new MemoryStream()) { bitmap.Save(stream, ImageFormat.Png); stream.Position = 0; BitmapImage result = new BitmapImage(); result.BeginInit(); result.CacheOption = BitmapCacheOption.OnLoad; result.StreamSource = stream; result.EndInit(); result.Freeze(); return result; }}public static BitmapImage SaveUi2BitmapImage(FrameworkElement frameworkElement){ using var bitmap = SaveUi2Bitmap(frameworkElement); return BitmapToBitmapImage(bitmap);} 截屏保存

获取图片

1234567891011121314151617181920212223242526272829using System;using System.Drawing;using System.Windows;using System.Windows.Forms;using System.Windows.Interop;using System.Windows.Media.Imaging;using Size = System.Drawing.Size;namespace JieTu.Utils{ class ZScreenUtil { public static void ScreenShot(string savePath) { using (Bitmap bmp = new Bitmap( Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb )) { using (Graphics g = Graphics.FromImage(bmp)) { g.CopyFromScreen(0, 0, 0, 0, bmp.Size); bmp.Save(savePath, ImageFormat.Jpeg); } } } }}

保存图片

12var filePath = "E:\123.jpg";ZScreenUtil.ScreenShot(filePath); 图片压缩123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277using System;using System.Drawing;using System.Drawing.Imaging;using System.IO;namespace card_scanner.util{ public class ZImageUtil { /// /// 压缩图片 /// /// /// /// 压缩后的大小单位kb public static void ZipImage(string sourcePath, string targetPath, long targetLen) { Image img = Image.FromFile(sourcePath); using (Image img2 = ZipImage(img, GetImageFormat(targetPath), targetLen)) { //解除之前文件占用 img.Dispose(); img2.Save(targetPath); } } /// /// 图片压缩 /// /// /// /// 压缩后的大小单位kb public static void ZipImage(Stream stream, string targetPath, long targetLen) { Image img = Image.FromStream(stream); using (Image img2 = ZipImage(img, GetImageFormat(targetPath), targetLen)) { img.Dispose(); img2.Save(targetPath); } } /// /// 压缩图片 /// /// 图片 /// 图片格式 /// 压缩后大小(kb) /// 原始大小 /// 压缩后的图片 public static Image ZipImage(Image img, ImageFormat format, long targetLen, long srcLen = 0) { //设置大小偏差幅度 10kb const long nearlyLen = 10240; //内存流 如果参数中原图大小没有传递 则使用内存流读取 var ms = new MemoryStream(); if (0 == srcLen) { img.Save(ms, format); srcLen = ms.Length; } //单位 由Kb转为byte 若目标大小高于原图大小,则满足条件退出 targetLen *= 1024; if (targetLen > srcLen) { ms.SetLength(0); ms.Position = 0; img.Save(ms, format); img = Image.FromStream(ms); return img; } //获取目标大小最低值 var exitLen = targetLen - nearlyLen; //初始化质量压缩参数 图像 内存流等 var quality = (long)Math.Floor(100.00 * targetLen / srcLen); var parms = new EncoderParameters(1); //获取编码器信息 ImageCodecInfo formatInfo = null; var encoders = ImageCodecInfo.GetImageEncoders(); foreach (ImageCodecInfo icf in encoders) { if (icf.FormatID == format.Guid) { formatInfo = icf; break; } } //使用二分法进行查找 最接近的质量参数 long startQuality = quality; long endQuality = 100; quality = (startQuality + endQuality) / 2; while (true) { //设置质量 parms.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, quality); //清空内存流 然后保存图片 ms.SetLength(0); ms.Position = 0; img.Save(ms, formatInfo, parms); //若压缩后大小低于目标大小,则满足条件退出 if (ms.Length >= exitLen && ms.Length = endQuality) //区间相等无需再次计算 { break; } else if (ms.Length < exitLen) //压缩过小,起始质量右移 { startQuality = quality; } else //压缩过大 终止质量左移 { endQuality = quality; } //重新设置质量参数 如果计算出来的质量没有发生变化,则终止查找。这样是为了避免重复计算情况{start:16,end:18} 和 {start:16,endQuality:17} var newQuality = (startQuality + endQuality) / 2; if (newQuality == quality) { break; } quality = newQuality; } img = Image.FromStream(ms); return img; } /// /// 根据尺寸按比例压缩 /// /// 图片 /// 目标的宽 /// 目标的高 /// public static Image ZoomImage(Image bitmap, int destWidth, int destHeight) { try { System.Drawing.Image sourImage = bitmap; int width = 0, height = 0; //按比例缩放 int sourWidth = sourImage.Width; int sourHeight = sourImage.Height; if (sourHeight > destHeight || sourWidth > destWidth) { if ((sourWidth * destHeight) > (sourHeight * destWidth)) { width = destWidth; height = (destWidth * sourHeight) / sourWidth; } else { height = destHeight; width = (sourWidth * destHeight) / sourHeight; } } else { width = sourWidth; height = sourHeight; } Bitmap destBitmap = new Bitmap(destWidth, destHeight); Graphics g = Graphics.FromImage(destBitmap); g.Clear(Color.Transparent); //设置画布的描绘质量 g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality; g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; g.DrawImage(sourImage, new Rectangle((destWidth - width) / 2, (destHeight - height) / 2, width, height), 0, 0, sourImage.Width, sourImage.Height, GraphicsUnit.Pixel); g.Dispose(); //设置压缩质量 System.Drawing.Imaging.EncoderParameters encoderParams = new System.Drawing.Imaging.EncoderParameters(); long[] quality = new long[1]; quality[0] = 100; System.Drawing.Imaging.EncoderParameter encoderParam = new System.Drawing.Imaging.EncoderParameter(System.Drawing.Imaging.Encoder.Quality, quality); encoderParams.Param[0] = encoderParam; sourImage.Dispose(); return destBitmap; } catch (Exception) { return bitmap; } } /// ///获取图片格式 /// /// 图片 /// 默认返回JPEG public static ImageFormat GetImageFormat(Image img) { if (img.RawFormat.Equals(ImageFormat.Jpeg)) { return ImageFormat.Jpeg; } if (img.RawFormat.Equals(ImageFormat.Gif)) { return ImageFormat.Gif; } if (img.RawFormat.Equals(ImageFormat.Png)) { return ImageFormat.Png; } if (img.RawFormat.Equals(ImageFormat.Bmp)) { return ImageFormat.Bmp; } return ImageFormat.Jpeg;//根据实际情况选择返回指定格式还是null } /// /// 根据目标路径获取图片格式 /// /// /// public static ImageFormat GetImageFormat(string imgPath) { string imagePathNew = imgPath.ToLower(); if (imagePathNew.EndsWith("gif")) { return ImageFormat.Gif; } else if (imagePathNew.EndsWith("png")) { return ImageFormat.Png; } else if (imagePathNew.EndsWith("bmp")) { return ImageFormat.Bmp; } else { return ImageFormat.Jpeg; } } /// /// 获取图片的新路径 /// /// /// public static string GetImagePathNew(string sourcePath) { string targetPath = ""; Console.WriteLine("sourcePath: " + sourcePath); try { FileInfo fi = new FileInfo(sourcePath); var di = fi.Directory; if (!di.Exists) { di.Create(); } string filename = fi.Name; string filenameNoSuff = filename.Substring(0, filename.LastIndexOf(".")); string suff = filename.Substring(filename.LastIndexOf(".")); targetPath = Path.Combine(di.FullName, filenameNoSuff + "_new" + suff); } catch (Exception) { } return targetPath; } }} 图片加载加载本地12BitmapImage bImage = new BitmapImage(new Uri("c:\\image.bmp"));image.Source = bImage; 加载本地图片并缩放12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152private void SetSource(System.Windows.Controls.Image image, string fileName){ System.Drawing.Image sourceImage = System.Drawing.Image.FromFile(fileName); int imageWidth = 0, imageHeight = 0; InitializeImageSize(sourceImage, image, out imageWidth, out imageHeight); Bitmap sourceBmp = new Bitmap(sourceImage, imageWidth, imageHeight); IntPtr hBitmap = sourceBmp.GetHbitmap(); BitmapSource bitmapSource = Imaging.CreateBitmapSourceFromHBitmap( hBitmap, IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions() ); bitmapSource.Freeze(); WriteableBitmap writeableBmp = new WriteableBitmap(bitmapSource); sourceImage.Dispose(); sourceBmp.Dispose(); image.Source = writeableBmp;}/// /// 设置图片大小/// /// /// /// /// private static void InitializeImageSize( System.Drawing.Image sourceImage, System.Windows.Controls.Image image, out int imageWidth, out int imageHeight){ int width = sourceImage.Width; int height = sourceImage.Height; float aspect = (float)width / (float)height; if (image.Height != double.NaN) { imageHeight = Convert.ToInt32(image.Height); imageWidth = Convert.ToInt32(aspect * imageHeight); } else if (image.Width != double.NaN) { imageWidth = Convert.ToInt32(image.Width); imageHeight = Convert.ToInt32(image.Width / aspect); } else { imageHeight = 100; imageWidth = Convert.ToInt32(aspect * imageHeight); }}

调用方式

1SetSource(this.imageCur, “C:\1.png”); JPEG转WEBP

添加依赖

1Install-Package Imazen.WebP -Version 10.0.1

下载DLL

https://www.dll-files.com/libwebp.dll.html

注意32位和64位,我这里用的32位

项目根目录添加DLL文件夹,把libwebp.dll放进去

属性=>生成事件=>生成前事件命令行添加

1xcopy /Y /d $(ProjectDir)\DLL\libwebp.dll $(TargetDir)

转为WEBP

1234567891011if (targetFilePath.EndsWith("webp")){ using (Bitmap bitmap = new Bitmap(sourceFilePath)) { using (var saveImageStream = System.IO.File.Open(targetFilePath, FileMode.Create)) { var encoder = new SimpleEncoder(); encoder.Encode(bitmap, saveImageStream, 80); } }} 封装的工具类123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335using Imazen.WebP;using System;using System.Drawing;using System.Drawing.Imaging;using System.IO;using System.Windows;using System.Windows.Forms;using System.Windows.Media;using System.Windows.Media.Imaging;namespace SchoolClient.Utils{ internal class ZScreenUtil { /// /// 屏幕截图 /// /// /// public static void ScreenShot(string savePath) { using (Bitmap bmp = new Bitmap( Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb )) { using (Graphics g = Graphics.FromImage(bmp)) { g.CopyFromScreen(0, 0, 0, 0, bmp.Size); bmp.Save(savePath, ImageFormat.Jpeg); } } } /// /// 截图并缩放 /// /// /// /// /// public static void CaptureScreenSave(string targetPath) { int lastindex = targetPath.LastIndexOf(Path.DirectorySeparatorChar); if (lastindex < targetPath.Length) { string fileFolder = targetPath.Substring(0, lastindex); string filename = targetPath.Substring(lastindex + 1); string filenameNoSuff = filename.Substring(0, filename.LastIndexOf(".")); string tempFilePath = fileFolder + Path.DirectorySeparatorChar + "z_" + filenameNoSuff + ".jpg"; //截屏 ScreenShot(tempFilePath); int Width = Screen.PrimaryScreen.Bounds.Width; int Height = Screen.PrimaryScreen.Bounds.Height; int maxHeight = 1080; int quality = 80; if (Height > maxHeight || targetPath.EndsWith("webp")) { // 图片需要缩放或者需要转WEBP float ratio = 1.0f * Height / maxHeight; Width = (int)(1.0d * Width / ratio); Height = (int)(1.0d * Height / ratio); Bitmap bitmp = PicScale(tempFilePath, Width, Height); try { if (targetPath.EndsWith("webp")) { Pic2Webp(bitmp, targetPath, quality); } else { PicCompress(bitmp, targetPath, quality); } } catch (Exception) { } bitmp.Dispose(); //删除原图 PicDel(tempFilePath); } else { // 图片不用转换为WEBP,并且文件大小未改变,直接重命名 try { FileInfo fi = new FileInfo(tempFilePath); if (fi.Exists) { fi.MoveTo(targetPath); } } catch (Exception) { } } } } /// 图片缩放 /// /// 原图片 /// /// /// 宽度 /// /// /// 高度 /// /// /// public static Bitmap PicScale(string sourcePath, int targetWidth, int targetHeight) { Bitmap bitmp = null; using (Image sourceImage = Image.FromFile(sourcePath)) { //用指定的大小和格式初始化Bitmap类的新实例 using (Bitmap bitmap = new Bitmap(targetWidth, targetHeight, System.Drawing.Imaging.PixelFormat.Format32bppArgb)) { //从指定的Image对象创建新Graphics对象 using (Graphics graphics = Graphics.FromImage(bitmap)) { graphics.DrawImage(sourceImage, new Rectangle(0, 0, targetWidth, targetHeight)); } bitmp = new Bitmap(bitmap); } } return bitmp; } /// /// 图片删除 /// /// /// public static void PicDel(string sourcePath) { try { // 防止文件占用导致的异常 FileInfo di = new FileInfo(sourcePath); if (di.Exists) { di.Delete(); } } catch (Exception e) { Console.WriteLine(e.Message); } } /// /// 图片压缩(降低质量以减小文件的大小) /// /// /// 传入的Bitmap对象 /// /// /// 压缩后的文件路径 /// /// /// 压缩等级,0到100,0 最差质量,100 最佳 /// public static void PicCompress(Bitmap bitmap, string targetPath, long quality) { using (Stream destStream = new FileStream(targetPath, FileMode.Create)) { ImageCodecInfo myImageCodecInfo; EncoderParameters myEncoderParameters; //获取表示jpeg编解码器的imagecodecinfo对象 myImageCodecInfo = GetEncoderInfo("image/jpeg"); myEncoderParameters = new EncoderParameters(1); myEncoderParameters.Param[0] = new EncoderParameter(Encoder.Quality, quality); ; bitmap.Save(destStream, myImageCodecInfo, myEncoderParameters); bitmap.Dispose(); GC.Collect(); } } /// /// 图片转WEBP /// /// /// /// /// /// /// public static void Pic2Webp(Bitmap bitmp, string targetPath, long quality) { using (var saveImageStream = File.Open(targetPath, FileMode.Create)) { var encoder = new SimpleEncoder(); encoder.Encode(bitmp, saveImageStream, quality); bitmp.Dispose(); } } /// /// 获取解码器 /// /// /// /// /// private static ImageCodecInfo GetEncoderInfo(string mimeType) { int j; ImageCodecInfo[] encoders; encoders = ImageCodecInfo.GetImageEncoders(); for (j = 0; j < encoders.Length; ++j) { if (encoders[j].MimeType == mimeType) { return encoders[j]; } } return null; } /// /// 保存界面为图片 /// /// /// /// /// public static void SaveUI2JpegFile(FrameworkElement frameworkElement, string filepath) { using (FileStream outStream = new FileStream(filepath, FileMode.Create, FileAccess.Write)) { RenderTargetBitmap bmp = new RenderTargetBitmap( (int)frameworkElement.ActualWidth, (int)frameworkElement.ActualHeight, 96, 96, PixelFormats.Default ); bmp.Render(frameworkElement); JpegBitmapEncoder encoder = new JpegBitmapEncoder { QualityLevel = 80 }; encoder.Frames.Add(BitmapFrame.Create(bmp)); encoder.Save(outStream); } } /// /// 根据路径获取BitmapImage /// /// /// /// /// public static BitmapImage GetImage(string imagePath) { BitmapImage bi = new BitmapImage(); if (File.Exists(imagePath)) { bi.BeginInit(); bi.CacheOption = BitmapCacheOption.OnLoad; using (Stream ms = new MemoryStream(File.ReadAllBytes(imagePath))) { bi.StreamSource = ms; bi.EndInit(); bi.Freeze(); } } return bi; } /// /// 截取图片指定部分 /// /// /// 图片路径 /// /// /// 容器内截取的宽度 /// /// /// 容器内截取的高度 /// /// /// 容器内开始截取处的坐标X值 /// /// /// 容器内开始截取处的坐标Y值 /// /// /// 图片容器宽度 /// /// /// 图片容器高度 /// public static Bitmap PicCrop(string imgPath, int cutWidth, int cutHeight, int cutX, int cutY, int containerW, int containerH) { Image originalImg = Image.FromFile(imgPath); float ratioW = 1.0f * originalImg.Width / containerW; float ratioH = 1.0f * originalImg.Height / containerH; //原图位置(默认从原图中截取的图片大小等于目标图片的大小) Rectangle origRect = new Rectangle( new System.Drawing.Point((int)(ratioW * cutX), (int)(ratioH * cutY)), new System.Drawing.Size((int)(ratioW * cutWidth), (int)(ratioH * cutHeight)) ); int targetW = (int)(ratioW * cutWidth); int targetH = (int)(ratioH * cutHeight); //目标位置 Rectangle destRect = new Rectangle( new System.Drawing.Point(0, 0), new System.Drawing.Size(targetW, targetH) ); Bitmap partImg = new Bitmap(targetW, targetH); Graphics graphics = Graphics.FromImage(partImg); graphics.DrawImage(originalImg, destRect, origRect, GraphicsUnit.Pixel); graphics.Dispose(); return partImg; } }} 相关概念GDI和GDI+

GDI在全称是Graphics Device Interface,即图形设备接口。是图形显示与实际物理设备之间的桥梁。

GDI接口是基于函数,虽然使程序员省力不少,但是编程方式依然显得麻烦。

例如显示一张位图,我们需要进行“创建位图,读取位图文件信息,启用场景设备,调色板变化“等一系列操作。然而有了GDI+,繁琐的步骤再次被简化。

顾名思义,GDI+就是GDI的增强版,它是微软在Windows 2000以后操作系统中提供的新接口。

GDI+主要提供以下三种功能:

二维矢量图形:GDI+提供了存储图形基元自身信息的类(或结构体)、存储图形基元绘制方式信息的类以及实际进行绘制的类;

图像处理:大多数图片都难以划定为直线和曲线的集合,无法使用二维矢量图形方式进行处理。因此,GDI+为我们提供了Bitmap、Image等类,它们可用于显示、操作和保存BMP、JPG、GIF等图像格式。

文字显示:GDI+支持使用各种字体、字号和样式来显示文本。

相比于GDI,GDI+是基于C++类的对象化的应用程序接口,因此用起来更为简单。

GDI的核心是设备上下文,GDI函数都依赖于设备上下文句柄,其编程方式是基于句柄的;

GDI+无需时刻依赖于句柄或设备上下文,用户只需创建一个Graphics 对象,就可以用面向对象的方式调用其成员函数进行图形操作,编程方式是基于对象的。

GDI +提供了Image、Bitmap 和Metafile 类,方便用户进行图像格式的加载、操作和保存。

GDI+支持的图像格式有BMP、GIF、JPEG、EXIF、PNG、TIFF、ICON、WMF、 EMF等,几乎涵盖了所有的常用图像格式。

GDI+和GDI区别以及一些新特征

GDI+与GDI

GDI是硬件加速的,而GDI+不是的,而且GDI+2.0比GDI+更快。

GDI是有状态的,而GDI+是无状态的。

GDI绘图要使用设备环境和句柄;而GDI+全部交由Graphics类管理(不创建句柄)。

GDI绘图时可以使用SelectObject频繁切换图形对象,而GDI+的图形对象是独立的。

GDI中存在一个当前位置(全局区),目的是提高绘图性能;而GDI+取消了它,以避免绘图时不确定这个当前位置而带来非预期的错误。

GDI总是将画笔和画刷绑定在一起,即使不需要填充一个区域也必须指定一个画刷;而GDI+则可以使用不同的函数分开使用画笔和画刷。

GDI+新特性

改进了颜色管理。GDI+不仅提供了更多可供选择使用的颜色,使其支持Alpha通道合成运算,而且还保持了与其他颜色的兼容性。

绘图支持反锯齿。通过设置GDI+对象的相关属性,GDI+可以与相关的显示驱动程序搭配完成图形绘制时的反锯齿功能,使得绘制的图形更加平滑,美观,而整个过程是由GDI+对象自动计算完成的。

提供渐变画刷。GDI+拓展了GDI的功能,提供线性渐变和路径渐变画刷来填充图形、路径和区域,甚至也可用来绘制直线、曲线等。

独立的路径对象。GDI+使用Graphics对象来进行绘图操作,并将路径操作从Graphics对象分离出来,提供一个Graphics类供用户使用,用户不必担心对象会受到Graphics对象操作的影响,从而可以使用同一个操作对象进行多次的路径绘制操作。

样条曲线。GDI+封装了绘制基数样条曲线和贝塞尔样条曲线的方法。

变形和矩阵运算。GDI+提供了功能强大的Matrix类来实现矩阵的旋转,错切、平移、比例等变换操作,以便产生复杂的新图形。

多图片格式的支持。GDI+该进了图形处理能力,通过GDI+,用户能够访问多种格式的图片文件,转换文件格式等,还能进行图像重新着色、色彩修正、消除走样等图像处理。

注意

GDI+对象比如Bitmap,是不会创建句柄的,GetHbitmap方法不是获取句柄而是创建句柄。不会受GDI句柄数量的限制。只有需要创建句柄进行其他操作时才要调用GetHbitmap创建句柄。

托管资源和非托管资源概念

托管资源指的是.NET可以自动进行回收的资源,主要是指托管堆上分配的内存资源。托管资源的回收工作是不需要人工干预的,有.NET运行库在合适调用垃圾回收器进行回收。

非托管资源指的是.NET不知道如何回收的资源,最常见的一类非托管资源是包装操作系统资源的对象,

例如文件,窗口,网络连接,数据库连接,画刷,图标等。

这类资源,垃圾回收器在清理的时候会调用Object.Finalize()方法。默认情况下,方法是空的,对于非托管对象,需要在此方法中编写回收非托管资源的代码,以便垃圾回收器正确回收资源。

常见的非托管资源

ApplicationContext, Brush, Component, ComponentDesigner, Container, Context, Cursor, FileStream, Font, Icon, Image, Matrix, Object, OdbcDataReader, OleDBDataReader, Pen, Regex, Socket, StreamWriter, Timer, Tooltip, 文件句柄, GDI资源, 数据库连接等等资源。

非托管资源的释放

托管资源由垃圾回收器控制如何释放,不需要程序员过多的考虑(当然也程序员也可以自己释放)。

非托管资源需要自己编写代码来释放。

在一个包含非托管资源的类中,关于资源释放的标准做法是:

继承IDisposable接口;

实现Dispose()方法,在其中释放托管资源和非托管资源,并将对象本身从垃圾回收器中移除(垃圾回收器不在回收此资源);

实现类析构函数,在其中释放非托管资源。

那么编写好的释放非托管资源的代码(释非代码)由谁来调用呢。

有两种实现方式:

将释非代码放到构造函数析构函数中,由系统自动调用,系统会在资源对象不再使用了,会在某个时间调用构造函数析构函数来释放非托管资源。构造函数析构函数的目的就是用来释放或清理非托管资源的。但它有一个问题是调用的时间是系统说了算,不能在程序中自己想要调用时调用析构函数,这是C#规定的。那么就产生了第二种方式。

将释非代码放到另外一个函数中,当自己想调用时就调用。将释非代码放在一个方法中共用。

代码如下

1234567891011121314151617181920212223242526272829MyClass:IDisposable{ private bool disposed = false; ~MyClass() { Dispose(false); } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } private void Dispose(bool disposing) { if(disposed == false) { if(disposing == true) { // 释托管代码 // ...... } // 释非代码 // ...... } disposed = true; }}

标准清理模式中多了一句GC.SuppressFinalize(this);【该方法通知CLR不要调用该方法的析构函数,因为它已经被清理了。】如果没有这句代码,我认为不影响程序的正确性,不会发生安全问题,他只是告诉系统不要再调用构造函数了。那么为什么要加上这句代码呢?如果在调用了Dispose()之后再调用析构函数只是多此一举,所以告诉系统不要再调用了。这一点应该和性能有关系。【如果不需要构造函数就不要执行构造函数,他们会带来性能上的开销】。

释放非托管资源可参看:

https://www.cnblogs.com/niaomingjian/p/3516083.html

using

定义一个范围,在范围结束时处理对象。只要离开了这个代码段就自动调用这个类实例的Dispose。

1234using (Class1 cls1 = new Class1(), cls2 = new Class1()){ // the code using cls1, cls2} // call the Dispose on cls1 and cls2 图片与Base64互转1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071using System;using System.Drawing;using System.IO;namespace Z.Common{ public class ZBase64Util { /// /// base64 转 Image /// /// public static void Base64ToImage(string base64, string filePath) { base64 = base64 .Replace("data:image/png;base64,", "") .Replace("data:image/jgp;base64,", "") .Replace("data:image/jpg;base64,", "") .Replace("data:image/jpeg;base64,", "");//将base64头部信息替换 byte[] bytes = Convert.FromBase64String(base64); MemoryStream memStream = new MemoryStream(bytes); Image mImage = Image.FromStream(memStream); Bitmap bp = new Bitmap(mImage); bp.Save(filePath, System.Drawing.Imaging.ImageFormat.Jpeg); } /// /// Image 转成 base64 /// /// public static string ImageToBase64(string filePath) { string prefix = "data:image/jpeg;base64,"; try { Bitmap bmp = new Bitmap(filePath); MemoryStream ms = new MemoryStream(); bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg); byte[] arr = new byte[ms.Length]; ms.Position = 0; ms.Read(arr, 0, (int)ms.Length); ms.Close(); return prefix + Convert.ToBase64String(arr); } catch (Exception) { return null; } } /// /// 图片转Base64 /// /// /// public static string ImageToBase64(Bitmap bmp) { string prefix = "data:image/jpeg;base64,"; try { MemoryStream ms = new MemoryStream(); bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg); byte[] arr = new byte[ms.Length]; ms.Position = 0; ms.Read(arr, 0, (int)ms.Length); ms.Close(); return prefix + Convert.ToBase64String(arr); } catch (Exception) { return null; } } }}


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有