Модераторы: Partizan, gambit
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Скриншот с экрана. Как правильно снимать? 
:(
    Опции темы
Specialistvlad
Дата 15.12.2010, 04:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 14
Регистрация: 20.10.2010

Репутация: нет
Всего: нет



Доброй ночи.

Решил собрать свой вариант ambilight т.к. из инета примеры не понравились.

Вот фото(кликабельно)
user posted image

user posted image

user posted image

Видео
http://www.youtube.com/watch?v=8_zCedHGcak
http://www.youtube.com/watch?v=D75QGyhxvIc

Вообщем проблема видна на втором видео, скриншоты снимает программа очень медленно, а в ручном режиме все летает и цвета меняются очень быстро и плавно. Погуглив нашел парочку способов, но все они работают примерно также тормознуто. Сразу скажу, что с .Net и C# знаком 5 дней. Пытаюсь разковырять это все, трудно дается.

Вот так я снимаю скриншот
Код

private Image MakeScreen()
        {
            Image myImage = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);
            Graphics gr1 = Graphics.FromImage(myImage);

            IntPtr dc1 = gr1.GetHdc();
            IntPtr dc2 = GetWindowDC(GetDesktopWindow());

            BitBlt(dc1, 0, 0, Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height, dc2, 0, 0, 13369376);

            gr1.ReleaseHdc(dc1);
            return myImage;
        }


Потом мне нужно разбить скрин на 4 штуки указанных размеров.

Код

private Bitmap CutZoneFromImage(int zoneindex, Bitmap img)
        {
            int n,m;

            int w = coord[zoneindex,2] - coord[zoneindex,0];
            int h = coord[zoneindex,3] - coord[zoneindex,1];

            Bitmap Cutoutimg = new Bitmap(w, h);
            
            for (n = 0; n < w; n++)
            {
                for (m = 0; m < h; m++)
                {
                    Cutoutimg.SetPixel(n,m, img.GetPixel(coord[zoneindex,0]+n,coord[zoneindex,1]+m));
                }
            }
            return Cutoutimg;
        }

Интуитивно понятно, что код ну совсем кривой  smile 

Подскажите пожалуйста, как мне можно снимать скриншоты быстрее? smile  Я догадываюсь, что это нужно делать средствами directX. Но куда копать даже не могу представить.

Весь материал и исходники после того как все адекватно заработает я размещу у себя в блоге.  smile 

Заранее спасибо за помощь.

PM MAIL   Вверх
jonie
Дата 15.12.2010, 08:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 5613
Регистрация: 21.8.2005
Где: Владимир

Репутация: 22
Всего: 118



а тупит снятие скрина или его обработка? Проверяли что не обработка?


--------------------
Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет...
PM MAIL Jabber   Вверх
CYBERDREAM
Дата 15.12.2010, 08:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


I think, there4 I am
***


Профиль
Группа: Завсегдатай
Сообщений: 1096
Регистрация: 31.10.2006
Где: CyberLand

Репутация: 11
Всего: 28



Приветствую Specialistvlad, 

По поводу разбивки, лучше не попиксельно а через DrawImage объекта графикс. Так что не прийдется бегать тысячи раз по пикселям - дорогостоящая операция выходит.

http://msdn.microsoft.com/en-us/library/sy...e(v=VS.80).aspx 


А по поводу скриншота посредством директX, увы не знаю, попробуй 
http://blog.bobcravens.com/2009/04/fastest...-vista-vs-win7/ 
Операция по идее не сильно тормознутая - 50милисикунд выходит примерно

Добавлено через 48 секунд
jonie, по идее именно обработка и тормозит его процесс


--------------------
Ищем .Net, Java, Javascript разработчиков, Кипр, Лимассол. (знание английского необязательно)
Telegram, skype: kuchuk.artiom
PM MAIL WWW   Вверх
Specialistvlad
Дата 15.12.2010, 17:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 14
Регистрация: 20.10.2010

Репутация: нет
Всего: нет



Пытаюсь использовать исходники из приведенной вами ссылки. Пока не получается, две ошибки.

Цитата

Для нестатического поля, метода или свойства "ScreenshotCaptureWithMouse.ScreenCapture.CaptureScreen.CaptureDesktop()" требуется ссылка на объект    E:\Project\PIC\ambylight\dotNet\ScreenCapture\CaptureScreen.cs    91    26    HID PnP Demo

Элемент "CaptureDesktopWithCursor" не существует в текущем контексте.    E:\Project\PIC\ambylight\dotNet\Form1.cs    1286    21    HID PnP Demo


Подскажите как их решить, не могу понять, что от меня хочет.

Что делал:

1. Перетянул папку(ScreenCapture) с тремя файлами в "Обозреватель решений" (CaptureScreen.cs, GDIStuff.cs, Win32Stuff.cs)
2. Открыл файл Form1.cs из того проекта и посмотрел, что есть строка

Код

using ScreenshotCaptureWithMouse.ScreenCapture;

Добавил её к себе вместе с методом 
Код

private void Display(Bitmap desktop)


Исходник файла CaptureScreen.cs
Код

using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Runtime.InteropServices;

namespace ScreenshotCaptureWithMouse.ScreenCapture
{
    class CaptureScreen
    {
        //This structure shall be used to keep the size of the screen.
        public struct SIZE
        {
            public int cx;
            public int cy;
        }

