WPF(C#)截屏及图片处理

截屏返回Bitmap

截图方法返回Bitmap可以方便后面对图片进行处理

截屏并绘制鼠标点

截屏并绘制鼠标所在位置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
private const PixelFormat FORMAT = PixelFormat.Format24bppRgb;

public static Bitmap GetScreen()
{
Bitmap screenshot = new Bitmap(
Screen.PrimaryScreen.Bounds.Width,
Screen.PrimaryScreen.Bounds.Height,
FORMAT
);
using (Graphics gfx = Graphics.FromImage(screenshot))
{
gfx.CopyFromScreen(
Screen.PrimaryScreen.Bounds.X,
Screen.PrimaryScreen.Bounds.Y,
0,
0,
Screen.PrimaryScreen.Bounds.Size,
CopyPixelOperation.SourceCopy
);

// 绘制光标图标
// 创建一个红色的画刷
Brush brush = new SolidBrush(Color.Red);
gfx.FillEllipse(
brush,
Cursor.Position.X - 10,
Cursor.Position.Y - 10,
20,
20
);
return screenshot;
}
}

绘制鼠标为自定义图片

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
private const PixelFormat FORMAT = PixelFormat.Format24bppRgb;
public static Bitmap GetScreen()
{
Bitmap screenshot = new Bitmap(
Screen.PrimaryScreen.Bounds.Width,
Screen.PrimaryScreen.Bounds.Height,
FORMAT
);
using (Graphics gfx = Graphics.FromImage(screenshot))
{
gfx.CopyFromScreen(
Screen.PrimaryScreen.Bounds.X,
Screen.PrimaryScreen.Bounds.Y,
0,
0,
Screen.PrimaryScreen.Bounds.Size,
CopyPixelOperation.SourceCopy
);

// 绘制光标图标
BitmapImage bi = new BitmapImage(new Uri("pack://application:,,/Images/RemoteControl/guangbiao.png"));
var bm = BitmapImageToBitmap(bi);
gfx.DrawImage
(
bm,
Cursor.Position.X,
Cursor.Position.Y,
20,
20
);
return screenshot;
}
}

// BitmapImage --> Bitmap
public static Bitmap BitmapImageToBitmap(BitmapImage bitmapImage)
{
using (MemoryStream outStream = new MemoryStream())
{
PngBitmapEncoder enc = new PngBitmapEncoder();
enc.Frames.Add(BitmapFrame.Create(bitmapImage));
enc.Save(outStream);
Bitmap bitmap = new Bitmap(outStream);
return new Bitmap(bitmap);
}
}

缩放

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public static Bitmap ScalePic
(
Bitmap sourrce,
int width,
int height
)
{
Bitmap result = new Bitmap(
width,
height,
FORMAT
);
using (Graphics g = Graphics.FromImage(result))
{
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.DrawImage(
sourrce,
0,
0,
width,
height
);
return result;
}
}

图片保存

使用默认方式

1
2
3
4
5
6
7
8
9
10
11
public static byte[] GetPicByte(Bitmap sourrce)
{
using (MemoryStream ms = new MemoryStream())
{
sourrce.Save(
ms,
ImageFormat.Jpeg
);
return ms.ToArray();
}
}

自定义压缩率

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
public static byte[] GetPicByte
(
Bitmap sourrce,
int quality
)
{
using (MemoryStream ms = new MemoryStream())
{
ImageCodecInfo jpegCodec = GetEncoderInfo("image/jpeg");
var encoderParameters = GetEncoderParameters(quality);
sourrce.Save(
ms,
jpegCodec,
encoderParameters
);
return ms.ToArray();
}
}

public static EncoderParameters GetEncoderParameters(int quality = 90)
{
Encoder qualityEncoder = Encoder.Quality;
EncoderParameters encoderParams = new EncoderParameters(1);
encoderParams.Param[0] = new EncoderParameter(
qualityEncoder,
quality
);
return encoderParams;
}

/// <summary>
/// 获取解码器
/// </summary>
/// <param name="mimeType">
/// </param>
/// <returns>
/// </returns>
private static ImageCodecInfo GetEncoderInfo(string mimeType)
{
int j;
var encoders = ImageCodecInfo.GetImageEncoders();
for (j = 0; j < encoders.Length; ++j)
{
if (encoders[j].MimeType == mimeType)
{
return encoders[j];
}
}
return null;
}

保存到文件

1
bmp.Save(savePath, ImageFormat.Jpeg);

截屏并获取Byte

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
/// <summary>
/// 获取屏幕的Byte[]
/// </summary>
/// <param name="maxHeight"></param>
/// <returns></returns>
public static byte[] GetScreenshot(int maxHeight = 720)
{
var screen = GetScreen();
Bitmap targetPic;
int width = screen.Width;
int height = screen.Height;
if (screen.Height > maxHeight)
{
double rate = 1.0d * screen.Height / maxHeight;
height = (int)(height / rate);
width = (int)(width / rate);
targetPic = ScalePic(
screen,
width,
height
);
screen.Dispose();
}
else
{
targetPic = screen;
}
var picByte = GetPicByte(
targetPic,
40
);
targetPic.Dispose();
return picByte;
}

Bitmap转BGR格式

在做视频编码的时候,我们需要的是原始的BGR数据。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public static byte[] Bitmap2Bgr(Bitmap bitmap)
{
BitmapData data = bitmap.LockBits(
new Rectangle(
0,
0,
bitmap.Width,
bitmap.Height
),
ImageLockMode.ReadWrite,
PixelFormat.Format24bppRgb
);
bitmap.UnlockBits(data);
int dstBytes = data.Stride * data.Height;
byte[] dstValues = new byte[dstBytes];
System.IntPtr srcPtr = data.Scan0;
Marshal.Copy(
srcPtr,
dstValues,
0,
dstBytes
);
return dstValues;
}

获取屏幕并转为Bgr格式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/// <summary>
/// 获取屏幕并转为Bgr格式
/// </summary>
/// <param name="targetWidth"></param>
/// <param name="targetHeight"></param>
/// <returns></returns>
public static byte[] CaptureScreen
(
int targetWidth,
int targetHeight
)
{
var screen = GetScreen();
var targetPic = ScalePic(
screen,
targetWidth,
targetHeight
);
screen.Dispose();
byte[] bgrByte = Bitmap2Bgr(targetPic);
targetPic.Dispose();
return bgrByte;
}