Форум программистов, компьютерный форум, киберфорум
Visual Basic .NET
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.82/11: Рейтинг темы: голосов - 11, средняя оценка - 4.82
0 / 0 / 0
Регистрация: 30.01.2016
Сообщений: 9
1
.NET 4.x

Скоростное создание скриншотов - до 30 в секунду

28.03.2016, 19:48. Показов 2124. Ответов 20
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Всем привет! Я настолько отважный парень, что решился написать программу для захвата видео с экрана! В общем у меня отчасти получилось: Сначала я делал скриншоты рабочего стола через VB, и записывал их в отдельные PNG файлы, затем через BAT файл, используя библиотеку ffmpeg склеивал эти PNG'шки в MP4 файл, в целом, всё нормально, качество идеальное. Но проблема состоит в том, что VB не способен делать больше 5 скринов в секунду! Подскажите пожалуйста, как создавать как минимум 30 скринов в секунду(Язык программирования не важен, главное, что-бы быстро)
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
28.03.2016, 19:48
Ответы с готовыми решениями:

Создание скриншотов
Подскажите как сделать автоматически скриншоты удаленного стола? Делаю в программе RoboTask,...

Создание и сохранение скриншотов
Необходимо, чтобы через определённый отрезок времени программа делала скришот экрана и...

Создание серии скриншотов
Есть две формы через Button1 запускаю цикл, как мне через эту же кнопку его прервать. oid...

Создание скриншотов и запись их в поток
Добрый день. Необходимо написать программу для снятия 25 скриншотов экрана в секунду с последующей...

20
525 / 487 / 98
Регистрация: 25.12.2011
Сообщений: 1,176
29.03.2016, 01:06 2
По вашему вопросу, могу посоветовать только то, что первое в голову пришло (может быть и глупость):
Собственно попробовать создать еще потоки, которые так-же будут делать скриншоты, передавать им Stopwatch (миллисекунды), и сохранять их по этому имени.

Добавлено через 8 минут
В 2 потока, за 4 секунды, делает более > 200 скриншотов.

Добавлено через 5 минут
P.S. Память не жалеет...
0
47 / 47 / 7
Регистрация: 26.12.2014
Сообщений: 189
29.03.2016, 08:43 3
Когда-то делал подобное, может даже исходники найду. Попробуй получить дескриптор экрана, а затем копируй через BitBlt winapi. Со скоростью все должно быть в порядке, если в память сохранять.
0
525 / 487 / 98
Регистрация: 25.12.2011
Сообщений: 1,176
29.03.2016, 09:34 4
Лучший ответ Сообщение было отмечено _Ender_ как решение

Решение

Вот, проверил > 50 в секунду.
VB.NET
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
Public Class Form1
 
    Dim OneThread As New Threading.Thread(AddressOf MySub)
    Dim TwoThread As New Threading.Thread(AddressOf MySub)
    Dim ThreeThread As New Threading.Thread(AddressOf MySub)
 
    Dim CurrentTime As New List(Of ULong)
 
    Sub MySub(ByVal watch As Stopwatch)
        Do
            Dim Current As New TimeSpan
            Dim IntL As ULong = watch.ElapsedMilliseconds
            If CurrentTime.Contains(IntL) = False Then
                Dim Bmp As Bitmap = GetScreen()
                Bmp.Save("E:\test" & watch.ElapsedMilliseconds & ".bmp")
                Bmp.Dispose()
            End If
        Loop
    End Sub
 
 
 
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
 
    End Sub
 
    Function GetScreen() As Bitmap
        Dim Bmp As New Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height)
        Dim G As Graphics = Graphics.FromImage(Bmp)
        G.CopyFromScreen(0, 0, 0, 0, Screen.PrimaryScreen.Bounds.Size)
        G.Dispose()
        Return Bmp
    End Function
 
    Dim watch As New Stopwatch
 
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        watch.Start()
        OneThread.Start(watch)
        TwoThread.Start(watch)
        ThreeThread.Start(watch)
    End Sub
 
End Class
1
0 / 0 / 0
Регистрация: 30.01.2016
Сообщений: 9
29.03.2016, 09:50  [ТС] 5
Спасибо, сейчас проверю

Добавлено через 9 минут
Цитата Сообщение от Jason Посмотреть сообщение
Вот, проверил > 50 в секунду.
Jason красава! Всё робит! Удачи тебе!