        public Bitmap CaptureDesktop()
        {
            SIZE size;
            IntPtr hBitmap;
            IntPtr hDC = Win32Stuff.GetDC(Win32Stuff.GetDesktopWindow());
            IntPtr hMemDC = GDIStuff.CreateCompatibleDC(hDC);

            size.cx = Win32Stuff.GetSystemMetrics
                      (Win32Stuff.SM_CXSCREEN);

            size.cy = Win32Stuff.GetSystemMetrics
                      (Win32Stuff.SM_CYSCREEN);

            hBitmap = GDIStuff.CreateCompatibleBitmap(hDC, size.cx, size.cy);

            if (hBitmap != IntPtr.Zero)
            {
                IntPtr hOld = (IntPtr)GDIStuff.SelectObject
                                       (hMemDC, hBitmap);

                GDIStuff.BitBlt(hMemDC, 0, 0, size.cx , size.cy, hDC,
                                               0, 0, GDIStuff.SRCCOPY);

                GDIStuff.SelectObject(hMemDC, hOld);
                GDIStuff.DeleteDC(hMemDC);
                Win32Stuff.ReleaseDC(Win32Stuff.GetDesktopWindow(), hDC);
                Bitmap bmp = System.Drawing.Image.FromHbitmap(hBitmap);
                GDIStuff.DeleteObject(hBitmap);
                GC.Collect();
                return bmp;
            }
            return null;
      
        }


        static Bitmap CaptureCursor(ref int x, ref int y)
        {
            Bitmap bmp;
            IntPtr hicon;
            Win32Stuff.CURSORINFO ci = new Win32Stuff.CURSORINFO();
            Win32Stuff.ICONINFO icInfo;
            ci.cbSize = Marshal.SizeOf(ci);
            if (Win32Stuff.GetCursorInfo(out ci))
            {
                if (ci.flags == Win32Stuff.CURSOR_SHOWING)
                {
                    hicon = Win32Stuff.CopyIcon(ci.hCursor);
                    if (Win32Stuff.GetIconInfo(hicon, out icInfo))
                    {
                        x = ci.ptScreenPos.x - ((int)icInfo.xHotspot);
                        y = ci.ptScreenPos.y - ((int)icInfo.yHotspot);

                        Icon ic = Icon.FromHandle(hicon);
                        bmp = ic.ToBitmap(); 
                        return bmp;
                    }
                }
            }

            return null;
        }

        public static Bitmap CaptureDesktopWithCursor()
        {
            int cursorX = 0;
            int cursorY = 0;
            Bitmap desktopBMP;
            Bitmap cursorBMP;
            Bitmap finalBMP;
            Graphics g;
            Rectangle r;

            desktopBMP = CaptureDesktop();
            cursorBMP = CaptureCursor(ref cursorX, ref cursorY);
            if (desktopBMP != null)
            {
                if (cursorBMP != null)
                { 
                    r = new Rectangle(cursorX, cursorY, cursorBMP.Width, cursorBMP.Height);
                    g = Graphics.FromImage(desktopBMP);
                    g.DrawImage(cursorBMP, r);
                    g.Flush();

                    return desktopBMP;
                }
                else
                    return desktopBMP;
            }

            return null;

        }


    }
}



Изпользую функцию Display(CaptureDesktopWithCursor()); как в том проекте - ругается на вложенную функцию. Где-то не добавил я чего-то... (


И по поводу разбивки. Как мне использовать один из методов Graphics.DrawImage Method
Для моего изображения? 
Код

Image img;


Кстати, забыл написать, что микроконтроллер(PIC 18F46J50) управляется через USB HID, не требующий сторонних драйверов, вообщем все удобно, позже хочу написать статью как это все собрать. 

Это сообщение отредактировал(а) Specialistvlad - 15.12.2010, 18:02
PM MAIL   Вверх
jonie
Дата 15.12.2010, 18:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 5613
Регистрация: 21.8.2005
Где: Владимир

Репутация: 22
Всего: 118



Цитата(Specialistvlad @  15.12.2010,  17:56 Найти цитируемый пост)

Кстати, забыл написать, что микроконтроллер(PIC 18F46J50) управляется через USB HID, не требующий сторонних драйверов, вообщем все удобно, позже хочу написать статью как это все собрать. 

а не баян ли это будет ?) http://habrahabr.ru/blogs/DIY/100085/


--------------------
Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет...
PM MAIL Jabber   Вверх
Specialistvlad
Дата 15.12.2010, 19:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 14
Регистрация: 20.10.2010

Репутация: нет
Всего: нет



Там используется Atmega контроллер, а я делаю на PIC. В целях саморазвития. 
PM MAIL   Вверх
Specialistvlad
Дата 16.12.2010, 14:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 14
Регистрация: 20.10.2010

Репутация: нет
Всего: нет



Люди, ауу..
PM MAIL   Вверх
Дрон
Дата 16.12.2010, 16:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Java-ненавистник :)
****


Профиль
Группа: Участник Клуба
Сообщений: 3179
Регистрация: 29.12.2002
Где: Санкт-Петербург

Репутация: 24
Всего: 93



Я думаю, что тормозит SetPixel/GetPixel в цикле.

У меня сейчас времени нет, да и с графикой я в .NET плотно не работал, хотя с предметом знаком smile

Метод CutZoneFromImage, как я понимаю, вырезает прямоугольную область из картинки. Зачем это надо?
Как сказал CYBERDREAM это можно сделать через DrawImage, но я вообще не совсем понимаю зачем это.

Тебе ведь наверно нужен средний цвет для какой-то области, так?

Это сообщение отредактировал(а) Дрон - 16.12.2010, 16:04


--------------------
Да. Именно так.
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Общие вопросы по .NET и C# | Следующая тема »


 




[ Время генерации скрипта: 0.0566 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.