Преглед изворни кода

zhao:增加保存UI内容为图片 增加图片音频合成视频

tags/录制修改前
耀 пре 4 година
родитељ
комит
6c2bc0ad3b
5 измењених фајлова са 361 додато и 2 уклоњено
  1. 3
    0
      Common/Common.csproj
  2. 51
    2
      Common/system/FFMpeg.cs
  3. 295
    0
      Common/system/ImageHelper.cs
  4. 4
    0
      XHWK.WKTool/App.config
  5. 8
    0
      XHWK.WKTool/XHWK.WKTool.csproj

+ 3
- 0
Common/Common.csproj Прегледај датотеку

@@ -53,6 +53,8 @@
53 53
     <Reference Include="NPOI.OpenXmlFormats">
54 54
       <HintPath>dlls\NPOI.OpenXmlFormats.dll</HintPath>
55 55
     </Reference>
56
+    <Reference Include="PresentationCore" />
57
+    <Reference Include="PresentationFramework" />
56 58
     <Reference Include="System" />
57 59
     <Reference Include="System.Configuration" />
58 60
     <Reference Include="System.Core" />
@@ -89,6 +91,7 @@
89 91
     <Reference Include="VisioForge.Types, Version=12.0.56.0, Culture=neutral, PublicKeyToken=722de1c1c0a7f49e, processorArchitecture=MSIL">
90 92
       <HintPath>..\packages\VisioForge.DotNet.Core.TRIAL.12.0.56\lib\net45\VisioForge.Types.dll</HintPath>
91 93
     </Reference>
94
+    <Reference Include="WindowsBase" />
92 95
   </ItemGroup>
93 96
   <ItemGroup>
94 97
     <Compile Include="Model\DownloadInfoModel.cs" />

+ 51
- 2
Common/system/FFMpeg.cs Прегледај датотеку

@@ -8,13 +8,21 @@ using VisioForge.Shared.NAudio.Wave;
8 8
 
9 9
 namespace Common.system