Добавлено через 5 минут
Извини, а можно ещё сделать кнопку остановки, и файлы называть по номеру кадра, а то у меня какая-то ошибка.
0
525 / 487 / 98
Регистрация: 25.12.2011
Сообщений: 1,176
29.03.2016, 10:15 6
Да можно, конечно:
VB.NET
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 Class Form1
 
    Dim OneThread As Threading.Thread
    Dim TwoThread As Threading.Thread
    Dim ThreeThread As Threading.Thread
 
    Dim IndexFrame As New List(Of Integer)
 
    Dim isRunning As Boolean = False
 
    Sub MySub()
        Do While isRunning
            Dim Bmp As Bitmap = GetScreen()
            IndexFrame.Add(IndexFrame(IndexFrame.Count - 1) + 1)
            Bmp.Save("E:\test" & IndexFrame(IndexFrame.Count - 1) & ".bmp")
            Bmp.Dispose()
        Loop
    End Sub
 
 
 
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
 
    End Sub
 
    Function GetScreen() As Bitmap
        Dim Bmp As New Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height)
        Dim G As Graphics = Graphics.FromImage(Bmp)
        G.CopyFromScreen(0, 0, 0, 0, Screen.PrimaryScreen.Bounds.Size)
        G.Dispose()
        Return Bmp
    End Function
 
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        IndexFrame.Add(0)
        isRunning = True
        OneThread = New Threading.Thread(AddressOf MySub)
        TwoThread = New Threading.Thread(AddressOf MySub)
        ThreeThread = New Threading.Thread(AddressOf MySub)
        OneThread.Start()
        TwoThread.Start()
        ThreeThread.Start()
    End Sub
 
    Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
        isRunning = False
        IndexFrame.Clear()
    End Sub
 
End Class
Что за ошибка (что пишет)?

Добавлено через 5 минут
Кнопку остановки, лучше так (иначе могу возникнуть ошибки с примером выше, не проверял просто):
VB.NET
1
2
3
4
5
6
7
    Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
        isRunning = False
        Do While OneThread.IsAlive Or TwoThread.IsAlive Or ThreeThread.IsAlive
 
        Loop
        IndexFrame.Clear()
    End Sub
0
0 / 0 / 0
Регистрация: 30.01.2016
Сообщений: 9
29.03.2016, 10:25  [ТС] 7
А в PNG можно? Чёт я забыл как Format.PNG писать

Добавлено через 3 минуты
А в PNG можно? Чёт я забыл как Format.PNG писать

Добавлено через 2 минуты
Всё, вспомнил: ImageFormat.Png

Добавлено через 1 минуту
Через Imports System.Drawing.Imaging
0
525 / 487 / 98
Регистрация: 25.12.2011
Сообщений: 1,176
29.03.2016, 10:26 8
А вы попробуйте переименовать в JPG и загрузить на форум, на что вам напишут:
219.jpg:
Это PNG изображение имеет неверное расширение.

Просто сохраняйте с расширением png, не знаю, почему я там написал bmp .

Добавлено через 59 секунд
Цитата Сообщение от _Ender_ Посмотреть сообщение
Через Imports System.Drawing.Imaging
Прочитайте то, что я написал.
0
0 / 0 / 0
Регистрация: 30.01.2016
Сообщений: 9
29.03.2016, 10:32  [ТС] 9
Отлично, а то в BMP почему-то не компилировался видео файл! Последняя просьба: нужно измерить средний fps!
0
525 / 487 / 98
Регистрация: 25.12.2011
Сообщений: 1,176
29.03.2016, 10:34 10
Средний FPS, после остановки?
0
0 / 0 / 0
Регистрация: 30.01.2016
Сообщений: 9
29.03.2016, 10:43  [ТС] 11
Да!
0
525 / 487 / 98
Регистрация: 25.12.2011
Сообщений: 1,176
29.03.2016, 10:43 12
Если после остановки, то:
Кликните здесь для просмотра всего текста
VB.NET
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
51
52
53
54
55
56
57
58
59
60
Public Class Form1
 
    Dim OneThread As Threading.Thread
    Dim TwoThread As Threading.Thread
    Dim ThreeThread As Threading.Thread
 
    Dim IndexFrame As New List(Of Integer)
 
    Dim isRunning As Boolean = False
 
    Sub MySub()
        Do While isRunning
            Dim Bmp As Bitmap = GetScreen()
            IndexFrame.Add(IndexFrame(IndexFrame.Count - 1) + 1)
            Bmp.Save("E:\test" & IndexFrame(IndexFrame.Count - 1) & ".bmp")
            Bmp.Dispose()
        Loop
    End Sub
 
 
 
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
 
    End Sub
 
    Function GetScreen() As Bitmap
        Dim Bmp As New Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height)
        Dim G As Graphics = Graphics.FromImage(Bmp)
        G.CopyFromScreen(0, 0, 0, 0, Screen.PrimaryScreen.Bounds.Size)
        G.Dispose()
        Return Bmp
    End Function
 
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        IndexFrame.Add(0)
        isRunning = True
        OneThread = New Threading.Thread(AddressOf MySub)
        TwoThread = New Threading.Thread(AddressOf MySub)
        ThreeThread = New Threading.Thread(AddressOf MySub)
        watch = New Stopwatch
        watch.Start()
        OneThread.Start()
        TwoThread.Start()
        ThreeThread.Start()
    End Sub
 
    Dim watch As Stopwatch
 
    Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
        isRunning = False
        Do While OneThread.IsAlive Or TwoThread.IsAlive Or ThreeThread.IsAlive
 
        Loop
        MsgBox("Средний FPS: " & Convert.ToString((IndexFrame.Count - 1) / watch.Elapsed.Seconds))
        'Если надо округлить, то: Convert.ToString(Fix((IndexFrame.Count - 1) / watch.Elapsed.Seconds)))
        watch.Stop()
        IndexFrame.Clear()
    End Sub
 
