仿照好视通的电子白板,做了一个小demo,记录一下,将office,pdf等文档转换成图片,然后把图片做成inkcanvas的背景,录放inkcanvas控件达到屏幕分享的目的
电子白班前台用到的是InkCanvas,xaml代码
<Grid x:Name="grid">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="30"/>
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal" Grid.Row="1" x:Name="sp">
<Button Height="28" Width="80" x:Name="background" Click="background_Click" Content="background"/>
<TextBlock x:Name="tbx" Background="AliceBlue" Width="50"/>
<Button x:Name="clear" Height="28" Width="80" Content="clear" Click="clear_Click"/>
<Button x:Name="acpk" Height="28" Width="80" Click="acpk_Click"/>
<Button x:Name="saveBipmap" Height="28" Width="80" Content="save" Click="saveBipmap_Click"/>
</StackPanel>
<InkCanvas x:Name="inkCanvas" Background="Pink"/>
</Grid>
cs代码,获取控件,然后把控件保存成图片,把保存好的图片转发给其他端口,其他端口进行播放显示。
public partial class MainWindow : Window
{
#region MyRegion
/// <summary>
/// 获得窗体句柄
/// </summary>
/// <returns></returns>
[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
public static extern IntPtr GetForegroundWindow();
/// <summary>
/// 查找窗体1
/// </summary>
/// <param name="lpClassName"></param>
/// <param name="lpWindowName"></param>
/// <returns></returns>
[DllImport("coredll.dll", EntryPoint = "FindWindow")]
private extern static IntPtr FindWindow(string lpClassName, string lpWindowName);
/// <summary>
/// 激活窗体
/// </summary>
/// <param name="hWnd"></param>
/// <returns></returns>
[DllImport("user32.dll")]
public static extern bool SetForegroundWindow(int hWnd);
/ <summary>
/ 查找窗体2
/ </summary>
/ <param name="lpClassName"></param>
/ <param name="lpWindowName"></param>
/ <returns></returns>
//[DllImport("user32.dll", EntryPoint = "FindWindow")]
//private extern static IntPtr FindWindow(string lpClassName, string lpWindowName);
/// <summary>
/// 查找子窗体
/// </summary>
/// <param name="hwndParent"></param>
/// <param name="hwndChildAfter"></param>
/// <param name="lpszClass"></param>
/// <param name="lpszWindow"></param>
/// <returns></returns>
[DllImport("user32.dll", EntryPoint = "FindWindow")]
private static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
/// <summary>
/// 获得窗体坐标
/// </summary>
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool GetWindowRect(IntPtr hWnd, ref RECT lpRect);
/// <summary>
/// 窗体坐标结构
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
public int Left; //最左坐标
public int Top; //最上坐标
public int Right; //最右坐标
public int Bottom; //最下坐标
}
#endregion
public MainWindow()
{
InitializeComponent();
timer = new DispatcherTimer();
timer.Tick += timer_Tick;
timer.Interval = TimeSpan.FromSeconds(0.5);
}
int index = 0;
void timer_Tick(object sender, EventArgs e)
{
// 录制软件大小的屏幕
//IntPtr ptr = new WindowInteropHelper(this).Handle;
//ImageFromHandle(ptr);
// 录制控件本身
SaveControls(grid, index + "");
index++;
tbx.Text = index + "";
}
DispatcherTimer timer;
bool stop = true;
private void background_Click(object sender, RoutedEventArgs e)
{
if (timer != null)
{
if (stop)
{
stop = false;
timer.Start();
}
else
{
stop = true;
timer.Stop();
}
}
}
#region bitmapsource保存成文件
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);
}
}
/// <summary>
/// 根据文件扩展名获取图片编码器
/// </summary>
/// <param name="filePath">文件路径</param>
/// <returns>图片编码器</returns>
private BitmapEncoder GetBitmapEncoder(string filePath)
{
var extName = System.IO.Path.GetExtension(filePath).ToLower();
if (extName.Equals(".png"))
{
return new PngBitmapEncoder();
}
else
{
return new JpegBitmapEncoder();
}
}
#endregion
#region 屏幕截图
static BitmapSource CopyScreen()
{
using (var screenBmp = new Bitmap((int)SystemParameters.PrimaryScreenWidth, (int)SystemParameters.PrimaryScreenHeight, System.Drawing.Imaging.PixelFormat.Format32bppArgb))
{
using (var bmpGraphics = Graphics.FromImage(screenBmp))
{
bmpGraphics.CopyFromScreen(0, 0, 0, 0, screenBmp.Size);
return Imaging.CreateBitmapSourceFromHBitmap(
screenBmp.GetHbitmap(),
IntPtr.Zero,
Int32Rect.Empty,
BitmapSizeOptions.FromEmptyOptions());
}
}
}
static BitmapSource CopyScreen(int left, int top, int width, int height)
{
using (var screenBmp = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format32bppArgb))
{
using (var bmpGraphics = Graphics.FromImage(screenBmp))
{
bmpGraphics.CopyFromScreen(left, top, 0, 0, screenBmp.Size);
return Imaging.CreateBitmapSourceFromHBitmap(
screenBmp.GetHbitmap(),
IntPtr.Zero,
Int32Rect.Empty,
BitmapSizeOptions.FromEmptyOptions());
}
}
}
#endregion
#region 根据窗体句柄获取图片
int i = 0;
[System.Runtime.InteropServices.DllImport("user32.dll")]
private static extern IntPtr GetWindowRect(IntPtr hwnd, ref System.Drawing.Rectangle lpRect);
private void ImageFromHandle(IntPtr handle)
{
RECT rect = new RECT();
GetWindowRect(handle, ref rect);
int width = rect.Right - rect.Left;
int height = rect.Bottom - rect.Top;
var img = new Bitmap(width, height);
using (var g = Graphics.FromImage(img))
{
g.CopyFromScreen(new System.Drawing.Point(rect.Left, rect.Top),
System.Drawing.Point.Empty, new System.Drawing.Size(width, height), CopyPixelOperation.SourceCopy);
g.DrawImage(img, 0, 0, img.Width, img.Height);
string path = string.Format("e:\\test\\13\\{0}.png", i);
if (File.Exists(path)) File.Delete(path);
img.Save(path);
}
tbx.Text = i + "";
i++;
}
#endregion
private void clear_Click(object sender, RoutedEventArgs e)
{
inkCanvas.EditingMode = InkCanvasEditingMode.EraseByPoint;
}
private void acpk_Click(object sender, RoutedEventArgs e)
{
inkCanvas.EditingMode = InkCanvasEditingMode.Ink;
}
private RenderTargetBitmap RenderVisaulToBitmap(Visual vsual, int width, int height)
{
var ss = PresentationSource.FromVisual(vsual).CompositionTarget.TransformToDevice;
var rtb = new RenderTargetBitmap(width, height, ss.OffsetX, ss.OffsetY, PixelFormats.Default);
Console.WriteLine(ss.OffsetX + ":" + ss.OffsetY);
rtb.Render(vsual);
return rtb;
}
private void SaveControls(FrameworkElement control, string fileName)
{
int height = (int)control.ActualHeight;
int width = (int)control.ActualWidth;
RenderTargetBitmap rtb = RenderVisaulToBitmap(control, width, height);
BmpBitmapEncoder encoder = new BmpBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(rtb));
string dirPath = "e:\\test\\13";
if (!Directory.Exists(dirPath))
Directory.CreateDirectory(dirPath);
string file = string.Format("{0}\\{1}.png", dirPath, fileName);
if (File.Exists(file)) File.Delete(file);
using (Stream stm = File.Create(file))
{
encoder.Save(stm);
}
}
private void saveBipmap_Click(object sender, RoutedEventArgs e)
{
SaveControls(inkCanvas, "image");
}
}
播放客户端代码xaml
<Border x:Name="borders"/>
cs代码
DispatcherTimer timer;
public MainWindow()
{
InitializeComponent();
timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromSeconds(0.6);
timer.Tick += timer_Tick;
timer.Start();
}
string path1 = "e:\\test\\13";
int index = 0;
void timer_Tick(object sender, EventArgs e)
{
string path = System.IO.Path.Combine(path1, index + ".png");
if (System.IO.File.Exists(path))
{
ImageBrush imageBrush = new ImageBrush();
imageBrush.ImageSource = new BitmapImage(new Uri(path, UriKind.Absolute));
borders.Background = imageBrush;
index++;
}
}