10 10
 {
11
+    /// <summary>
12
+    /// ffmpeg帮助类
13
+    /// 需要安装\ffmpeg\bin\Setup Screen Capturer Recorder v0.12.10.exe
14
+    /// 本地调试需要配置环境变量 将ffmpeg.exe位置配置到环境变量的path中
15
+    /// </summary>
11 16
     public class FFMpeg
12 17
     {
13 18
         Process myProcess = null;
14 19
 
20
+        /// <summary>
21
+        /// 录屏
22
+        /// </summary>
23
+        /// <param name="PathName">文件存储路径</param>
15 24
         public void RunFFmpeg(string PathName)
16 25
         {
17
-
18 26
             Process[] KillProcessArray = Process.GetProcessesByName("ffmpeg");
19 27
             Debug.WriteLine(KillProcessArray.Length.ToString());
20 28
             foreach (var KillProcess in KillProcessArray)
@@ -41,7 +49,6 @@ namespace Common.system
41 49
             myProcess.Start();
42 50
             myProcess.BeginErrorReadLine();
43 51
         }
44
-
45 52
         /// <summary>
46 53
         /// 停止录制
47 54
         /// </summary>
@@ -67,6 +74,48 @@ namespace Common.system
67 74
                 Debug.WriteLine(output.Data.ToString());
68 75
         }
69 76
 
77
+        /// <summary>
78
+        /// 合成视频
79
+        /// </summary>
80
+        /// <param name="ImageListPath">图片列表位置 命名为1.png</param>
81
+        /// <param name="Mp3Path">MP3音频位置</param>
82
+        /// <param name="VideoSavePath">视频保存位置</param>
83
+        /// <param name="frequency">每秒帧率</param>
84
+        private void SynthesisVideo(string ImageListPath,string Mp3Path,string VideoSavePath,int frequency)
85
+        {
86
+            Process[] KillProcessArray = Process.GetProcessesByName("ffmpeg");
87
+            Debug.WriteLine(KillProcessArray.Length.ToString());
88
+            foreach (var KillProcess in KillProcessArray)
89
+            {
90
+                KillProcess.Kill();
91
+            }
92
+            Process myProcess = new Process();
93
+            this.myProcess.StartInfo.FileName = FileToolsCommon.GetFileAbsolutePath(@"/ffmpeg/bin/ffmpeg.exe");   //ffmpeg.exe的绝对路径
94
+            myProcess.StartInfo.Arguments = @"-y -r "+ frequency + " -i " +
95
+                ImageListPath + @"%d.png -i " +
96
+                Mp3Path + @" -s 800x800 -vcodec mpeg4 " +
97
+                VideoSavePath;
98
+            myProcess.StartInfo.UseShellExecute = false;
99
+            myProcess.StartInfo.RedirectStandardError = true;
100
+            myProcess.StartInfo.CreateNoWindow = true;
101
+            //外部程序(这里是FFMPEG)输出流时候产生的事件,这里是把流的处理过程转移到下面的方法中,详细请查阅MSDN
102
+            myProcess.ErrorDataReceived += new DataReceivedEventHandler(Output);
103
+            //p.ErrorDataReceived += new DataReceivedEventHandler((s, message) => { Console.WriteLine(message.Data); });
104
+            myProcess.Start();//启动线程
105
+            myProcess.BeginErrorReadLine();//开始异步读取
106
+            myProcess.WaitForExit();//阻塞等待进程结束
107
+            myProcess.Close();//关闭进程
108
+            myProcess.Dispose();//释放资源
109
+        }
110
+
111
+        //private void P_ErrorDataReceived(object sender, DataReceivedEventArgs e)
112
+        //{
113
+        //    //+= new DataReceivedEventHandler((s, message) => { Console.WriteLine(message.Data); })
114
+        //    using (StreamWriter fs = new StreamWriter("E:\\项目\\测试\\Wpf测试\\bin\\Debug\\ffmpeg\\log.txt", true))
115
+        //    {
116
+        //        fs.WriteLine(e.Data);
117
+        //    }
118
+        //}
70 119
 
71 120
         /// <summary>
72 121
         /// 获取麦克风

+ 295
- 0
Common/system/ImageHelper.cs Прегледај датотеку

@@ -2,8 +2,13 @@
2 2
 using System.Collections.Generic;
3 3
 using System.Drawing;
4 4
 using System.IO;
5
+using System.Windows.Media.Imaging;
6
+using System.Windows;
5 7
 using System.Linq;
6 8
 using System.Text;
9
+using System.Drawing.Imaging;
10
+using System.Configuration;
11
+using System.Windows.Media;
7 12
 
8 13
 namespace Common.system
9 14
 {
@@ -71,5 +76,295 @@ namespace Common.system
71 76
                 return null;
72 77
             }
73 78
         }