End Class
1
0 / 0 / 0
Регистрация: 30.01.2016
Сообщений: 9
29.03.2016, 10:54  [ТС] 13
Отлично, доделаю, скину прогу. Спасибо большое! У меня ругается на E:\test(C:\ffmpeg), а на C:\ffmpeg\ робит, это наверное из-за того, что у меня VB2008

Добавлено через 2 минуты
Можно ещё 3-ю кнопку для удаления остаточных файлов (Наших скринов)
0
525 / 487 / 98
Регистрация: 25.12.2011
Сообщений: 1,176
29.03.2016, 10:55 14
Это что? E:\test(C:\ffmpeg) ?
E - у меня лок. диск. Ты используй свой путь (я тестировал у себя) и не забудь там папку создать.
0
0 / 0 / 0
Регистрация: 30.01.2016
Сообщений: 9
29.03.2016, 10:56  [ТС] 15
Я же в скобках свой написал
0
395 / 314 / 53
Регистрация: 14.08.2014
Сообщений: 1,010
29.03.2016, 11:02 16
Jason, нельзя останавливать потоки через Boolean.
VB.NET
1
Dim isRunning As Boolean = False
Вернее останавливать то можно, но это не правильное решение, т.к. при такой остановке не снимается нагрузка с процессора.
Правильнее будет через Suspend и Resume, в таком случае потоки остановятся на безопасных поинтерах и при этом снимется нагрузка с системы. Правда стоит отметить, что Suspend и Resume уже устаревшее. Сейчас насколько я знаю рекомендуется использовать мьютексы.
0
525 / 487 / 98
Регистрация: 25.12.2011
Сообщений: 1,176
29.03.2016, 11:02 17
ВНИМАНИЕ! Код удалит все файлы из папки! Поэтому "кормить" это, только папкой со скриншотами, либо сделать проверку на расширение.
VB.NET
1
2
3
4
5
6
    Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
        Dim DirInfo As DirectoryInfo = New DirectoryInfo("E:\test")
        For Each file As FileInfo In DirInfo.GetFiles
            file.Delete()
        Next
    End Sub
0
525 / 487 / 98
Регистрация: 25.12.2011
Сообщений: 1,176
29.03.2016, 11:12 18
Дядя Корней, первый раз слышу о том, что так нельзя останавливать поток (не правильное решение).
Вот скриншот студии, нагрузка ЦП (красное во время работы, синее после работы).
Скоростное создание скриншотов - до 30 в секунду

Может, конечно я и не прав, с удовольствием почитаю мнения других.
0
395 / 314 / 53
Регистрация: 14.08.2014
Сообщений: 1,010
29.03.2016, 12:18 19
Jason, книга А.Дубовцев | Microsoft .NET. Наиболее полное руководство
Стр. 393.
С иллюстрациями показан наглядный пример остановки с boolean и Suspend.
Вариант с boolean не высвобождает ресурсы и нагрузка остается.

Добавлено через 1 минуту
Jason, и да, у вас на скриншоте включен debug режим, он работает совсем не так, как релиз версия. В дебаг совсем иначе идет распределение памяти.

Добавлено через 28 минут
Цитата Сообщение от Jason Посмотреть сообщение
ВНИМАНИЕ! Код удалит все файлы из папки! Поэтому "кормить" это, только папкой со скриншотами, либо сделать проверку на расширение.
Честно говоря тоже не оптимальный код. Для чего использовать цикл, если можно сразу удалить всю папку разом?
Пример
VB.NET
1
Directory.Delete("путь")
0
0 / 0 / 0
Регистрация: 30.01.2016
Сообщений: 9
29.03.2016, 13:13  [ТС] 20
У меня опять возникла проблема: я запуская ffmpeg следующей командой:ffmpeg -r 20 -f image2 -i %d.png test.mp4 .%d значит все файлы png то-есть: 1.png, 2.png и т.д. Я запускаю батник cmd'шкой, и эта cmd'шка не видит % и-за чего и не удаётся кодировать видеофайл(
0
29.03.2016, 13:13
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
29.03.2016, 13:13
Помогаю со студенческими работами здесь

Создание скриншотов нескольких папок
Здравствуйте. Подскажите пожалуйста, как в Powershell сделать поочередно скриншоты нескольких...

Слишком медленное создание скриншотов
Мне нужно оптимизировать код. У меня в нескольких потоках постоянно узнается цвет конкретного...

Очень быстрое создание картинок (скриншотов)
Всем привет! Суть программы - создание скриншотов рабочего стола очень и очень быстро. Для...

Скоростное мышление
Приветствую всех форумчан! Недавно я смотрел передачу, где показывали программистов Фейсбука. Так...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru