前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >WPF图片处理相关

WPF图片处理相关

作者头像
码客说
发布2020-08-12 10:24:47
发布2020-08-12 10:24:47
3.7K00
代码可运行
举报
文章被收录于专栏:码客码客
运行总次数:0
代码可运行

GDI和GDI+

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

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

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

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

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

  1. 二维矢量图形:GDI+提供了存储图形基元自身信息的类(或结构体)、存储图形基元绘制方式信息的类以及实际进行绘制的类;
  2. 图像处理:大多数图片都难以划定为直线和曲线的集合,无法使用二维矢量图形方式进行处理。因此,GDI+为我们提供了Bitmap、Image等类,它们可用于显示、操作和保存BMP、JPG、GIF等图像格式。
  3. 文字显示: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

  1. GDI是硬件加速的,而GDI+不是的,而且GDI+2.0比GDI+更快。
  2. GDI是有状态的,而GDI+是无状态的。
  3. GDI绘图要使用设备环境和句柄;而GDI+全部交由Graphics类管理(不创建句柄)。
  4. GDI绘图时可以使用SelectObject频繁切换图形对象,而GDI+的图形对象是独立的。
  5. GDI中存在一个当前位置(全局区),目的是提高绘图性能;而GDI+取消了它,以避免绘图时不确定这个当前位置而带来非预期的错误。
  6. GDI总是将画笔和画刷绑定在一起,即使不需要填充一个区域也必须指定一个画刷;而GDI+则可以使用不同的函数分开使用画笔和画刷。

GDI+新特性

  1. 改进了颜色管理。GDI+不仅提供了更多可供选择使用的颜色,使其支持Alpha通道合成运算,而且还保持了与其他颜色的兼容性。
  2. 绘图支持反锯齿。通过设置GDI+对象的相关属性,GDI+可以与相关的显示驱动程序搭配完成图形绘制时的反锯齿功能,使得绘制的图形更加平滑,美观,而整个过程是由GDI+对象自动计算完成的。
  3. 提供渐变画刷。GDI+拓展了GDI的功能,提供线性渐变和路径渐变画刷来填充图形、路径和区域,甚至也可用来绘制直线、曲线等。
  4. 独立的路径对象。GDI+使用Graphics对象来进行绘图操作,并将路径操作从Graphics对象分离出来,提供一个Graphics类供用户使用,用户不必担心对象会受到Graphics对象操作的影响,从而可以使用同一个操作对象进行多次的路径绘制操作。
  5. 样条曲线。GDI+封装了绘制基数样条曲线和贝塞尔样条曲线的方法。
  6. 变形和矩阵运算。GDI+提供了功能强大的Matrix类来实现矩阵的旋转,错切、平移、比例等变换操作,以便产生复杂的新图形。
  7. 多图片格式的支持。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资源, 数据库连接等等资源。

非托管资源的释放

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

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

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

  1. 继承IDisposable接口;
  2. 实现Dispose()方法,在其中释放托管资源和非托管资源,并将对象本身从垃圾回收器中移除(垃圾回收器不在回收此资源);
  3. 实现类析构函数,在其中释放非托管资源。

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

有两种实现方式:

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

代码如下

代码语言:javascript
代码运行次数:0
运行
复制
MyClass: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

代码语言:javascript
代码运行次数:0
运行
复制
using (Class1 cls1 = new Class1(), cls2 = new Class1())
{
  // the code using cls1, cls2
} // call the Dispose on cls1 and cls2

图片相关类

常见的类

  • System.Drawing.Image
  • System.Drawing.Bitmap 继承于Image 图片的缩放与保存
  • System.Windows.Controls.Image 展示图片的组件
  • ImageSource
  • BitmapSource 继承于ImageSource
  • BitmapImage 继承于BitmapSource
  • RenderTargetBitmap

Image和Bitmap

继承关系

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

Image

为源自 BitmapMetafile 的类提供功能的抽象基类。

代码语言:javascript
代码运行次数:0
运行
复制
// 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::SetPixelBitmap::GetPixel分别用来对位图进行读写像素操作,从而可以为图像的柔化和锐化处理提供一种可能。

示例

代码语言:javascript
代码运行次数:0
运行
复制
Image img = this.pictureBox1.Image;
Bitmap map = new Bitmap(img);

GetHbitmap

Bitmap的GetHbitmap()方法

官方文档

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

官方示例方法

代码语言:javascript
代码运行次数:0
运行
复制
[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

代码语言:javascript
代码运行次数:0
运行
复制
namespace 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 控件的源

代码语言:javascript
代码运行次数:0
运行
复制
// 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

代码语言:javascript
代码运行次数:0
运行
复制
<Grid x:Name="myview">
  <StackPanel>
    <TextBlock Text="我的应用程序" FontSize="20"  />
    <TextBlock Text="点击截屏" FontSize="60" />
  </StackPanel>
</Grid>

<!--该图片控件用于展示截图图片效果-->
<Image x:Name="img" />

C#

代码语言:javascript
代码运行次数:0
运行
复制
RenderTargetBitmap bitmap = new RenderTargetBitmap();
await bitmap.RenderAsync(myview);
// 把图片展现出来
img.Source = bitmap;

图片转换

Bitmap与ImageSource之间的转换

代码语言:javascript
代码运行次数:0
运行
复制
public class ImageConverter
{
  [DllImport("gdi32.dll", SetLastError = true)]
  private static extern bool DeleteObject(IntPtr hObject);
  /// <summary>
  /// 从bitmap转换成ImageSource
  /// </summary>
  /// <param name="icon"></param>
  /// <returns></returns>
  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;
  }
  /// <summary>
  /// 从Bitmap转换成BitmapSource
  /// </summary>
  /// <param name="bmp"></param>
  /// <returns></returns>
  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;
  }
  /// <summary>
  /// 从Icon到ImageSource的转换
  /// </summary>
  public ImageSource ChangeIconToImageSource(Icon icon)
  {
    ImageSource imageSource = System.Windows.Interop.Imaging.CreateBitmapSourceFromHIcon(
      icon.Handle,
      Int32Rect.Empty,
      BitmapSizeOptions.FromEmptyOptions());
    return imageSource;
  }
}

Bitmap和BitmapImage相互转换

代码语言:javascript
代码运行次数:0
运行
复制
// Bitmap --> BitmapImage
public static BitmapImage BitmapToBitmapImage(Bitmap bitmap)
{
  using (MemoryStream stream = new MemoryStream())
  {
    bitmap.Save(stream, ImageFormat.Png); // 坑点:格式选Bmp时,不带透明度

    stream.Position = 0;
    BitmapImage result = new BitmapImage();
    result.BeginInit();
    // According to MSDN, "The default OnDemand cache option retains access to the stream until the image is needed."
    // Force the bitmap to load right now so we can dispose the stream.
    result.CacheOption = BitmapCacheOption.OnLoad;
    result.StreamSource = stream;
    result.EndInit();
    result.Freeze();
    return result;
  }
}

// BitmapImage --> Bitmap
public 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);
  }
}

RenderTargetBitmap=>BitmapImage

代码语言:javascript
代码运行次数:0
运行
复制
// RenderTargetBitmap --> BitmapImage
public 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[]相互转换

代码语言:javascript
代码运行次数:0
运行
复制
// 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[] --> BitmapImage
public 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[]=>Bitmap

代码语言:javascript
代码运行次数:0
运行
复制
public 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保存

代码语言:javascript
代码运行次数:0
运行
复制
Bitmap img = ZScreenUtil.CaptureScreen();

保存

代码语言:javascript
代码运行次数:0
运行
复制
var filePath = "E:\123.jpg";
img.Save(filePath, System.Drawing.Imaging.ImageFormat.Jpeg);
img.Dispose();

保存设置压缩质量

代码语言:javascript
代码运行次数:0
运行
复制
public 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=>写文件

代码语言:javascript
代码运行次数:0
运行
复制
float 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()
    );
    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保存为图片文件。

图片加载

加载本地

代码语言:javascript
代码运行次数:0
运行
复制
BitmapImage bImage = new BitmapImage(new Uri("c:\\image.bmp"));
image.Source = bImage;

加载本地图片并缩放

代码语言:javascript
代码运行次数:0
运行
复制
private 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;
}

/// <summary>
/// 设置图片大小
/// </summary>
/// <param name="sourceImage"></param>
/// <param name="image"></param>
/// <param name="imageWidth"></param>
/// <param name="imageHeight"></param>
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);
  }
}

调用方式

代码语言:javascript
代码运行次数:0
运行
复制
SetSource(this.imageCur, “C:\1.png”);

截屏保存

获取图片

代码语言:javascript
代码运行次数:0
运行
复制
using System;
using System.Drawing;
using System.Windows.Forms;

namespace SchoolClient.Utils
{
  internal class ZScreenUtil
  {
    /// <summary>
    /// 截取屏幕
    /// </summary>
    /// <returns></returns>
    public static Bitmap CaptureScreen()
    {
      int iw = Screen.PrimaryScreen.Bounds.Width;
      int ih = Screen.PrimaryScreen.Bounds.Height;
      float factor = Graphics.FromHwnd(IntPtr.Zero).DpiX / 96;
      int imageW = Convert.ToInt32(factor * iw);
      int imageH = Convert.ToInt32(factor * ih);
      Bitmap postImage=null;
      try
      {
        using(Bitmap bmp = new Bitmap(imageW, imageH)){
          using (Graphics g = Graphics.FromImage(bmp))
          {
            g.CopyFromScreen(0, 0, 0, 0, new Size(imageW, imageH));
          }
          postImage = new Bitmap(bmp, 1280, 800);
        }
        return postImage;
      }
      catch (Exception e)
      {
        Console.WriteLine(e.Message);
        return null;
      }
    }
  }
}

保存图片

代码语言:javascript
代码运行次数:0
运行
复制
Bitmap img = ZScreenUtil.CaptureScreen();
var filePath = "E:\123.jpg";
img.Save(filePath, System.Drawing.Imaging.ImageFormat.Jpeg);
img.Dispose();

保存图片并压缩

代码语言:javascript
代码运行次数:0
运行
复制
public 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;
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020-08-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • GDI和GDI+
  • 托管资源和非托管资源
    • 概念
    • 常见的非托管资源
    • 非托管资源的释放
    • using
  • 图片相关类
    • 常见的类
    • Image和Bitmap
      • GetHbitmap
    • Image和ImageSource
    • ImageSource/BitmapSource/BitmapImage
    • RenderTargetBitmap
  • 图片转换
    • Bitmap与ImageSource之间的转换
    • Bitmap和BitmapImage相互转换
    • RenderTargetBitmap=>BitmapImage
    • BitmapImage和byte[]相互转换
    • byte[]=>Bitmap
  • 图片保存
    • Bitmap保存
    • BitmapSource保存
  • 图片加载
    • 加载本地
    • 加载本地图片并缩放
  • 截屏保存
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档