79
+
80
+        #region 截图统一方法
81
+
82
+        /// <summary>
83
+        /// 截图通用方法 创建人:赵耀 创建时间:2020年8月11日
84
+        /// </summary>
85
+        /// <param name="ScreenSize">截图的区域,设置new Rectangle(0, 0, 0, 0)为截全屏</param>
86
+        /// <param name="ImageSavePath">图片存储路径,为空或null则保存到临时文件夹</param>
87
+        /// <param name="level">压缩等级,0到100,0 最差质量,100 最佳</param>
88
+        /// <returns></returns>
89
+        public static BitmapImage GetScreenshot(Rectangle ScreenSize, string ImageSavePath, long level = -1)
90
+        {
91
+            try
92
+            {
93
+                System.Drawing.Size bounds = PrimaryScreen.DESKTOP;
94
+                //if (string.IsNullOrEmpty(ImageSavePath))
95
+                //{
96
+                //    ImageSavePath = GetTempImagePath();//如果为空则指定临时存储路径
97
+                //}
98
+                double scaleWidth = (bounds.Width * 1.0) / SystemParameters.PrimaryScreenWidth;
99
+                double scaleHeight = (bounds.Height * 1.0) / SystemParameters.PrimaryScreenHeight;
100
+                int width = bounds.Width;
101
+                int height = bounds.Height;
102
+                if (ScreenSize.Size != new System.Drawing.Size(0, 0))
103
+                {
104
+                    width = (int)(ScreenSize.Size.Width * scaleWidth);
105
+                    height = (int)(ScreenSize.Size.Height * scaleHeight);
106
+                }
107
+                int l = (int)(ScreenSize.X * scaleWidth);
108
+                int t = (int)(ScreenSize.Y * scaleHeight);
109
+                //if (_Bitmap != null)
110
+                //{
111
+                //    _Bitmap.Dispose();
112
+                //}
113
+                Bitmap _Bitmap = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
114
+                using (Graphics g = Graphics.FromImage(_Bitmap))
115
+                {
116
+                    g.CopyFromScreen(l, t, 0, 0, _Bitmap.Size, CopyPixelOperation.SourceCopy);
117
+                    Compress(_Bitmap, ImageSavePath, level);
118
+                }
119
+                Uri uri = new Uri(ImageSavePath, UriKind.Absolute);
120
+                BitmapImage bimg = new BitmapImage(uri);
121
+                GC.Collect();
122
+                return bimg;
123
+            }
124
+            catch (Exception ex)
125
+            {
126
+                LogHelper.WriteErrLog("【截图】(GetBitmapSource)截图失败," + ex.Message, ex);
127
+                return null;
128
+            }
129
+        }
130
+
131
+        //private static Bitmap _Bitmap = null;
132
+
133
+        //public static string GetRGB(int x, int y)
134
+        //{
135
+        //    StringBuilder sb = new StringBuilder();
136
+        //    try
137
+        //    {
138
+        //        Color color = _Bitmap.GetPixel(x, y);
139
+
140
+        //        sb.Append("RGB:(");
141
+        //        sb.Append(color.R.ToString());
142
+        //        sb.Append(",");
143
+        //        sb.Append(color.G.ToString());
144
+        //        sb.Append(",");
145
+        //        sb.Append(color.B.ToString());
146
+        //        sb.Append(")");
147
+        //    }
148
+        //    catch (Exception ex)
149
+        //    {
150
+        //        throw ex;
151
+        //    }
152
+
153
+        //    return sb.ToString();
154
+        //}
155
+
156
+        #endregion 截图统一方法
157
+
158
+        #region 图片压缩
159
+
160
+        /// <summary>
161
+        /// 图片压缩(降低质量以减小文件的大小) 创建人:赵耀 创建时间:2020年8月11日
162
+        /// </summary>
163
+        /// <param name="srcBitMap">传入的Bitmap对象</param>
164
+        /// <param name="destFile">压缩后的图片保存路径</param>
165
+        /// <param name="level">压缩等级,-1为config配置的值,0到100,0 最差质量,100 最佳</param>
166
+        public static void Compress(Bitmap srcBitMap, string destFile, long level)
167
+        {
168
+            if (level <= -1)
169
+            {
170
+                int ImageCompressionLevel = int.Parse(ConfigurationManager.AppSettings["ImageCompressionLevel"]);
171
+                level = ImageCompressionLevel;
172
+            }
173
+            Stream s = new FileStream(destFile, FileMode.Create);
174
+            Compress(srcBitMap, s, level);
175
+            s.Close();
176
+        }
177
+
178
+        /// <summary>
179
+        /// 图片压缩(降低质量以减小文件的大小) 创建人:赵耀 创建时间:2020年8月11日
180
+        /// </summary>
181
+        /// <param name="srcBitmap">传入的Bitmap对象</param>
182
+        /// <param name="destStream">压缩后的Stream对象</param>
183
+        /// <param name="level">压缩等级,0到100,0 最差质量,100 最佳</param>
184
+        public static void Compress(Bitmap srcBitmap, Stream destStream, long level)
185
+        {
186
+            ImageCodecInfo myImageCodecInfo;
187
+            System.Drawing.Imaging.Encoder myEncoder;
188
+            EncoderParameter myEncoderParameter;
189
+            EncoderParameters myEncoderParameters;
190
+
191
+            //获取表示jpeg编解码器的imagecodecinfo对象
192
+            myImageCodecInfo = GetEncoderInfo("image/jpeg");
193
+
194
+            myEncoder = System.Drawing.Imaging.Encoder.Quality;
195
+
196
+            myEncoderParameters = new EncoderParameters(1);
197
+
198
+            myEncoderParameter = new EncoderParameter(myEncoder, level);
199
+            myEncoderParameters.Param[0] = myEncoderParameter;
200
+            srcBitmap.Save(destStream, myImageCodecInfo, myEncoderParameters);
201
+        }
202
+
203
+        /// <summary>
204
+        /// 获取解码器 创建人:赵耀 创建时间2020年8月11日
205
+        /// </summary>
206
+        /// <param name="mimeType"></param>
207
+        /// <returns></returns>
208
+        private static ImageCodecInfo GetEncoderInfo(string mimeType)
209
+        {
210
+            int j;
211
+            ImageCodecInfo[] encoders;
212
+            encoders = ImageCodecInfo.GetImageEncoders();
213
+            for (j = 0; j < encoders.Length; ++j)
214
+            {
215
+                if (encoders[j].MimeType == mimeType)
216
+                {
217
+                    return encoders[j];
218
+                }
219
+            }
220
+            return null;
221
+        }
222
+
223
+        /// <summary>
224
+        /// 压缩图片 -测试方法 待完善 暂无用
225
+        /// </summary>
226
+        /// <param name="_bitmap">原图片</param>
227
+        /// <param name="dFile">压缩后保存图片地址</param>
228
+        /// <param name="flag">压缩质量(数字越小压缩率越高)1-100</param>
229
+        /// <param name="size">压缩后图片的最大大小</param>
230
+        /// <param name="sfsc">是否是第一次调用</param>
231
+        /// <returns></returns>
232
+        public static bool CompressImage(Bitmap _bitmap, string dFile, int flag = 90, int size = 300)
233
+        {
234
+            ////如果是第一次调用,原始图像的大小小于要压缩的大小,则直接复制文件,并且返回true
235
+            //FileInfo firstFileInfo = new FileInfo(sFile);
236
+            //if (sfsc == true && firstFileInfo.Length < size * 1024)
237
+            //{
238
+            //    firstFileInfo.CopyTo(dFile);
239
+            //    return true;
240
+            //}
241
+            //Image iSource = Image.FromFile(sFile);
242
+            Image iSource = _bitmap;
243
+            ImageFormat tFormat = iSource.RawFormat;
244
+            int dHeight = iSource.Height / 2;
245
+            int dWidth = iSource.Width / 2;
246
+            int sW, sH;
247
+            //按比例缩放
248
+            System.Drawing.Size tem_size = new System.Drawing.Size(iSource.Width, iSource.Height);
249
+            if (tem_size.Width > dHeight || tem_size.Width > dWidth)
250
+            {
251
+                if ((tem_size.Width * dHeight) > (tem_size.Width * dWidth))
252
+                {
253
+                    sW = dWidth;
254
+                    sH = (dWidth * tem_size.Height) / tem_size.Width;
255
+                }
256
+                else
257
+                {
258
+                    sH = dHeight;
259
+                    sW = (tem_size.Width * dHeight) / tem_size.Height;
260
+                }
261
+            }
262
+            else
263
+            {
264
+                sW = tem_size.Width;
265
+                sH = tem_size.Height;
266
+            }
267
+
268
+            Bitmap ob = new Bitmap(dWidth, dHeight);
269
+            Graphics g = Graphics.FromImage(ob);
270
+
271
+            g.Clear(System.Drawing.Color.WhiteSmoke);
272
+            g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
273
+            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
274
+            g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
275
+
276
+            g.DrawImage(iSource, new Rectangle((dWidth - sW) / 2, (dHeight - sH) / 2, sW, sH), 0, 0, iSource.Width, iSource.Height, GraphicsUnit.Pixel);
277
+
278
+            g.Dispose();
279
+
280
+            //以下代码为保存图片时,设置压缩质量
281
+            EncoderParameters ep = new EncoderParameters();
282
+            long[] qy = new long[1];
283
+            qy[0] = flag;//设置压缩的比例1-100
284
+            EncoderParameter eParam = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, qy);
285
+            ep.Param[0] = eParam;
286
+
287
+            try
288
+            {
289
+                ImageCodecInfo[] arrayICI = ImageCodecInfo.GetImageEncoders();
290
+                ImageCodecInfo jpegICIinfo = null;
291
+                for (int x = 0; x < arrayICI.Length; x++)
292
+                {
293
+                    if (arrayICI[x].FormatDescription.Equals("JPEG"))
294
+                    {
295
+                        jpegICIinfo = arrayICI[x];
296
+                        break;
297
+                    }
298
+                }
299
+                if (jpegICIinfo != null)
300
+                {
301
+                    if (flag > 0)
302
+                    {
303
+                        ob.Save(dFile, jpegICIinfo, ep);//dFile是压缩后的新路径
304
+                        FileInfo fi = new FileInfo(dFile);
305
+                        if (fi.Length > 1024 * size)
306
+                        {
307
+                            flag -= 10;
308
+                            CompressImage(_bitmap, dFile, flag, size);
309
+                        }
310
+                    }
311
+                    //ob.Save(dFile, jpegICIinfo, ep);
312
+                    //FileInfo fi = new FileInfo(dFile);
313
+                    //bool IsAgain = false;
314
+                    //if (fi.Length > 1024 * size)
315
+                    //{
316
+                    //    fi.CopyTo(dFile + fi.Length);
317
+                    //    fi.Delete();
318
+                    //    Bitmap newbitmap = ReadImageFile(dFile + fi.Length);
319
+                    //    CompressImage(newbitmap, dFile, flag, size);
320
+                    //    FileToolsCommon.DeleteFile(dFile + fi.Length);
321
+                    //}
322
+                }
323
+                else
324
+                {
325
+                    ob.Save(dFile, tFormat);
326
+                }
327
+                return true;
328
+            }
329
+            catch
330
+            {
331
+                return false;
332
+            }
333
+            finally
334
+            {
335
+                iSource.Dispose();
336
+                ob.Dispose();
337
+            }
338
+        }
339
+        #endregion 图片压缩
340
+
341
+        #region 截屏指定UI控件
342
+
343
+        /// <summary>
344
+        /// 保存图片
345
+        /// </summary>
346
+        /// <param name="ui">需要截图的UI控件</param>
347
+        /// <param name="filePathName">图片保存地址 命名 1.png</param>
348
+        /// <param name="width">保存宽</param>
349
+        /// <param name="height">保存高</param>
350
+        private void SaveUIToImage(FrameworkElement ui, string filePathName, int width, int height)
351
+        {
352
+            try
353
+            {
354
+                System.IO.FileStream fs = new System.IO.FileStream(filePathName, System.IO.FileMode.Create);
355
+                RenderTargetBitmap bmp = new RenderTargetBitmap(width, height, 96d, 96d,
356
+                PixelFormats.Pbgra32);
357
+                bmp.Render(ui);
358
+                BitmapEncoder encoder = new PngBitmapEncoder();
359
+                encoder.Frames.Add(BitmapFrame.Create(bmp));
360
+                encoder.Save(fs);
361
+                fs.Close();
362
+            }
363
+            catch (Exception ex)
364
+            {
365
+                Console.WriteLine(ex.Message);
366
+            }
367
+        }
368
+        #endregion
74 369
     }
75 370
 }

+ 4
- 0
XHWK.WKTool/App.config Прегледај датотеку

@@ -3,4 +3,8 @@
3 3
     <startup> 
4 4
         <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
5 5
     </startup>
6
+ <appSettings>
7
+    <!--图片压缩等级-->
8
+    <add key="ImageCompressionLevel" value="30" />
9
+  </appSettings>
6 10
 </configuration>

+ 8
- 0
XHWK.WKTool/XHWK.WKTool.csproj Прегледај датотеку

@@ -40,6 +40,7 @@
40 40
     </Reference>
41 41
     <Reference Include="System" />
42 42
     <Reference Include="System.Data" />
43
+    <Reference Include="System.Windows.Forms" />
43 44
     <Reference Include="System.Xml" />
44 45
     <Reference Include="Microsoft.CSharp" />
45 46
     <Reference Include="System.Core" />
@@ -54,6 +55,9 @@
54 55
     <Reference Include="PresentationFramework" />
55 56
   </ItemGroup>
56 57
   <ItemGroup>
58
+    <Compile Include="XHMicroLessonSystemWindow.xaml.cs">
59
+      <DependentUpon>XHMicroLessonSystemWindow.xaml</DependentUpon>
60
+    </Compile>
57 61
     <Page Include="CreateAMicroLessonWindow.xaml">
58 62
       <Generator>MSBuild:Compile</Generator>
59 63
       <SubType>Designer</SubType>
@@ -63,6 +67,10 @@
63 67
       <DependentUpon>CreateAMicroLessonWindow.xaml</DependentUpon>
64 68
       <SubType>Code</SubType>
65 69
     </Compile>
70
+    <Page Include="XHMicroLessonSystemWindow.xaml">
71
+      <Generator>MSBuild:Compile</Generator>
72
+      <SubType>Designer</SubType>
73
+    </Page>
66 74
   </ItemGroup>
67 75
   <ItemGroup>
68 76
     <Compile Include="Properties\AssemblyInfo.cs">

Loading…
Откажи
Сачувај